18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Wi-Fi Direct - P2P module 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 152e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt#include "common/wpa_ctrl.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx); 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev); 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq); 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len); 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_scan recovery timeout 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Many drivers are using 30 second timeout on scan results. Allow a bit larger 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * timeout for this to avoid hitting P2P timeout unnecessarily. 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_SCAN_TIMEOUT 35 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entries will be removed 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 452093d0658d2f0f8b5a98df7accc97fff3b2bb7d5Dmitry Shmidt#ifndef P2P_PEER_EXPIRATION_AGE 462093d0658d2f0f8b5a98df7accc97fff3b2bb7d5Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 60 471846323989242844f0e857458a8939fa5836429cDmitry Shmidt#endif /* P2P_PEER_EXPIRATION_AGE */ 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expire_peers(struct p2p_data *p2p) 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *n; 54fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now; 55c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t i; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec) 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 61c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 629e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt if (dev == p2p->go_neg_peer) { 639e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt /* 649e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * GO Negotiation is in progress with the peer, so 659e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * don't expire the peer entry until GO Negotiation 669e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * fails or times out. 679e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt */ 689e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt continue; 699e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt } 709e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt 71c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->cfg->go_connected && 72c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->cfg->go_connected(p2p->cfg->cb_ctx, 73c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt dev->info.p2p_device_addr)) { 74c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 75c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * We are connected as a client to a group in which the 76c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * peer is the GO, so do not expire the peer entry. 77c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 78fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 79c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 80c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 81c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 82c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 83c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p_group_is_client_connected( 84c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->groups[i], dev->info.p2p_device_addr)) 85c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt break; 86c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 87c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (i < p2p->num_groups) { 88c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 89c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * The peer is connected as a client in a group where 90c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * we are the GO, so do not expire the peer entry. 91c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 92fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 93c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 94c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 95c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 96b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Expiring old peer entry " MACSTR, 97b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expiration_timeout(void *eloop_ctx, void *timeout_ctx) 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expire_peers(p2p); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_state_txt(int state) 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SEARCH"; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT"; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT_LISTEN"; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "GO_NEG"; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "LISTEN_ONLY"; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_CONNECT"; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_IDLE"; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SD_DURING_FIND"; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PROVISIONING"; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PD_DURING_FIND"; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE"; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE_LISTEN"; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "?"; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidtconst char * p2p_get_state_txt(struct p2p_data *p2p) 149b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt{ 150b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return p2p_state_txt(p2p->state); 151b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt} 152b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 153b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!addr || !p2p) 1591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return dev->wps_prov_info; 1641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 1651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 16904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!addr || !p2p) 1741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 1751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 1791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_state(struct p2p_data *p2p, int new_state) 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 184b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "State %s -> %s", 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), p2p_state_txt(new_state)); 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->state = new_state; 18743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 18843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (new_state == P2P_IDLE && p2p->pending_channel) { 18943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p_dbg(p2p, "Apply change in listen channel"); 19043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->reg_class = p2p->pending_reg_class; 19143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->channel = p2p->pending_channel; 19243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_reg_class = 0; 19343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_channel = 0; 19443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec) 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 200b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set timeout (state=%s): %u.%06u sec", 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), sec, usec); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_clear_timeout(struct p2p_data *p2p) 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 209b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Clear timeout (state=%s)", p2p_state_txt(p2p->state)); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer, 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int status) 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 2208c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer) { 2218c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 2221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->go_neg_peer->wps_method = WPS_NOT_READY; 223cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->go_neg_peer->oob_pw_id = 0; 2248c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.status = status; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer) { 230413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_free(peer->go_neg_conf); 231413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt peer->go_neg_conf = NULL; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 241d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc) 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r, tu; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 247b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting short listen state (state=%s)", 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2503c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt if (p2p->pending_listen_freq) { 2513c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt /* We have a pending p2p_listen request */ 2523c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p_dbg(p2p, "p2p_listen command pending already"); 2533c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt return; 2543c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt } 2553c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 2564b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 258b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) + 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int) * 100; 265d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu) 266d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->max_disc_tu; 267d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!dev_disc && tu < 100) 268d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = 100; /* Need to wait in non-device discovery use cases */ 269d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen) 270d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->cfg->max_listen * 1000 / 1024; 271d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 272d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (tu == 0) { 273b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip listen state since duration was 0 TU"); 274d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_set_timeout(p2p, 0, 0); 275d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 276d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2823c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_freq = freq; 2833c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_sec = 0; 2843c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_usec = 1024 * tu; 2853c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000, 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies) < 0) { 288b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start listen mode"); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen(struct p2p_data *p2p, unsigned int timeout) 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 300b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Going to listen(only) state"); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3023c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt if (p2p->pending_listen_freq) { 3033c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt /* We have a pending p2p_listen request */ 3043c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p_dbg(p2p, "p2p_listen command pending already"); 3053c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt return -1; 3063c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt } 3073c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 3084b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 310b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = timeout / 1000; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = (timeout % 1000) * 1000; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 31804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) { 319b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - connect is already pending - skip listen"); 3201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 322b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - delay start of listen state"); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3313c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_freq = freq; 3323c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { 334b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start listen mode"); 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_LISTEN_ONLY); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_clear_reported(struct p2p_data *p2p) 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_REPORTED; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device - Fetch a peer entry 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr) 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0) 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Interface Address of the peer 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0) 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_create_device - Create a peer entry 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL on failure 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If there is already an entry for the peer, it will be returned instead of 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * creating a new one. 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_device * p2p_create_device(struct p2p_data *p2p, 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *oldest = NULL; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count = 0; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oldest == NULL || 412fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_reltime_before(&dev->last_seen, &oldest->last_seen)) 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldest = dev; 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count + 1 > p2p->cfg->max_peers && oldest) { 416b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Remove oldest peer entry to make room for a new peer"); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&oldest->list); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, oldest); 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = os_zalloc(sizeof(*dev)); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&p2p->devices, &dev->list); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN); 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_client_info(struct p2p_device *dev, 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli) 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name[cli->dev_name_len] = '\0'; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab = cli->dev_capab; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.config_methods = cli->config_methods; 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8); 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_interface_addr, int freq, 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *gi, size_t gi_len) 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t c; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Clear old data for this group; if the devices are still in the 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group, the information will be restored in the loop following this. 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(dev->member_in_go_iface, go_interface_addr, 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_iface, 0, ETH_ALEN); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_dev, 0, ETH_ALEN); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (c = 0; c < info.num_clients; c++) { 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli = &info.client[c]; 4731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr, 4741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ETH_ALEN) == 0) 4751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; /* ignore our own entry */ 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, cli->p2p_device_addr); 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY | 47904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_PROBE_REQ_ONLY)) { 48004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 48104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Update information since we have not 48204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * received this directly from the client. 48304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 48504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 48604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 48704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Need to update P2P Client Discoverability 48804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * flag since it is valid only in P2P Group 48904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Info attribute. 49004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 49104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= 49204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 49304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= 49404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cli->dev_capab & 49504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 49604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, cli->p2p_device_addr); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq = freq; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.p2p_device_addr, 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &dev->info, 1); 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, cli->p2p_interface_addr, 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 515fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_iface, go_interface_addr, 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 525b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, 526b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt int probe_req, const struct p2p_message *msg) 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, msg->device_name, 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.device_name)); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->manufacturer && 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len < sizeof(dev->info.manufacturer)) { 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.manufacturer, 0, 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.manufacturer)); 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.manufacturer, msg->manufacturer, 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len); 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_name && 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len < sizeof(dev->info.model_name)) { 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_name, 0, 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_name)); 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_name, msg->model_name, 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len); 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_number && 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len < sizeof(dev->info.model_number)) { 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_number, 0, 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_number)); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_number, msg->model_number, 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->serial_number && 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len < sizeof(dev->info.serial_number)) { 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.serial_number, 0, 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.serial_number)); 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.serial_number, msg->serial_number, 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->pri_dev_type) 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type, 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg->wps_pri_dev_type) 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type, 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_sec_dev_type_list) { 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list, 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len); 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->capability) { 57904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 58004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * P2P Client Discoverability bit is reserved in all frames 58104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * that use this function, so do not change its value here. 58204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 58304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 58404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= msg->capability[0] & 58504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab = msg->capability[1]; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->ext_listen_timing) { 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval = 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing + 2); 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 59404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!probe_req) { 596f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt u16 new_config_methods; 597f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt new_config_methods = msg->config_methods ? 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_methods : msg->wps_config_methods; 599f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (new_config_methods && 600f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods != new_config_methods) { 601b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update peer " MACSTR 602b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " config_methods 0x%x -> 0x%x", 603b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 604b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt dev->info.config_methods, 605b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt new_config_methods); 606f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods = new_config_methods; 607f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6122e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidtstatic void p2p_update_peer_vendor_elems(struct p2p_device *dev, const u8 *ies, 6132e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt size_t ies_len) 6142e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt{ 6152e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt const u8 *pos, *end; 6162e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt u8 id, len; 6172e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6182e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_free(dev->info.vendor_elems); 6192e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt dev->info.vendor_elems = NULL; 6202e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6212e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt end = ies + ies_len; 6222e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6232e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt for (pos = ies; pos + 1 < end; pos += len) { 6242e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt id = *pos++; 6252e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt len = *pos++; 6262e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6272e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (pos + len > end) 6282e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt break; 6292e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6302e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (id != WLAN_EID_VENDOR_SPECIFIC || len < 3) 6312e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt continue; 6322e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6332e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (len >= 4) { 6342e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt u32 type = WPA_GET_BE32(pos); 6352e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6362e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (type == WPA_IE_VENDOR_TYPE || 6372e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt type == WMM_IE_VENDOR_TYPE || 6382e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt type == WPS_IE_VENDOR_TYPE || 6392e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt type == P2P_IE_VENDOR_TYPE || 6402e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt type == WFD_IE_VENDOR_TYPE) 6412e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt continue; 6422e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt } 6432e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6442e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt /* Unknown vendor element - make raw IE data available */ 6452e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (wpabuf_resize(&dev->info.vendor_elems, 2 + len) < 0) 6462e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt break; 6472e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_data(dev->info.vendor_elems, pos - 2, 2 + len); 6482e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt } 6492e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt} 6502e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6512e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 65304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * p2p_add_device - Add peer entries based on scan results or P2P frames 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Source address of Beacon or Probe Response frame (may be either 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Address or P2P Interface Address) 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @level: Signal level (signal strength of the received frame from the peer) 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency on which the Beacon or Probe Response frame was received 659f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @rx_time: Time when the result was received 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies: IEs from the Beacon or Probe Response frame 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies_len: Length of ies buffer in octets 66204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @scan_res: Whether this was based on scan results 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If the scan result is for a GO, the clients in the group will also be added 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the peer table. This function can also be used with some other frames 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * like Provision Discovery Request that contains P2P Capability and P2P Device 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Info attributes. 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 670a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtint p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, 671fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime *rx_time, int level, const u8 *ies, 672a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len, int scan_res) 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *p2p_dev_addr; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 678fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime time_now; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ies, ies_len, &msg)) { 682b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P IE for a device entry"); 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg.device_id) 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.device_id; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 692b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore scan data without P2P Device Info or P2P Device Id"); 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(p2p->peer_filter) && 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) { 699b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not add peer filter for " MACSTR 700b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " due to peer filter", MAC2STR(p2p_dev_addr)); 701a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 710a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 711f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (rx_time == NULL) { 712fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&time_now); 713f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt rx_time = &time_now; 714f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 715a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 716a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 717a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Update the device entry only if the new peer 718a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * entry is newer than the one previously stored. 719a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 720f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->last_seen.sec > 0 && 721fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_reltime_before(rx_time, &dev->last_seen)) { 722b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not update peer entry based on old frame (rx_time=%u.%06u last_seen=%u.%06u)", 723f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->sec, 724f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec, 725f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) dev->last_seen.sec, 726f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) dev->last_seen.usec); 727a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 728a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 729a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 730a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 731fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_reltime)); 732a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0) 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, addr, ETH_ALEN); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid && 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0)) { 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]); 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len = msg.ssid[1]; 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 2412 && freq <= 2484 && msg.ds_params && 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.ds_params >= 1 && *msg.ds_params <= 14) { 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ds_freq; 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.ds_params == 14) 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2484; 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2407 + *msg.ds_params * 5; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != ds_freq) { 753b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update Listen frequency based on DS Parameter Set IE: %d -> %d MHz", 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, ds_freq); 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = ds_freq; 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 75904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (dev->listen_freq && dev->listen_freq != freq && scan_res) { 760b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update Listen frequency based on scan results (" 761b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " %d -> %d MHz (DS param %d)", 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->listen_freq, 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, msg.ds_params ? *msg.ds_params : -1); 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 76504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 76604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->listen_freq = freq; 76704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.group_info) 76804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->oper_freq = freq; 76904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 77075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.level = level; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 772b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, &msg); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_vendor_ext[i] == NULL) 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy( 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]); 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->info.wps_vendor_ext[i] == NULL) 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 78861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 78961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 79061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 79161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 79261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 79304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 79404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq, 79504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_info, msg.group_info_len); 79604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8002e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p_update_peer_vendor_elems(dev, ies, ies_len); 8012e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_REPORTED) 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 805b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer found with Listen frequency %d MHz (rx_time=%u.%06u)", 806b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq, (unsigned int) rx_time->sec, 807f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 809b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 813f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->info.config_methods == 0 && 814f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (freq == 2412 || freq == 2437 || freq == 2462)) { 815f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 816f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * If we have only seen a Beacon frame from a GO, we do not yet 817f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * know what WPS config methods it supports. Since some 818f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * applications use config_methods value from P2P-DEVICE-FOUND 819f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * events, postpone reporting this peer until we've fully 820f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * discovered its capabilities. 821f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * 822f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * At least for now, do this only if the peer was detected on 823f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * one of the social channels since that peer can be easily be 824f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * found again and there are no limitations of having to use 825f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * passive scan on this channels, so this can be done through 826f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Probe Response frame that includes the config_methods 827f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * information. 828f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 829b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report peer " MACSTR 830b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " with unknown config methods", MAC2STR(addr)); 831f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 832f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 833f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 846497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt if (p2p->go_neg_peer == dev) { 8471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 8481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * If GO Negotiation is in progress, report that it has failed. 8491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 850497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 852497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt } 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == dev) 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == dev) 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_client_disc_go == dev) 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_go = NULL; 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 860c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt /* dev_lost() device, but only if it was previously dev_found() */ 861c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (dev->flags & P2P_DEV_REPORTED_ONCE) 862c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt p2p->cfg->dev_lost(p2p->cfg->cb_ctx, 863c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt dev->info.p2p_device_addr); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 87061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 8712e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_free(dev->info.vendor_elems); 872413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_free(dev->go_neg_conf); 87361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dev); 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_get_next_prog_freq(struct p2p_data *p2p) 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *c; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *cla; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t cl, ch; 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 reg_class; 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = &p2p->cfg->channels; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cl = 0; cl < c->reg_classes; cl++) { 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla = &c->reg_class[cl]; 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->reg_class != p2p->last_prog_scan_class) 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = 0; ch < cla->channels; ch++) { 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->channel[ch] == p2p->last_prog_scan_chan) { 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found) 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start from beginning */ 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[0].reg_class; 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[0].channel[0]; 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Pick the next channel */ 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch++; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ch == cla->channels) { 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl++; 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cl == c->reg_classes) 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl = 0; 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch = 0; 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[cl].reg_class; 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[cl].channel[ch]; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9204b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(reg_class, channel); 921b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Next progressive search channel: reg_class %u channel %u -> %d MHz", 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class, channel, freq); 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_class = reg_class; 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_chan = channel; 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2412 || freq == 2437 || freq == 2462) 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* No need to add social channels */ 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return freq; 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_search(struct p2p_data *p2p) 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq = 0; 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_scan_type type; 93604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 pw_id = DEV_PW_DEFAULT; 93761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int res; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 940b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver is still in Listen state - wait for it to end before continuing"); 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 94504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->find_type == P2P_FIND_PROGRESSIVE && 94604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (freq = p2p_get_next_prog_freq(p2p)) > 0) { 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL_PLUS_ONE; 948b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting search (+ freq %u)", freq); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL; 951b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting search"); 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 95461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq, 95561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types, 95661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->find_dev_id, pw_id); 95761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0) { 958b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Scan request failed"); 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 961b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Running p2p_scan"); 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx) 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 973b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Find timeout -> stop"); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_run_after_scan(struct p2p_data *p2p) 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_after_scan op; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 9848da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 1; 985b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Action frame at p2p_scan completion"); 9861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->cfg->send_action(p2p->cfg->cb_ctx, 9871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->freq, 9881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->dst, 9891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->src, 9901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->bssid, 9911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (u8 *) (p2p->after_scan_tx + 1), 9921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->len, 9931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->wait_time); 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op = p2p->start_after_scan; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (op) { 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_NOTHING: 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_LISTEN: 1005b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start previously requested Listen state"); 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen(p2p, p2p->pending_listen_sec * 1000 + 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec / 1000); 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_CONNECT: 1010b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start previously requested connect with " MACSTR, 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->after_scan_peer)); 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, p2p->after_scan_peer); 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 1014b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer not known anymore"); 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, dev); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx) 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int running; 1029b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan timeout (running=%d)", p2p->p2p_scan_running); 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt running = p2p->p2p_scan_running; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we recover from missed scan results callback */ 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (running) 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_run_after_scan(p2p); 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_free_req_dev_types(struct p2p_data *p2p) 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = 0; 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->req_dev_types); 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = NULL; 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_find(struct p2p_data *p2p, unsigned int timeout, 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 1049c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types, 105061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *dev_id, unsigned int search_delay) 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1054b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting find (type=%d)", type); 1055fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&p2p->find_start); 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 1057b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan is already running"); 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req_dev_types && num_req_dev_types) { 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = os_malloc(num_req_dev_types * 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->req_dev_types == NULL) 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->req_dev_types, req_dev_types, 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types * WPS_DEV_TYPE_LEN); 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = num_req_dev_types; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1071c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) { 1072c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN); 1073c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = p2p->find_dev_id_buf; 1074c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else 1075c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = NULL; 1076c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->find_type = type; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_clear_reported(p2p); 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 108361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay = search_delay; 108461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 10861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->last_p2p_find_timeout = timeout; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout) 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, p2p_find_timeout, 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_START_WITH_FULL: 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_PROGRESSIVE: 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 109504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 109604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_ONLY_SOCIAL: 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0, 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 110104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 110204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) { 1109b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Running p2p_scan"); 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 1114fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else if (p2p->p2p_scan_running) { 1115fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt p2p_dbg(p2p, "Failed to start p2p_scan - another p2p_scan was already running"); 1116fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt /* wait for the previous p2p_scan to complete */ 111796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt res = 0; /* do not report failure */ 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1119b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start p2p_scan"); 11201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 11211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find_for_freq(struct p2p_data *p2p, int freq) 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1130b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Stopping find"); 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 1133fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p->state == P2P_SEARCH) 1134b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->find_stopped(p2p->cfg->cb_ctx); 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 11388c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer) 11398c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 114304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_listen_for_freq(p2p, freq); 114404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 114504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 114604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 114704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq) 114804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) { 1150b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip stop_listen since we are on correct channel for response"); 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 115304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->in_listen) { 115404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->in_listen = 0; 115504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_clear_timeout(p2p); 115604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 11571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->drv_in_listen) { 11581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 11591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * The driver may not deliver callback to p2p_listen_end() 11601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * when the operation gets canceled, so clear the internal 11611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * variable that is tracking driver state. 11621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 1163b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Clear drv_in_listen (%d)", p2p->drv_in_listen); 11641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->drv_in_listen = 0; 11651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1170391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid p2p_stop_listen(struct p2p_data *p2p) 1171391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 1172391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p->state != P2P_LISTEN_ONLY) { 1173391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dbg(p2p, "Skip stop_listen since not in listen_only state."); 1174391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 1175391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 1176391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1177391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_stop_listen_for_freq(p2p, 0); 1178391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 1179391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 1180391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1181391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find(struct p2p_data *p2p) 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11843c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_freq = 0; 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find_for_freq(p2p, 0); 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1189a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int p2p_prepare_channel_pref(struct p2p_data *p2p, 1190a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int force_freq, 119168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt unsigned int pref_freq, int go) 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1193a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1194a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int freq = force_freq ? force_freq : pref_freq; 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 119668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Prepare channel pref - force_freq=%u pref_freq=%u go=%d", 119768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt force_freq, pref_freq, go); 11984b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_class, &op_channel) < 0) { 1199b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported frequency %u MHz", freq); 1200a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1201a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1202a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 120368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (!p2p_channels_includes(&p2p->cfg->channels, op_class, op_channel) && 120468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt (go || !p2p_channels_includes(&p2p->cfg->cli_channels, op_class, 120568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel))) { 1206b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Frequency %u MHz (oper_class %u channel %u) not allowed for P2P", 1207b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq, op_class, op_channel); 1208a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1209a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1210a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1211a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1212a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1214a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) { 1215a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_classes = 1; 1216a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channels = 1; 1217a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; 1218a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channel[0] = p2p->op_channel; 1219a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct p2p_channels)); 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1223a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1224a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 1225a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1226a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1227a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1228a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void p2p_prepare_channel_best(struct p2p_data *p2p) 1229a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 1230a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1231a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt const int op_classes_5ghz[] = { 124, 115, 0 }; 1232a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt const int op_classes_ht40[] = { 126, 127, 116, 117, 0 }; 1233e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt const int op_classes_vht[] = { 128, 0 }; 1234a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1235b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Prepare channel best"); 1236b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1237a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 && 1238a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_overall) && 12394b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_overall, &op_class, &op_channel) 12404b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt == 0) { 1241b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best overall channel as operating channel preference"); 1242a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1243a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1244a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 && 1245a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_5) && 12464b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_5, &op_class, &op_channel) 12474b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt == 0) { 1248b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best 5 GHz channel as operating channel preference"); 1249a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1250a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1251a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_24 > 0 && 1252a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_24) && 12534b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_24, &op_class, 12544b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt &op_channel) == 0) { 1255b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best 2.4 GHz channel as operating channel preference"); 1256a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1257a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1258b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt } else if (p2p->cfg->num_pref_chan > 0 && 1259b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_channels_includes(&p2p->cfg->channels, 1260b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->cfg->pref_chan[0].op_class, 1261b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->cfg->pref_chan[0].chan)) { 1262b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Select first pref_chan entry as operating channel preference"); 1263b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->op_reg_class = p2p->cfg->pref_chan[0].op_class; 1264b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->op_channel = p2p->cfg->pref_chan[0].chan; 1265e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht, 1266e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &p2p->op_reg_class, &p2p->op_channel) == 1267e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 0) { 1268e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p_dbg(p2p, "Select possible VHT channel (op_class %u channel %u) as operating channel preference", 1269e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1270e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_ht40, 1271e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &p2p->op_reg_class, &p2p->op_channel) == 1272e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 0) { 1273e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p_dbg(p2p, "Select possible HT40 channel (op_class %u channel %u) as operating channel preference", 1274e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1275e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_5ghz, 1276e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &p2p->op_reg_class, &p2p->op_channel) == 1277e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 0) { 1278e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p_dbg(p2p, "Select possible 5 GHz channel (op_class %u channel %u) as operating channel preference", 1279e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1280d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt } else if (p2p_channels_includes(&p2p->cfg->channels, 1281d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->cfg->op_reg_class, 1282d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->cfg->op_channel)) { 1283b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Select pre-configured channel as operating channel preference"); 1284a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = p2p->cfg->op_reg_class; 1285a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = p2p->cfg->op_channel; 1286d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt } else if (p2p_channel_random_social(&p2p->cfg->channels, 1287d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_reg_class, 1288d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_channel) == 0) { 1289d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p_dbg(p2p, "Select random available social channel %d from 2.4 GHz band as operating channel preference", 1290d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->op_channel); 1291d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt } else { 1292d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt /* Select any random available channel from the first available 1293d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt * operating class */ 1294d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p_channel_select(&p2p->cfg->channels, NULL, 1295d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_reg_class, 1296d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_channel); 1297d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p_dbg(p2p, "Select random available channel %d from operating class %d as operating channel preference", 1298d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->op_channel, p2p->op_reg_class); 1299a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1300a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1301a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 1302a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(struct p2p_channels)); 1303a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1304a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1305a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1306a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1307a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * p2p_prepare_channel - Select operating channel for GO Negotiation 1308a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @p2p: P2P module context from p2p_init() 1309a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @dev: Selected peer device 1310a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @force_freq: Forced frequency in MHz or 0 if not forced 1311a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @pref_freq: Preferred frequency in MHz or 0 if no preference 131268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @go: Whether the local end will be forced to be GO 1313a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 on success, -1 on failure (channel not supported for P2P) 1314a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1315a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is used to do initial operating channel selection for GO 1316a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Negotiation prior to having received peer information. The selected channel 1317a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * may be further optimized in p2p_reselect_channel() once the peer information 1318a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * is available. 1319a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 13207a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtint p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev, 132168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt unsigned int force_freq, unsigned int pref_freq, int go) 1322a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 132368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Prepare channel - force_freq=%u pref_freq=%u go=%d", 132468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt force_freq, pref_freq, go); 1325a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq || pref_freq) { 132668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_prepare_channel_pref(p2p, force_freq, pref_freq, go) < 132768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 0) 1328a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1329a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 1330a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_prepare_channel_best(p2p); 1331a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 133268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "prepared channels", &p2p->channels); 133368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (go) 133468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_remove_freqs(&p2p->channels, &p2p->no_go_freq); 133568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt else if (!force_freq) 133668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_union(&p2p->channels, &p2p->cfg->cli_channels, 133768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt &p2p->channels); 133868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "after go/cli filter/add", &p2p->channels); 133968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 1340b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Own preference for operation channel: Operating Class %u Channel %u%s", 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, p2p->op_channel, 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq ? " (forced)" : ""); 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1344a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) 1345a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags |= P2P_DEV_FORCE_FREQ; 1346a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else 1347a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags &= ~P2P_DEV_FORCE_FREQ; 1348a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_set_dev_persistent(struct p2p_device *dev, 13541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int persistent_group) 13551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 13561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (persistent_group) { 13571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 0: 13581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP | 13591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN); 13601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 1: 13621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP; 13631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN; 13641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 2: 13661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP | 13671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN; 13681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 13701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 13711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 13721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 137604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 137704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1378cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int pd_before_go_neg, unsigned int pref_freq, u16 oob_pw_id) 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1382b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 1384cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt " wps_method=%d persistent_group=%d pd_before_go_neg=%d " 1385cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "oob_pw_id=%u", 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1387cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_method, persistent_group, pd_before_go_neg, oob_pw_id); 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 1391b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to unknown P2P Device " MACSTR, 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 139668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq, 139768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt go_intent == 15) < 0) 1398a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1399a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 1403b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) { 1409b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with incomplete information", 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * First, try to connect directly. If the peer does not 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * acknowledge frames, assume it is sleeping and use device 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * discoverability via the GO at that point. 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 142204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 142304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 142404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 142504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 142604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 142704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 142804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 142904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 143004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 143504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pd_before_go_neg) 143604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG; 1437a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else { 143804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 1439a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 14409cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * Assign dialog token and tie breaker here to use the same 14419cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * values in each retry within the same GO Negotiation exchange. 1442a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 1443a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token++; 1444a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (dev->dialog_token == 0) 1445a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token = 1; 14469cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt dev->tie_breaker = p2p->next_tie_breaker; 14479cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt p2p->next_tie_breaker = !p2p->next_tie_breaker; 1448a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->connect_reqs = 0; 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 14521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We need to drop the pending frame to avoid issues with the 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new GO Negotiation, e.g., when the pending frame was from a 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previous attempt at starting a GO Negotiation. 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1465b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Dropped previous pending Action frame TX that was waiting for p2p_scan completion"); 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 1471cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_pw_id = oob_pw_id; 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 1475b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - delay connect send"); 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT; 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN); 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect_send(p2p, dev); 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 148904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 1490d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1491cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt unsigned int pref_freq, u16 oob_pw_id) 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1495b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 1497cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt " wps_method=%d persistent_group=%d oob_pw_id=%u", 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1499cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_method, persistent_group, oob_pw_id); 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 1503b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot authorize unknown P2P Device " MACSTR, 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 150868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq, go_intent == 150968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 15) < 0) 1510a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1511a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 151204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 151304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 151404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 151504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 151604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 151704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 151804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 151904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 152004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 15251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 1530cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_pw_id = oob_pw_id; 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, struct p2p_message *msg) 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1540fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1542b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, msg); 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->listen_channel) { 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 15464b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(msg->listen_channel[3], 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 1549b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown peer Listen channel: " 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c(0x%02x) reg_class=%u channel=%u", 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[0], 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[1], 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[2], 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1557b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update peer " MACSTR 1558b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " Listen channel: %u -> %u MHz", 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, freq); 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = freq; 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 156561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg->wfd_subelems) { 156661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 156761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems); 156861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 156961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 1572b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Completed device entry based on data from GO Negotiation Request"); 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1574b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Created device entry based on GO Neg Req: " 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' " 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d", 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab, dev->info.group_capab, 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name, dev->listen_freq); 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY; 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 1585b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len) 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2); 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2], 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len); 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len; 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_ssid(p2p, params->ssid, ¶ms->ssid_len); 16082271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p_random(params->passphrase, p2p->cfg->passphrase_len); 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go = peer->go_state == LOCAL_GO; 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels intersection; 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freqs; 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1621b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation with " MACSTR " completed (%s will be GO)", 1622b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(peer->info.p2p_device_addr), go ? "local end" : "peer"); 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.role_go = go; 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN); 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN); 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = peer->wps_method; 16291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { 16301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN) 16311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 2; 16321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 16331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 1; 16341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Setup AP mode for WPS provisioning */ 16384b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt res.freq = p2p_channel_to_freq(p2p->op_reg_class, 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel); 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 16422271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p_random(res.passphrase, p2p->cfg->passphrase_len); 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = peer->oper_freq; 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ssid_len) { 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 165168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "own channels", &p2p->channels); 165268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "peer channels", &peer->channels); 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_channels_intersect(&p2p->channels, &peer->channels, 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &intersection); 165568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (go) { 165668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_remove_freqs(&intersection, &p2p->no_go_freq); 165768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "intersection after no-GO removal", 165868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt &intersection); 165968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freqs = 0; 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < intersection.reg_classes; i++) { 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *c = &intersection.reg_class[i]; 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < c->channels; j++) { 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16694b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(c->reg_class, c->channel[j]); 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq_list[freqs++] = freq; 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout; 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 16791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->ssid_set = 0; 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->go_neg_req_sent = 0; 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->wps_method = WPS_NOT_READY; 1682cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt peer->oob_pw_id = 0; 1683413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_free(peer->go_neg_conf); 1684413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt peer->go_neg_conf = NULL; 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PROVISIONING); 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1694b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "RX P2P Public Action from " MACSTR, MAC2STR(sa)); 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len); 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_REQ: 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_RESP: 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_CONF: 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1); 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_REQ: 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_req(p2p, sa, data + 1, len - 1, 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_freq); 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_RESP: 1715051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_REQ: 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_RESP: 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1); 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_REQ: 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_RESP: 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1); 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1731b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported P2P Public Action frame type %d", 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da, 17391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *sa, const u8 *bssid, const u8 *data, 17401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int freq) 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_VENDOR_SPECIFIC: 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 1749a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (len < 4) 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1751a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (WPA_GET_BE32(data) != P2P_IE_VENDOR_TYPE) 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1754a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt data += 4; 1755a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt len -= 4; 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1757a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt p2p_rx_p2p_action(p2p, sa, data, len, freq); 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_REQ: 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq); 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_RESP: 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq); 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_REQ: 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq); 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_RESP: 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq); 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u8 category, 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int freq) 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category == WLAN_ACTION_PUBLIC) { 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq); 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category != WLAN_ACTION_VENDOR_SPECIFIC) 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 4) 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1790a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (WPA_GET_BE32(data) != P2P_IE_VENDOR_TYPE) 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1792a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt data += 4; 1793a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt len -= 4; 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P action frame */ 1796b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "RX P2P Action from " MACSTR, MAC2STR(sa)); 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len); 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NOA: 1803b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - Notice of Absence"); 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_REQ: 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq); 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_RESP: 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1); 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_DISC_REQ: 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq); 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1816b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - unknown type %u", data[0]); 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx) 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status = P2P_SC_SUCCESS; 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_invite_start(void *eloop_ctx, void *timeout_ctx) 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == NULL) 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 1839cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr, 1840cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->invite_dev_pw_id); 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL) 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* not a P2P probe */ 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0) { 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* The Probe Request is not part of P2P Device Discovery. It is 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not known whether the source address of the frame is the P2P 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Device Address or P2P Interface Address. Do not add a new 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer entry based on this frames. 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->country[0] == 0 && msg.listen_channel) 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 1873fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* already known */ 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1884fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PROBE_REQ_ONLY; 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.listen_channel) { 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 18894b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->listen_freq = p2p_channel_to_freq(msg.listen_channel[3], 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[4]); 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1893b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 1, &msg); 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 189561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 189661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 189761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 189861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 189961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1902b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Created device entry based on Probe Req: " MACSTR 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d", 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab, 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab, dev->info.device_name, 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq); 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message *msg) 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 1918fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; /* already known */ 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_info(p2p, addr, dev, msg); 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int dev_type_match(const u8 *dev_type, const u8 *req_dev_type) 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0) 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, 2) == 0 && 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE32(&req_dev_type[2]) == 0 && 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(&req_dev_type[6]) == 0) 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Category match with wildcard OUI/sub-category */ 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[], 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_req_dev_type) 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_req_dev_type; i++) { 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_match(dev_type, req_dev_type[i])) 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_match_dev_type - Match local device type with requested type 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs) 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 on match, 0 on mismatch 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to match the Requested Device Type attribute in 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS IE with the local device types for deciding whether to reply to a Probe 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Request frame. 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps) 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(wps, &attr)) 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* assume no Requested Device Type attributes */ 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.num_req_dev_type == 0) 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* no Requested Device Type attributes -> match */ 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type, 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Primary Device Type matches */ 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < p2p->cfg->num_sec_dev_types; i++) 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->sec_dev_type[i], 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.req_dev_type, 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Secondary Device Type matches */ 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No matching device type found */ 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p) 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 199604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int pw_id = -1; 199761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 199861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 199961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 200061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 200161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_probe_resp); 200261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20042e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]) 20052e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]); 20062e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 200761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 201104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer) { 201204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Advertise immediate availability of WPS credential */ 201304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pw_id = p2p_wps_method_pw_id(p2p->go_neg_peer->wps_method); 201404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 201504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 201668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_build_wps_ie(p2p, buf, pw_id, 1) < 0) { 201768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Failed to build WPS IE for Probe Response"); 201868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpabuf_free(buf); 201968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NULL; 202068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 202261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 202361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 202461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp); 202561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 202661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 20272e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]) 20282e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(buf, 20292e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]); 20302e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P IE */ 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 203304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 203404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 204504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum p2p_probe_req_status 204604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 204704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 20521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_message msg; 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->in_listen || !p2p->drv_in_listen) { 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not in Listen state - ignore Probe Request */ 20577f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt p2p_dbg(p2p, "Not in Listen state (in_listen=%d drv_in_listen=%d) - ignore Probe Request", 20587f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt p2p->in_listen, p2p->drv_in_listen); 205904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_LISTEN; 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) == 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ParseFailed) { 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ignore invalid Probe Request frames */ 2065ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Could not parse Probe Request frame - ignore it"); 206604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_MALFORMED; 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.p2p == NULL) { 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not a P2P probe - ignore it */ 2071ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Not a P2P probe - ignore it"); 207204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dst && !is_broadcast_ether_addr(dst) && 20761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 20771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the broadcast address or our P2P Device Address 20781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 2079ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req DA " MACSTR " not ours - ignore it", 2080ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt MAC2STR(dst)); 208104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (bssid && !is_broadcast_ether_addr(bssid)) { 20851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the Wildcard BSSID */ 2086ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req BSSID " MACSTR " not wildcard - ignore it", 2087ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt MAC2STR(bssid)); 208804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN || 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) != 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not using P2P Wildcard SSID - ignore */ 2095ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req not using P2P Wildcard SSID - ignore it"); 209604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (supp_rates_11b_only(&elems)) { 21001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Indicates support for 11b rates only */ 2101ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req with 11b rates only supported - ignore it"); 210204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 21031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 21061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0) { 21071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Could not parse P2P attributes */ 2108ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Could not parse P2P attributes in Probe Req - ignore it"); 210904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 21101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.device_id && 211304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 21141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Device ID did not match */ 2115ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req requested Device ID " MACSTR " did not match - ignore it", 2116ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt MAC2STR(msg.device_id)); 21171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 211804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check Requested Device Type match */ 21221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.wps_attributes && 21231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !p2p_match_dev_type(p2p, msg.wps_attributes)) { 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No match with Requested Device Type */ 2125ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req requestred Device Type did not match - ignore it"); 21261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 212704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 213104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!p2p->cfg->send_probe_resp) { 213204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Response generated elsewhere */ 2133ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Resp generated elsewhere - do not generate additional response"); 213404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 213504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2137b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Reply to P2P Probe Request in Listen state"); 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We do not really have a specific BSS that this frame is advertising, 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so build a frame that has some information in valid format. This is 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * really only used for discovery purposes, not to learn exact BSS 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parameters. 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 214704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(200 + wpabuf_len(ies)); 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 215204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = NULL; 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp); 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) | 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WLAN_FC_STYPE_PROBE_RESP << 4)); 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, addr, ETH_ALEN); 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN); 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN); 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.beacon_int = host_to_le16(100); 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* hardware or low-level driver will setup seq_ctrl and timestamp */ 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.capab_info = 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE | 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_PRIVACY | 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_SHORT_SLOT_TIME); 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SSID); 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN); 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES); 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 8); 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (60 / 5) | 0x80); 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 90 / 5); 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (120 / 5) | 0x80); 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 180 / 5); 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (240 / 5) | 0x80); 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 360 / 5); 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 480 / 5); 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 540 / 5); 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS); 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 1); 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, p2p->cfg->channel); 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(buf, ies); 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf); 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 219504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 219604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 220004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtenum p2p_probe_req_status 220104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 220204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 220404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum p2p_probe_req_status res; 220504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 220804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len); 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer && 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN) 22139cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt == 0 && 22149cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt !(p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from GO Negotiation peer */ 2216b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Found GO Negotiation peer - try to start GO negotiation from timeout"); 22179cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL); 221904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) && 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer && 22243c4793790bf06f1fe08a2ddf604c9caa855151f1Dmitry Shmidt (p2p->invite_peer->flags & P2P_DEV_WAIT_INV_REQ_ACK) && 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN) 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from Invite peer */ 2228b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Found Invite peer - try to start Invite from timeout"); 22297f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt eloop_cancel_timeout(p2p_invite_start, p2p, NULL); 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL); 223104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 223404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return res; 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, struct wpabuf *p2p_ie) 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* WLAN AP is not a P2P manager */ 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Interface attribute (present if concurrent device and 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Management is enabled) 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_alloc(200); 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = 0; 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->num_groups > 0) { 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect) 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab); 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_p2p_interface(tmp, p2p); 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int p2p_group, struct wpabuf *p2p_ie) 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *peer; 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 229661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_group) 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie); 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 230161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 230261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 230361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_assoc_req); 230461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 230561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 23062e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]) 23072e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]); 23082e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen Timing (may be present) 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Info attribute (shall be present) 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 231561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tmp = wpabuf_alloc(200 + extra); 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 231961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 232061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 232161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req); 232261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 232361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 23242e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]) 23252e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(tmp, 23262e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]); 23272e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = bssid ? p2p_get_device(p2p, bssid) : NULL; 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, 0); 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period, 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(tmp, p2p, peer); 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end) 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE); 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_attr_text(p2p_ie, buf, end); 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 236604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr) 2367c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 2368c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct p2p_message msg; 2369c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2370c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 237104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 2372c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 2373c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 237404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.p2p_device_addr) { 237504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN); 237604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 237704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (msg.device_id) { 237804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.device_id, ETH_ALEN); 237904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 2380c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 238104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 238204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 2383c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 238404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 238504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr) 238604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 238704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *p2p_ie; 238804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 238904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 239004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 239104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_IE_VENDOR_TYPE); 239204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_ie == NULL) 239304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 239404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr); 2395c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpabuf_free(p2p_ie); 239604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 2397c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 2398c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2399c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_clear_go_neg(struct p2p_data *p2p) 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr) 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 2411b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending Group Formation - ignore WPS registration success notification"); 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) != 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 2417b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore WPS registration success notification for " 2418b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " (GO Negotiation peer " MACSTR ")", 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr), 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Ignore unexpected peer address */ 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2424b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Group Formation completed successfully with " MACSTR, 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr)); 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_group_formation_failed(struct p2p_data *p2p) 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 2434b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending Group Formation - ignore group formation failure notification"); 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Group Formation failed with " MACSTR, 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_data * p2p_init(const struct p2p_config *cfg) 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p; 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24492271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (cfg->max_peers < 1 || 24502271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt cfg->passphrase_len < 8 || cfg->passphrase_len > 63) 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg)); 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg = (struct p2p_config *) (p2p + 1); 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg, cfg, sizeof(*cfg)); 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->dev_name) 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(cfg->dev_name); 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->manufacturer) 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(cfg->manufacturer); 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_name) 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(cfg->model_name); 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_number) 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(cfg->model_number); 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->serial_number) 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(cfg->serial_number); 246804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (cfg->pref_chan) { 246904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan * 247004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 247104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->cfg->pref_chan) { 247204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan, 247304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cfg->num_pref_chan * 247404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 247504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 247604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = 0; 247704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 247804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int = 1; 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->max_disc_int = 3; 2481d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = -1; 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random(&p2p->next_tie_breaker, 1); 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->next_tie_breaker &= 0x01; 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->sd_request) 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY; 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE; 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->concurrent_operations) 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER; 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_init(&p2p->devices); 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 249761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = 100; 249861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = 20; 249913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt p2p->num_p2p_sd_queries = 0; 250061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 250168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "initialized"); 250268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); 250368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "cli_channels", &p2p->cfg->cli_channels); 250468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p; 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deinit(struct p2p_data *p2p) 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 251161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 251261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 251361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 251461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 251561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 251661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 251761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 251861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 251961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 252061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 252161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 252261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 252361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 252461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL); 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 25289cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_flush(p2p); 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 253604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->groups); 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->sd_resp); 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 254168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(p2p->no_go_freq.range); 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p); 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_flush(struct p2p_data *p2p) 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *prev; 254904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_find(p2p); 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device, 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list) { 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_sd_queries(p2p); 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_unauthorize(struct p2p_data *p2p, const u8 *addr) 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2569b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unauthorizing " MACSTR, MAC2STR(addr)); 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == dev) 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = WPS_NOT_READY; 2575cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_pw_id = 0; 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check if after_scan_tx is for this peer. If so free it */ 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx && 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) { 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name) 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_name) { 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(dev_name); 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->dev_name == NULL) 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = NULL; 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer) 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = NULL; 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (manufacturer) { 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(manufacturer); 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->manufacturer == NULL) 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_name(struct p2p_data *p2p, const char *model_name) 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = NULL; 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_name) { 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(model_name); 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_name == NULL) 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_number(struct p2p_data *p2p, const char *model_number) 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = NULL; 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_number) { 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(model_number); 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_number == NULL) 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number) 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = NULL; 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (serial_number) { 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(serial_number); 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->serial_number == NULL) 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods) 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->config_methods = config_methods; 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid) 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->uuid, uuid, 16); 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type) 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8); 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8], 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_dev_types) 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_dev_types > P2P_SEC_DEVICE_TYPES) 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_dev_types = P2P_SEC_DEVICE_TYPES; 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->num_sec_dev_types = num_dev_types; 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8); 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_remove_wps_vendor_extensions(struct p2p_data *p2p) 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->wps_vendor_ext[i]); 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = NULL; 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_add_wps_vendor_extension(struct p2p_data *p2p, 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *vendor_ext) 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor_ext == NULL) 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= P2P_MAX_WPS_VENDOR_EXT) 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext); 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_country(struct p2p_data *p2p, const char *country) 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->country, country, 3); 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_continue_find(struct p2p_data *p2p) 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 273513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (dev->sd_pending_bcast_queries == 0) { 273613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt /* Initialize with total number of registered broadcast 273713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt * SD queries. */ 273813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt dev->sd_pending_bcast_queries = p2p->num_p2p_sd_queries; 273913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 274013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 274113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (p2p_start_sd(p2p, dev) == 0) 274213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return; 274313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (dev->req_config_methods && 274413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt !(dev->flags & P2P_DEV_PD_FOR_JOIN)) { 2745b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Provision Discovery Request to " 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (config methods 0x%x)", 27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods); 27491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0) 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2754d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 1); 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_sd_cb(struct p2p_data *p2p, int success) 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2760b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Service Discovery Query TX callback: success=%d", 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 276513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt p2p->sd_peer = NULL; 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == NULL) { 2771b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No SD peer entry known"); 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SD_DURING_FIND); 27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 278275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/** 278375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * p2p_retry_pd - Retry any pending provision disc requests in IDLE state 278475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @p2p: P2P module context from p2p_init() 278575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 27861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_retry_pd(struct p2p_data *p2p) 278775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 278875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct p2p_device *dev; 278975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 279075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->state != P2P_IDLE) 279175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 279275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 279375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 279475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Retry the prov disc req attempt only for the peer that the user had 2795d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * requested. 279675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 279775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 279875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 279975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (os_memcmp(p2p->pending_pd_devaddr, 280075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.p2p_device_addr, ETH_ALEN) != 0) 280175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 280275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!dev->req_config_methods) 280375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 280475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 2805b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Provision Discovery Request to " 280675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MACSTR " (config methods 0x%x)", 280775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MAC2STR(dev->info.p2p_device_addr), 280875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->req_config_methods); 2809d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_send_prov_disc_req(p2p, dev, 2810051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN, 2811051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p2p->pd_force_freq); 281275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 281375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 281475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 281575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 281675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_prov_disc_cb(struct p2p_data *p2p, int success) 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2819b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request TX callback: success=%d", 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 282175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 282275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 282375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Postpone resetting the pending action state till after we actually 282475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * time out. This allows us to take some action like notifying any 282575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * interested parties about no response to the request. 282675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 282775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When the timer (below) goes off we check in IDLE, SEARCH, or 282875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * LISTEN_ONLY state, which are the only allowed states to issue a PD 282975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * requests in, if this was still pending and then raise notification. 283075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 283375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 283475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 283561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->user_initiated_pd && 283661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->state == P2P_SEARCH || p2p->state == P2P_LISTEN_ONLY)) 283761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { 283861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Retry request from timeout to avoid busy loops */ 283961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 284061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, 0, 50000); 284161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (p2p->state != P2P_IDLE) 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 284375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else if (p2p->user_initiated_pd) { 284475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 284575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_set_timeout(p2p, 0, 300000); 284675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 285075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 285175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * This postponing, of resetting pending_action_state, needs to be 285275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * done only for user initiated PD requests and not internal ones. 285375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 285475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd) 285575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 285675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else 285775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 285875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PD_DURING_FIND); 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, 2867fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime *rx_time, int level, const u8 *ies, 2868a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len) 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2870fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (os_reltime_before(rx_time, &p2p->find_start)) { 2871f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 2872f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * The driver may have cached (e.g., in cfg80211 BSS table) the 2873f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * scan results for relatively long time. To avoid reporting 2874f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * stale information, update P2P peers only based on results 2875f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * that have based on frames received after the last p2p_find 2876f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * operation was started. 2877f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 2878b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore old scan result for " MACSTR 2879b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " (rx_time=%u.%06u)", 2880f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt MAC2STR(bssid), (unsigned int) rx_time->sec, 2881f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec); 2882f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 2883f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 2884f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 2885f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt p2p_add_device(p2p, bssid, freq, rx_time, level, ies, ies_len, 1); 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_scan_res_handled(struct p2p_data *p2p) 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->p2p_scan_running) { 2894b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan was not running, but scan results received"); 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_run_after_scan(p2p)) 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2906c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id) 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 290861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len; 290961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 291061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 291161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_req) 291261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(ies, p2p->wfd_ie_probe_req); 291361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 291461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 29152e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]) 29162e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(ies, 29172e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]); 29182e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 291961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len = p2p_buf_add_ie_hdr(ies); 292004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(ies, p2p->dev_capab & 292104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 2922c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) 2923c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_buf_add_device_id(ies, dev_id); 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->reg_class && p2p->cfg->channel) 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_listen_channel(ies, p2p->cfg->country, 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class, 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period, 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: p2p_buf_add_operating_channel() if GO */ 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(ies, len); 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtsize_t p2p_scan_ie_buf_len(struct p2p_data *p2p) 29371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 293861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 100; 293961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 294061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 294161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p && p2p->wfd_ie_probe_req) 294261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += wpabuf_len(p2p->wfd_ie_probe_req); 294361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 294461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 29452e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p && p2p->vendor_elem && 29462e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]) 29472e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt len += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]); 29482e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 294961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 29501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 29511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end) 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_attr_text(p2p_ie, buf, end); 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_req_cb(struct p2p_data *p2p, int success) 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 29628c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt int timeout; 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2964b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Request TX callback: success=%d", success); 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 2967b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending GO Negotiation"); 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (success) { 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 297604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (dev->go_neg_req_sent) { 297704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Cancel the increment from p2p_connect_send() on failure */ 297898f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt dev->go_neg_req_sent--; 297998f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt } 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success && 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) && 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(dev->member_in_go_dev)) { 2984b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " did not acknowledge request - try to use device discoverability through its GO", 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_send_dev_disc_req(p2p, dev); 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use P2P find, if needed, to find the other device from its listen 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 29968c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout = success ? 500000 : 100000; 29978c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (!success && p2p->go_neg_peer && 29988c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE)) { 29998c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt unsigned int r; 30008c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt /* 30018c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * Peer is expected to wait our response and we will skip the 30028c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * listen phase. Add some randomness to the wait time here to 30038c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * make it less likely to hit cases where we could end up in 30048c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * sync with peer not listening. 30058c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt */ 30068c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 30078c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout += r % 100000; 30088c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 30098c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, timeout); 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success) 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3015b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Response TX callback: success=%d", 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) { 3018b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore TX callback event - GO Negotiation is not running anymore"); 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 30228c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30264b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtstatic void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success, 30274b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt const u8 *addr) 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3029b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Response (failure) TX callback: success=%d", success); 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) { 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status); 30334b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } else if (success) { 30344b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt struct p2p_device *dev; 30354b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev = p2p_get_device(p2p, addr); 30364b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (dev && 30371d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance dev->status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { 30384b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->flags |= P2P_DEV_PEER_WAITING_RESPONSE; 30391d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance if ((p2p->state == P2P_SEARCH) || 30401d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance (p2p->state == P2P_LISTEN_ONLY)) { 30411d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance /* Clear our search state or Listen state since 30421d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance * now peer is awaiting response from our side. 30431d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance */ 30441d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance p2p_dbg(p2p, "Clear the P2P discovery state"); 30451d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance p2p_stop_find(p2p); 30461d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance } 30471d57ba2e974d60c4b36b65c9d58f6ec7cebad0aaJithu Jance } 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_conf_cb(struct p2p_data *p2p, 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3057b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Confirm TX callback: result=%d", result); 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_FAILED) { 3059413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3063413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 3064413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev = p2p->go_neg_peer; 3065413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_NO_ACK) { 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3068413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * Retry GO Negotiation Confirmation 3069413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * P2P_GO_NEG_CNF_MAX_RETRY_COUNT times if we did not receive 3070413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * ACK for confirmation. 3071413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt */ 3072413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt if (dev && dev->go_neg_conf && 3073413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->go_neg_conf_sent <= P2P_GO_NEG_CNF_MAX_RETRY_COUNT) { 3074413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p_dbg(p2p, "GO Negotiation Confirm retry %d", 3075413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->go_neg_conf_sent); 3076413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->pending_action_state = P2P_PENDING_GO_NEG_CONFIRM; 3077413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt if (p2p_send_action(p2p, dev->go_neg_conf_freq, 3078413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->info.p2p_device_addr, 3079413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->cfg->dev_addr, 3080413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->info.p2p_device_addr, 3081413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_head(dev->go_neg_conf), 3082413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_len(dev->go_neg_conf), 0) >= 3083413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 0) { 3084413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->go_neg_conf_sent++; 3085413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt return; 3086413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt } 3087413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p_dbg(p2p, "Failed to re-send Action frame"); 3088413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 3089413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt /* 3090413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * Continue with the assumption that the first attempt 3091413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * went through and just the ACK frame was lost. 3092413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt */ 3093413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt } 3094413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 3095413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt /* 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * It looks like the TX status for GO Negotiation Confirm is 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * often showing failure even when the peer has actually 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received the frame. Since the peer may change channels 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately after having received the frame, we may not see 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an Ack for retries, so just dropping a single frame may 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * trigger this. To allow the group formation to succeed if the 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer did indeed receive the frame, continue regardless of 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the TX status. 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3105b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Assume GO Negotiation Confirm TX was actually received by the peer even though Ack was not reported"); 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3109413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_complete(p2p, dev); 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_pending_action_state state; 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int success; 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3124b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Action frame TX callback (state=%d freq=%u dst=" MACSTR 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " src=" MACSTR " bssid=" MACSTR " result=%d", 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src), 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), result); 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success = result == P2P_SEND_ACTION_SUCCESS; 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = p2p->pending_action_state; 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NO_PENDING_ACTION: 31334582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt if (p2p->send_action_in_progress) { 31344582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt p2p->send_action_in_progress = 0; 31354582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 31364582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt } 31378da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->after_scan_tx_in_progress) { 31388da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 31398da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->start_after_scan != P2P_AFTER_SCAN_NOTHING && 31408da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p_run_after_scan(p2p)) 31418da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt break; 31428da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->state == P2P_SEARCH) { 3143b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Continue find after after_scan_tx completion"); 31448da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p_continue_find(p2p); 31458da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 31468da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_REQUEST: 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_req_cb(p2p, success); 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE: 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_cb(p2p, success); 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE_FAILURE: 31554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_go_neg_resp_failure_cb(p2p, success, dst); 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_CONFIRM: 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_conf_cb(p2p, result); 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_SD: 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_cb(p2p, success); 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_PD: 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_prov_disc_cb(p2p, success); 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_REQUEST: 31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_req_cb(p2p, success); 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_RESPONSE: 31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_resp_cb(p2p, success); 31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_REQUEST: 31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_req_cb(p2p, success); 31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_RESPONSE: 31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_resp_cb(p2p, success); 31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_DISC_REQ: 31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_disc_req_cb(p2p, success); 31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31828da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt 31838da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_listen_cb(struct p2p_data *p2p, unsigned int freq, 31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int duration) 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == p2p->pending_client_disc_freq) { 3191b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability remain-awake completed"); 31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_freq = 0; 31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != p2p->pending_listen_freq) { 3197b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unexpected listen callback for freq=%u duration=%u (pending_listen_freq=%u)", 31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration, p2p->pending_listen_freq); 31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3202b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting Listen timeout(%u,%u) on freq=%u based on callback", 32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec, p2p->pending_listen_usec, 32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq); 32058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 1; 32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = freq; 32078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_listen_sec || p2p->pending_listen_usec) { 32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Add 20 msec extra wait to avoid race condition with driver 32108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * remain-on-channel end event, i.e., give driver more time to 32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * complete the operation before our timeout expires. 32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, p2p->pending_listen_sec, 32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec + 20000); 32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen_end(struct p2p_data *p2p, unsigned int freq) 32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3223b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver ended Listen state (freq=%u)", freq); 32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = 0; 32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->in_listen) 32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Internal timeout will trigger the next step */ 32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) { 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 3230b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (p2p->state == P2P_SEARCH) { 3239c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->p2p_scan_running) { 3240c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 3241c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Search is already in progress. This can happen if 3242c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * an Action frame RX is reported immediately after 3243c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * the end of a remain-on-channel operation and the 3244c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * response frame to that is sent using an offchannel 3245c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * operation while in p2p_find. Avoid an attempt to 3246c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * restart a scan here. 3247c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 3248b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan already in progress - do not try to start a new one"); 3249c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 1; 3250c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 325104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->pending_listen_freq) { 325204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 325304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Better wait a bit if the driver is unable to start 325404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * offchannel operation for some reason. p2p_search() 325504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * will be started from internal timeout. 325604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 3257b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Listen operation did not seem to start - delay search phase to avoid busy loop"); 325804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 325904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 326004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 326161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay) { 3262b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay search operation by %u ms", 326361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 326461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 326561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 326661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 326761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect(struct p2p_data *p2p) 32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 327904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer && 328004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 3281b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Wait for GO Negotiation Confirm timed out - assume GO Negotiation failed"); 328204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 328304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 328404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 32858c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer && 32868c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE) && 32878c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->connect_reqs < 120) { 3288b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer expected to wait our response - skip listen"); 32898c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 32908c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt return; 32918c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 3292cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->oob_go_neg_freq > 0) { 3293cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Skip connect-listen since GO Neg channel known (OOB)"); 3294cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 3295cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_set_timeout(p2p, 0, 30000); 3296cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return; 3297cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 3299d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect_listen(struct p2p_data *p2p) 33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer) { 33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 3307b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver is still in Listen state; wait for it to complete"); 33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 3312b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_connect(struct p2p_data *p2p) 33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); 33271846323989242844f0e857458a8939fa5836429cDmitry Shmidt 33281846323989242844f0e857458a8939fa5836429cDmitry Shmidt if (p2p->cfg->is_concurrent_session_active && 33291846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p->cfg->is_concurrent_session_active(p2p->cfg->cb_ctx)) 33301846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 33311846323989242844f0e857458a8939fa5836429cDmitry Shmidt else 33321846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_idle(struct p2p_data *p2p) 33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 33396dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt struct os_reltime now; 33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 3342b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown GO Neg peer - stop GO Neg wait"); 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33466dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt os_get_reltime(&now); 33476dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt if (os_reltime_expired(&now, &dev->go_neg_wait_started, 120)) { 3348b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on waiting peer to become ready for GO Negotiation"); 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3353b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Go to Listen state while waiting for the peer to become ready for GO Negotiation"); 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); 3355d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_sd_during_find(struct p2p_data *p2p) 33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3361b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Service Discovery Query timeout"); 33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p) 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3372b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request timeout"); 33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 337875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void p2p_timeout_prov_disc_req(struct p2p_data *p2p) 337975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 338075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 338175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 338275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 338375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * For user initiated PD requests that we have not gotten any responses 338475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * for while in IDLE state, we retry them a couple of times before 338575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * giving up. 338675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 338775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!p2p->user_initiated_pd) 338875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 338975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3390b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "User initiated Provision Discovery Request timeout"); 339175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 339275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pd_retries) { 339375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries--; 339475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_retry_pd(p2p); 339575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 3396d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct p2p_device *dev; 3397d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int for_join = 0; 3398d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3399d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3400d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (os_memcmp(p2p->pending_pd_devaddr, 3401d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dev->info.p2p_device_addr, ETH_ALEN) != 0) 3402d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt continue; 3403d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (dev->req_config_methods && 3404d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (dev->flags & P2P_DEV_PD_FOR_JOIN)) 3405d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join = 1; 3406d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 3407d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 340875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 340975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, 341075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_pd_devaddr, 3411d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join ? 3412d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt P2P_PROV_DISC_TIMEOUT_JOIN : 341375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_TIMEOUT); 341475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 341575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 341675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 341775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 341875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite(struct p2p_data *p2p) 34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE_LISTEN); 34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { 34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Better remain on operating channel instead of listen channel 34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * when running a group. 34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3428b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Inviting in active GO role - wait on operating channel"); 34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3432d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite_listen(struct p2p_data *p2p) 34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) { 34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE); 34408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, 3441cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->invite_go_dev_addr, p2p->invite_dev_pw_id); 34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer) { 3444b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Invitation Request retry limit reached"); 34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->invitation_result) 34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->invitation_result( 3447700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->cfg->cb_ctx, -1, NULL, NULL, 3448e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->invite_peer->info.p2p_device_addr, 344915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 0, 0); 34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx) 34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3460b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout (state=%s)", p2p_state_txt(p2p->state)); 34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 0; 34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p->state) { 34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 346675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 346775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 346875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 347175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 347275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 347375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 347461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay && !p2p->in_search_delay) { 3475b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay search operation by %u ms", 347661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 347761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 1; 347861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 347961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 348061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 348161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 348261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect(p2p); 34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect_listen(p2p); 34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 349475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 349575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 349675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 349775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_only) { 3499b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Extended Listen Timing - Listen State completed"); 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_connect(p2p); 35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_idle(p2p); 35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_sd_during_find(p2p); 35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 35148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_prov_disc_during_find(p2p); 35178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 35198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite(p2p); 35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 35228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite_listen(p2p); 35238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_reject(struct p2p_data *p2p, const u8 *peer_addr) 35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 35318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 3533b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Local request to reject connection attempts by peer " 3534b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(peer_addr)); 35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 3536b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " unknown", MAC2STR(peer_addr)); 35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_FAIL_REJECTED_BY_USER; 35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_USER_REJECTED; 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst char * p2p_wps_method_text(enum p2p_wps_method method) 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (method) { 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_NOT_READY: 35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "not-ready"; 35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Display"; 35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Keypad"; 35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 35558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PBC"; 3556cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case WPS_NFC: 3557cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return "NFC"; 35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_go_state_text(enum p2p_go_state go_state) 35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (go_state) { 35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case UNKNOWN_GO: 35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "unknown"; 35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case LOCAL_GO: 35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "local"; 35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case REMOTE_GO: 35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "remote"; 35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p, 35801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr, int next) 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) 35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev && next) { 35908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, struct p2p_device, list); 35918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = NULL; 35938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 35961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 35971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return &dev->info; 35991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 36001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_get_peer_info_txt(const struct p2p_peer_info *info, 36031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *buf, size_t buflen) 36041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 36051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 36061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int res; 36071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *pos, *end; 3608fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now; 36091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (info == NULL) 36118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = (struct p2p_device *) (((u8 *) info) - 36141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offsetof(struct p2p_device, info)); 36151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 36178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 36188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3619fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 36208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 36218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "age=%d\n" 36228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d\n" 36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wps_method=%s\n" 36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface_addr=" MACSTR "\n" 36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_dev=" MACSTR "\n" 36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_iface=" MACSTR "\n" 36278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_neg_req_sent=%d\n" 36288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_state=%s\n" 36298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dialog_token=%u\n" 36308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "intended_addr=" MACSTR "\n" 36318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c\n" 36328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_freq=%d\n" 36338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "req_config_methods=0x%x\n" 363413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s\n" 36358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d\n" 36368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation_reqs=%u\n", 36378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (now.sec - dev->last_seen.sec), 36388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, 36398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_method_text(dev->wps_method), 36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->interface_addr), 36418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_dev), 36428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_iface), 36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent, 36448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_state_text(dev->go_state), 36458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token, 36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->intended_addr), 36478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[0] ? dev->country[0] : '_', 36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[1] ? dev->country[1] : '_', 36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq, 36508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 36518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PROBE_REQ_ONLY ? 36528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PROBE_REQ_ONLY]" : "", 36538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "", 36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_NOT_YET_READY ? 36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[NOT_YET_READY]" : "", 36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_DISPLAY ? 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_DISPLAY]" : "", 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_KEYPAD ? 36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_KEYPAD]" : "", 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_USER_REJECTED ? 36618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[USER_REJECTED]" : "", 36628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ? 36638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PEER_WAITING_RESPONSE]" : "", 36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ? 36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PREFER_PERSISTENT_GROUP]" : "", 36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ? 36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_RESPONSE]" : "", 36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ? 36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_CONFIRM]" : "", 36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ? 36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[GROUP_CLIENT_ONLY]" : "", 36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_FORCE_FREQ ? 36738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[FORCE_FREQ]" : "", 36748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN ? 36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_FOR_JOIN]" : "", 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status, 36778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->invitation_reqs); 36788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->ext_listen_period) { 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_period=%u\n" 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_interval=%u\n", 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period, 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval); 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_ssid_len) { 36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_ssid=%s\n", 36968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(dev->oper_ssid, 36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len)); 36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 37018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 370361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 370461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (dev->info.wfd_subelems) { 370561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "wfd_subelems="); 370661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 370761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 370861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 370961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 371061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, 371161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_head(dev->info.wfd_subelems), 371261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(dev->info.wfd_subelems)); 371361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 371461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "\n"); 371561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 371661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 371761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 371861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 371961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 372061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_peer_known(struct p2p_data *p2p, const u8 *addr) 37261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 37271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_get_device(p2p, addr) != NULL; 37281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 37291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 37301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_client_discoverability(struct p2p_data *p2p, int enabled) 37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 3734b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability enabled"); 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3737b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability disabled"); 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1, 37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration2, u32 interval2) 37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL; 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = wpabuf_alloc(100); 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration1 || interval1) { 37558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc1, 0, sizeof(desc1)); 37568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.count_type = 1; 37578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.duration = duration1; 37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.interval = interval1; 37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr1 = &desc1; 37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration2 || interval2) { 37628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc2, 0, sizeof(desc2)); 37638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.count_type = 2; 37648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.duration = duration2; 37658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.interval = interval2; 37668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr2 = &desc2; 37678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1); 37718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(req); 37728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2); 37738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(req, len); 37748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 37768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr, 37808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *own_interface_addr, unsigned int freq, 37818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration1, u32 interval1, u32 duration2, 37828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval2) 37838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 37858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3786b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send Presence Request to GO " MACSTR 3787b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " (own interface " MACSTR ") freq=%u dur1=%u int1=%u " 3788b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "dur2=%u int2=%u", 37898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_interface_addr), MAC2STR(own_interface_addr), 37908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration1, interval1, duration2, interval2); 37918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_presence_req(duration1, interval1, duration2, 37938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interval2); 37948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 37958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 37968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 37988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr, 37998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_interface_addr, 38008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 3801b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 38028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 38048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa, 38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t noa_len, u8 dialog_token) 38118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 38138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 38148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_alloc(100 + noa_len); 38168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 38188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token); 38208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(resp); 38218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_status(resp, status); 38228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (noa) { 38238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE); 38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_le16(resp, noa_len); 38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, noa, noa_len); 38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 38278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL); 38288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(resp, len); 38298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 38318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 38358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 38368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq) 38378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 38398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 status; 38408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 38418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t g; 38428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group = NULL; 38438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int parsed = 0; 38448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 noa[50]; 38458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int noa_len; 38468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3847b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - P2P Presence Request"); 38488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 38508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]), 38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 38528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p->groups[g]; 38538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 38548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) { 3857b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore P2P Presence Request for unknown group " 38588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(da)); 38598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 3863b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P Presence Request"); 38648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 38658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 38668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parsed = 1; 38688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.noa == NULL) { 3870b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No NoA attribute in P2P Presence Request"); 38718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 38728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 38738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len); 38768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 38788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->get_noa) 38798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa, 38808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(noa)); 38818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = -1; 38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL, 38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len > 0 ? noa_len : 0, 38858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token); 38868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parsed) 38878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, rx_freq, sa, da, da, 38938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 3894b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 38978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 39018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len) 39028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 39048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3905b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - P2P Presence Response"); 39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 3908b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P Presence Response"); 39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.status == NULL || msg.noa == NULL) { 3913b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No Status or NoA attribute in P2P Presence Response"); 39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p->cfg->presence_resp) { 3919fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt p2p->cfg->presence_resp(p2p->cfg->cb_ctx, sa, *msg.status, 3920fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt msg.noa, msg.noa_len); 3921fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3922fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 39238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.status) { 3924b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "P2P Presence Request was rejected: status %u", 39258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.status); 39268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3930b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "P2P Presence Request was accepted"); 39318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA", 39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.noa, msg.noa_len); 39338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: process NoA */ 39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx) 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 39418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) { 39438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Schedule next extended listen timeout */ 39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39496dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt if ((p2p->cfg->is_p2p_in_progress && 39506dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt p2p->cfg->is_p2p_in_progress(p2p->cfg->cb_ctx)) || 39516dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt (p2p->pending_action_state == P2P_PENDING_PD && 39526dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt p2p->pd_retries > 0)) { 39535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt p2p_dbg(p2p, "Operation in progress - skip Extended Listen timeout (%s)", 39545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt p2p_state_txt(p2p->state)); 39555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 39565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 39575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) { 39598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 39608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This should not really happen, but it looks like the Listen 39618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * command may fail is something else (e.g., a scan) was 39628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * running at an inconvenient time. As a workaround, allow new 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen operation to be started. 39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3965b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Previous Extended Listen operation had not been completed - try again"); 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) { 3971b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip Extended Listen timeout in active state (%s)", p2p_state_txt(p2p->state)); 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3975b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Extended Listen timeout"); 39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 1; 39778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen(p2p, p2p->ext_listen_period) < 0) { 3978b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start Listen state for Extended Listen Timing"); 39798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ext_listen(struct p2p_data *p2p, unsigned int period, 39858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 39868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (period > 65535 || interval > 65535 || period > interval || 39888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (period == 0 && interval > 0) || (period > 0 && interval == 0)) { 3989b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Invalid Extended Listen Timing request: period=%u interval=%u", 3990b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt period, interval); 39918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 39958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (interval == 0) { 3997b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disabling Extended Listen Timing"); 39988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = 0; 39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = 0; 40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4003b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Enabling Extended Listen Timing: period %u msec, interval %u msec", 4004b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt period, interval); 40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = period; 40068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = interval; 40078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_sec = interval / 1000; 40088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec = (interval % 1000) * 1000; 40098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 40118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 40128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 40138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 40198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 40208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 40228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 40248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 40278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 40288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40299767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt if (msg.minor_reason_code == NULL) { 40309767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt p2p_parse_free(&msg); 40318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40329767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt } 40338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4034b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Deauthentication notification BSSID " MACSTR 40358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 40368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 40378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 40398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 40438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 40448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 40468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 40488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 40518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 40528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40539767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt if (msg.minor_reason_code == NULL) { 40549767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt p2p_parse_free(&msg); 40558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40569767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt } 40578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4058b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disassociation notification BSSID " MACSTR 40598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 40608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 40618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 40638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_managed_oper(struct p2p_data *p2p, int enabled) 40678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 4069b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Managed P2P Device operations enabled"); 40708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED; 40718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4072b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Managed P2P Device operations disabled"); 40738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED; 40748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 407843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtint p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel, 407943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u8 forced) 40808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40814b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(reg_class, channel) < 0) 40828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4084b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set Listen channel: reg_class %u channel %u", 4085b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt reg_class, channel); 408643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 408743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* 408843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * Listen channel was set in configuration or set by control interface; 408943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * cannot override it. 409043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt */ 409143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p->cfg->channel_forced && forced == 0) 409243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return -1; 409343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 409443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p->state == P2P_IDLE) { 409543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->reg_class = reg_class; 409643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->channel = channel; 409743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->channel_forced = forced; 409843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } else { 409943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p_dbg(p2p, "Defer setting listen channel"); 410043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_reg_class = reg_class; 410143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_channel = channel; 410243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_channel_forced = forced; 410343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 41048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 410943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtu8 p2p_get_listen_channel(struct p2p_data *p2p) 411043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{ 411143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return p2p->cfg->channel; 411243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt} 411343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 411443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 41158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len) 41168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4117b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "New SSID postfix: %s", wpa_ssid_txt(postfix, len)); 41188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (postfix == NULL) { 41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = 0; 41208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(p2p->cfg->ssid_postfix)) 41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->ssid_postfix, postfix, len); 41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = len; 41268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 413075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenint p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel, 413175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int cfg_op_channel) 413275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 41334b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(op_reg_class, op_channel) < 0) 413475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 413575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4136b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set Operating channel: reg_class %u channel %u", 4137b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt op_reg_class, op_channel); 413875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_reg_class = op_reg_class; 413975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_channel = op_channel; 414075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->cfg_op_channel = cfg_op_channel; 414175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return 0; 414275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 414375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 414475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 414504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan, 414604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const struct p2p_channel *pref_chan) 414704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 414804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct p2p_channel *n; 414904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 415004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pref_chan) { 415104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = os_malloc(num_pref_chan * sizeof(struct p2p_channel)); 415204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (n == NULL) 415304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 415404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(n, pref_chan, 415504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_pref_chan * sizeof(struct p2p_channel)); 415604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 415704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = NULL; 415804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 415904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 416004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = n; 416104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = num_pref_chan; 416204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 416304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 416404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 416504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 416604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 416768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_set_no_go_freq(struct p2p_data *p2p, 416868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct wpa_freq_range_list *list) 416968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 417068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct wpa_freq_range *tmp; 417168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 417268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (list == NULL || list->num == 0) { 417368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(p2p->no_go_freq.range); 417468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.range = NULL; 417568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.num = 0; 417668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 417768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 417868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 417968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt tmp = os_calloc(list->num, sizeof(struct wpa_freq_range)); 418068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (tmp == NULL) 418168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return -1; 418268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(tmp, list->range, list->num * sizeof(struct wpa_freq_range)); 418368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(p2p->no_go_freq.range); 418468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.range = tmp; 418568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.num = list->num; 418668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Updated no GO chan list"); 418768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 418868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 418968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 419068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 419168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 41928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr, 41938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *iface_addr) 41948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device(p2p, dev_addr); 41968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || is_zero_ether_addr(dev->interface_addr)) 41978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN); 41998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr, 42048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *dev_addr) 42058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 42078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 42088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN); 42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr) 42158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->peer_filter, addr, ETH_ALEN); 42178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(p2p->peer_filter)) 4218b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disable peer filter"); 42198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4220b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Enable peer filter for " MACSTR, 4221b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(p2p->peer_filter)); 42228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_cross_connect(struct p2p_data *p2p, int enabled) 42268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4227b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cross connection %s", enabled ? "enabled" : "disabled"); 42288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cross_connect == enabled) 42298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 42308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect = enabled; 42318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: may need to tear down any action group where we are GO(?) */ 42328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr) 42368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 42388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 42398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) 42418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev->oper_freq; 42438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled) 42478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4248b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Intra BSS distribution %s", 42498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 42508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->p2p_intra_bss = enabled; 42518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 425468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_update_channel_list(struct p2p_data *p2p, 425568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_channels *chan, 425668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_channels *cli_chan) 42578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4258b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update channel list"); 42598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels)); 426068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); 426168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(&p2p->cfg->cli_channels, cli_chan, 426268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt sizeof(struct p2p_channels)); 426368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "cli_channels", &p2p->cfg->cli_channels); 42648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 42688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 42698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 42708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 4272b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay Action frame TX until p2p_scan completes"); 42738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 4274b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Dropped previous pending Action frame TX"); 42758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 42768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) + 42788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 42798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx == NULL) 42808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->freq = freq; 42828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN); 42838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN); 42848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN); 42858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->len = len; 42868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->wait_time = wait_time; 42878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx + 1, buf, len); 42888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, 42928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len, wait_time); 42938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, 42978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_overall) 42988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4299b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Best channel: 2.4 GHz: %d, 5 GHz: %d, overall: %d", 4300b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq_24, freq_5, freq_overall); 43018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24 = freq_24; 43028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_5 = freq_5; 43038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_overall = freq_overall; 43048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4307700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtvoid p2p_set_own_freq_preference(struct p2p_data *p2p, int freq) 4308700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 4309b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Own frequency preference: %d MHz", freq); 4310700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->own_freq_preference = freq; 4311700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 4312700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 4313700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 43148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_neg_peer(struct p2p_data *p2p) 43158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 43168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || p2p->go_neg_peer == NULL) 43178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->go_neg_peer->info.p2p_device_addr; 43198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct p2p_peer_info * 43238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtp2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next) 43248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 43258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 43268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 43288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 43298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 43308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!next) { 43338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) 43348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 43378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 43388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 43398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 43408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 43418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 43427832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (!dev || &dev->list == &p2p->devices) 43438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY); 43458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 43478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 43488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 43498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 43518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 43528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 43538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 43547832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (!dev || &dev->list == &p2p->devices) 43558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 43608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 43621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 43631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_in_progress(struct p2p_data *p2p) 43641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 43651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 43661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 4367fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p->state == P2P_SEARCH) 436861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 2; 43691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING; 43701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 437161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 437261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 437361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout, 437461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 client_timeout) 437561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 437661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p) { 437761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = go_timeout; 437861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = client_timeout; 437961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 438061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 438161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 438261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 438361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 438461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 438561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void p2p_update_wfd_ie_groups(struct p2p_data *p2p) 438661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 438761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t g; 438861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_group *group; 438961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 439061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 439161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt group = p2p->groups[g]; 4392b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt p2p_group_force_beacon_update_ies(group); 439361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 439461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 439561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 439661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 439761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_beacon(struct p2p_data *p2p, struct wpabuf *ie) 439861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 439961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 440061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_beacon = ie; 440161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 440261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 440361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 440461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 440561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 440661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_req(struct p2p_data *p2p, struct wpabuf *ie) 440761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 440861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 440961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_req = ie; 441061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 441161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 441261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 441361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 441461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_resp(struct p2p_data *p2p, struct wpabuf *ie) 441561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 441661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 441761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_resp = ie; 441861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 441961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 442061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 442161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 442261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 442361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_assoc_req(struct p2p_data *p2p, struct wpabuf *ie) 442461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 442561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 442661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_assoc_req = ie; 442761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 442861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 442961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 443061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 443161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_invitation(struct p2p_data *p2p, struct wpabuf *ie) 443261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 443361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 443461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_invitation = ie; 443561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 443661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 443761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 443861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 443961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_req(struct p2p_data *p2p, struct wpabuf *ie) 444061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 444161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 444261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_req = ie; 444361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 444461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 444561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 444661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 444761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_resp(struct p2p_data *p2p, struct wpabuf *ie) 444861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 444961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 445061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_resp = ie; 445161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 445261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 445361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 445461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 445561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_go_neg(struct p2p_data *p2p, struct wpabuf *ie) 445661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 445761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 445861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_go_neg = ie; 445961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 446061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 446161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 446261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 446361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_dev_info(struct p2p_data *p2p, const struct wpabuf *elem) 446461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 446561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 446661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 446761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = wpabuf_dup(elem); 446861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_dev_info == NULL) 446961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 447061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 447161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = NULL; 447261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 447361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 447461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 447561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 447661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 447761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_assoc_bssid(struct p2p_data *p2p, const struct wpabuf *elem) 447861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 447961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 448061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 448161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = wpabuf_dup(elem); 448261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_assoc_bssid == NULL) 448361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 448461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 448561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = NULL; 448661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 448761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 448861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 448961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 449061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 449161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p, 449261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpabuf *elem) 449361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 449461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 449561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 449661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = wpabuf_dup(elem); 449761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_coupled_sink_info == NULL) 449861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 449961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 450061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = NULL; 450161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 450261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 450361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 450461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 450561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 4506d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4507d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4508d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int, 4509d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int max_disc_tu) 4510d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 4511d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (min_disc_int > max_disc_int || min_disc_int < 0 || max_disc_int < 0) 4512d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 4513d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4514d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->min_disc_int = min_disc_int; 4515d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_int = max_disc_int; 4516d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = max_disc_tu; 4517b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set discoverable interval: min=%d max=%d max_tu=%d", 4518b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt min_disc_int, max_disc_int, max_disc_tu); 4519d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4520d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 4521d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 4522b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4523b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4524b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_dbg(struct p2p_data *p2p, const char *fmt, ...) 4525b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 4526b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 4527b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 4528b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4529b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 4530b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 4531b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4532b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 4533b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 4534b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4535b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 4536b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_DEBUG, buf); 4537b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 4538b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4539b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4540b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_info(struct p2p_data *p2p, const char *fmt, ...) 4541b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 4542b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 4543b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 4544b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4545b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 4546b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 4547b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4548b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 4549b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 4550b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4551b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 4552b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_INFO, buf); 4553b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 4554b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4555b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4556b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_err(struct p2p_data *p2p, const char *fmt, ...) 4557b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 4558b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 4559b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 4560b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4561b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 4562b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 4563b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4564b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 4565b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 4566b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4567b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 4568b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_ERROR, buf); 4569b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 4570cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4571cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4572d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtvoid p2p_loop_on_known_peers(struct p2p_data *p2p, 4573d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt void (*peer_callback)(struct p2p_peer_info *peer, 4574d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt void *user_data), 4575d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt void *user_data) 4576d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{ 4577d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt struct p2p_device *dev, *n; 4578d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 4579d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 4580d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt peer_callback(&dev->info, user_data); 4581d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt } 4582d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt} 4583d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 4584d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 4585cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC 4586cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4587cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic struct wpabuf * p2p_build_nfc_handover(struct p2p_data *p2p, 4588cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int client_freq, 4589cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *go_dev_addr, 4590cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 4591cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4592cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *buf; 4593cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 op_class, channel; 4594cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt enum p2p_role_indication role = P2P_DEVICE_NOT_IN_GROUP; 4595cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4596cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt buf = wpabuf_alloc(1000); 4597cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (buf == NULL) 4598cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 4599cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4600cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt op_class = p2p->cfg->reg_class; 4601cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt channel = p2p->cfg->channel; 4602cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4603cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 4604cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 4605cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 4606cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4607cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p->num_groups > 0) { 46087832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt int freq = p2p_group_get_freq(p2p->groups[0]); 4609cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt role = P2P_GO_IN_A_GROUP; 46107832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_class, &channel) < 0) { 46117832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt p2p_dbg(p2p, 46127832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt "Unknown GO operating frequency %d MHz for NFC handover", 46137832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt freq); 46147832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt wpabuf_free(buf); 46157832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt return NULL; 46167832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt } 4617cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (client_freq > 0) { 4618cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt role = P2P_CLIENT_IN_A_GROUP; 46197832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (p2p_freq_to_channel(client_freq, &op_class, &channel) < 0) { 46207832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt p2p_dbg(p2p, 46217832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt "Unknown client operating frequency %d MHz for NFC handover", 46227832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt client_freq); 46237832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt wpabuf_free(buf); 46247832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt return NULL; 46257832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt } 4626cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4627cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4628cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_oob_go_neg_channel(buf, p2p->cfg->country, op_class, 4629cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt channel, role); 4630cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4631cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p->num_groups > 0) { 4632cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt /* Limit number of clients to avoid very long message */ 4633cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_group_info(p2p->groups[0], buf, 5); 4634cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_group_buf_add_id(p2p->groups[0], buf); 4635cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (client_freq > 0 && 4636cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt go_dev_addr && !is_zero_ether_addr(go_dev_addr) && 4637cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid && ssid_len > 0) { 4638cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt /* 4639cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt * Add the optional P2P Group ID to indicate in which group this 4640cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt * device is a P2P Client. 4641cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt */ 4642cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_group_id(buf, go_dev_addr, ssid, ssid_len); 4643cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4644cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4645cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return buf; 4646cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4647cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4648cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4649cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * p2p_build_nfc_handover_req(struct p2p_data *p2p, 4650cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int client_freq, 4651cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *go_dev_addr, 4652cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 4653cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4654cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return p2p_build_nfc_handover(p2p, client_freq, go_dev_addr, ssid, 4655cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid_len); 4656cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4657cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4658cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4659cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * p2p_build_nfc_handover_sel(struct p2p_data *p2p, 4660cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int client_freq, 4661cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *go_dev_addr, 4662cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 4663cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4664cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return p2p_build_nfc_handover(p2p, client_freq, go_dev_addr, ssid, 4665cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid_len); 4666cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4667cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4668cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4669cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint p2p_process_nfc_connection_handover(struct p2p_data *p2p, 4670cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_nfc_params *params) 4671cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4672cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_message msg; 4673cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_device *dev; 4674cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *p2p_dev_addr; 4675cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int freq; 4676cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt enum p2p_role_indication role; 4677cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4678cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = NO_ACTION; 4679cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4680cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p_parse_ies_separate(params->wsc_attr, params->wsc_len, 4681cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->p2p_attr, params->p2p_len, &msg)) { 4682cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Failed to parse WSC/P2P attributes from NFC"); 4683cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(&msg); 4684cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4685cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4686cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4687cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.p2p_device_addr) 4688cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 4689cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (msg.device_id) 4690cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dev_addr = msg.device_id; 4691cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else { 4692cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Ignore scan data without P2P Device Info or P2P Device Id"); 4693cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(&msg); 4694cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4695cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4696cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4697cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.oob_dev_password) { 4698cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(params->oob_dev_pw, msg.oob_dev_password, 4699cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg.oob_dev_password_len); 4700cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->oob_dev_pw_len = msg.oob_dev_password_len; 4701cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4702cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4703cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 4704cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dev == NULL) { 4705cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(&msg); 4706cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4707cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4708cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4709cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->peer = &dev->info; 4710cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4711cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_get_reltime(&dev->last_seen); 4712cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 4713cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, &msg); 4714cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4715cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!msg.oob_go_neg_channel) { 4716cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "OOB GO Negotiation Channel attribute not included"); 4717cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4718cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4719cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4720cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.oob_go_neg_channel[3] == 0 && 4721cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg.oob_go_neg_channel[4] == 0) 4722cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq = 0; 4723cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else 4724cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq = p2p_channel_to_freq(msg.oob_go_neg_channel[3], 4725cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg.oob_go_neg_channel[4]); 4726cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (freq < 0) { 4727cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Unknown peer OOB GO Neg channel"); 4728cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4729cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4730cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt role = msg.oob_go_neg_channel[5]; 4731cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4732cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (role == P2P_GO_IN_A_GROUP) { 4733cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Peer OOB GO operating channel: %u MHz", freq); 4734cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_freq = freq; 4735cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (role == P2P_CLIENT_IN_A_GROUP) { 4736cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Peer (client) OOB GO operating channel: %u MHz", 4737cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq); 4738cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_freq = freq; 4739cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else 4740cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Peer OOB GO Neg channel: %u MHz", freq); 4741cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_go_neg_freq = freq; 4742cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4743cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!params->sel && role != P2P_GO_IN_A_GROUP) { 4744cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, 4745cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->cfg->channel); 4746cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (freq < 0) { 4747cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Own listen channel not known"); 4748cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4749cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4750cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Use own Listen channel as OOB GO Neg channel: %u MHz", freq); 4751cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_go_neg_freq = freq; 4752cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4753cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4754cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.group_id) { 4755cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(params->go_dev_addr, msg.group_id, ETH_ALEN); 4756cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_ssid_len = msg.group_id_len - ETH_ALEN; 4757cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(params->go_ssid, msg.group_id + ETH_ALEN, 4758cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_ssid_len); 4759cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4760cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4761cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 4762cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 4763717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt p2p_parse_free(&msg); 4764cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 4765cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4766cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4767cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!(dev->flags & P2P_DEV_REPORTED)) { 4768cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, p2p_dev_addr, &dev->info, 4769cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 4770cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 4771cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4772717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt p2p_parse_free(&msg); 4773cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4774cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (role == P2P_GO_IN_A_GROUP && p2p->num_groups > 0) 4775cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = BOTH_GO; 4776cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (role == P2P_GO_IN_A_GROUP) 4777cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = JOIN_GROUP; 4778cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (role == P2P_CLIENT_IN_A_GROUP) { 4779cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 4780cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = PEER_CLIENT; 4781cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (p2p->num_groups > 0) 4782cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = AUTH_JOIN; 4783cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (params->sel) 4784cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = INIT_GO_NEG; 4785cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else 4786cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = RESP_GO_NEG; 4787cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4788cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 4789cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4790cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4791cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4792cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtvoid p2p_set_authorized_oob_dev_pw_id(struct p2p_data *p2p, u16 dev_pw_id, 4793cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int go_intent, 4794cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *own_interface_addr) 4795cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4796cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4797cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->authorized_oob_dev_pw_id = dev_pw_id; 4798cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dev_pw_id == 0) { 4799cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "NFC OOB Password unauthorized for static handover"); 4800cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return; 4801cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4802cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4803cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "NFC OOB Password (id=%u) authorized for static handover", 4804cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev_pw_id); 4805cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4806cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->go_intent = go_intent; 4807cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 4808cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4809cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4810cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */ 48112271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 48122271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 48132271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidtint p2p_set_passphrase_len(struct p2p_data *p2p, unsigned int len) 48142271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt{ 48152271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (len < 8 || len > 63) 48162271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt return -1; 48172271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p->cfg->passphrase_len = len; 48182271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt return 0; 48192271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt} 48202e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 48212e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 48222e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidtvoid p2p_set_vendor_elems(struct p2p_data *p2p, struct wpabuf **vendor_elem) 48232e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt{ 48242e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem = vendor_elem; 48252e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt} 4826