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" 139c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt#include "common/defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 162e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt#include "common/wpa_ctrl.h" 17216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#include "crypto/sha256.h" 18216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#include "crypto/crypto.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx); 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev); 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq); 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len); 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx); 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_scan recovery timeout 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Many drivers are using 30 second timeout on scan results. Allow a bit larger 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * timeout for this to avoid hitting P2P timeout unnecessarily. 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_SCAN_TIMEOUT 35 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entries will be removed 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 482093d0658d2f0f8b5a98df7accc97fff3b2bb7d5Dmitry Shmidt#ifndef P2P_PEER_EXPIRATION_AGE 492093d0658d2f0f8b5a98df7accc97fff3b2bb7d5Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 60 501846323989242844f0e857458a8939fa5836429cDmitry Shmidt#endif /* P2P_PEER_EXPIRATION_AGE */ 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid p2p_expire_peers(struct p2p_data *p2p) 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *n; 56fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now; 57c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t i; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec) 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 63c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 649e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt if (dev == p2p->go_neg_peer) { 659e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt /* 669e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * GO Negotiation is in progress with the peer, so 679e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * don't expire the peer entry until GO Negotiation 689e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * fails or times out. 699e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt */ 709e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt continue; 719e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt } 729e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt 73c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->cfg->go_connected && 74c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->cfg->go_connected(p2p->cfg->cb_ctx, 75c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt dev->info.p2p_device_addr)) { 76c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 77c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * We are connected as a client to a group in which the 78c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * peer is the GO, so do not expire the peer entry. 79c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 80fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 81c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 82c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 83c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 84c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 85c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p_group_is_client_connected( 86c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->groups[i], dev->info.p2p_device_addr)) 87c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt break; 88c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 89c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (i < p2p->num_groups) { 90c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 91c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * The peer is connected as a client in a group where 92c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * we are the GO, so do not expire the peer entry. 93c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 94fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 95c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 96c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 97c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 98b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Expiring old peer entry " MACSTR, 99b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_state_txt(int state) 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SEARCH"; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT"; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT_LISTEN"; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "GO_NEG"; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "LISTEN_ONLY"; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_CONNECT"; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_IDLE"; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SD_DURING_FIND"; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PROVISIONING"; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PD_DURING_FIND"; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE"; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE_LISTEN"; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "?"; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 141b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidtconst char * p2p_get_state_txt(struct p2p_data *p2p) 142b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt{ 143b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return p2p_state_txt(p2p->state); 144b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt} 145b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 146b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 147216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstruct p2ps_advertisement * p2p_get_p2ps_adv_list(struct p2p_data *p2p) 148216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 149216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return p2p ? p2p->p2ps_adv_list : NULL; 150216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 151216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 152216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 153216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtvoid p2p_set_intended_addr(struct p2p_data *p2p, const u8 *intended_addr) 154216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 155216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p && intended_addr) 156216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(p2p->intended_addr, intended_addr, ETH_ALEN); 157216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 158216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 159216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!addr || !p2p) 1651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return dev->wps_prov_info; 1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!addr || !p2p) 1801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 1811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_state(struct p2p_data *p2p, int new_state) 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 190b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "State %s -> %s", 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), p2p_state_txt(new_state)); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->state = new_state; 19343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 19443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (new_state == P2P_IDLE && p2p->pending_channel) { 19543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p_dbg(p2p, "Apply change in listen channel"); 19643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->reg_class = p2p->pending_reg_class; 19743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->channel = p2p->pending_channel; 19843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_reg_class = 0; 19943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_channel = 0; 20043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec) 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 206b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set timeout (state=%s): %u.%06u sec", 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), sec, usec); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_clear_timeout(struct p2p_data *p2p) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 215b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Clear timeout (state=%s)", p2p_state_txt(p2p->state)); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid p2p_go_neg_failed(struct p2p_data *p2p, int status) 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 2236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct p2p_device *peer = p2p->go_neg_peer; 2246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!peer) 2266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 2276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eloop_cancel_timeout(p2p_go_neg_wait_timeout, p2p, NULL); 2296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (p2p->state != P2P_SEARCH) { 2306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 2316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Clear timeouts related to GO Negotiation if no new p2p_find 2326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * has been started. 2336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 2346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_clear_timeout(p2p); 2356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 2368c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 2376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 2396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt peer->wps_method = WPS_NOT_READY; 2406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt peer->oob_pw_id = 0; 2416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(peer->go_neg_conf); 2426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt peer->go_neg_conf = NULL; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.status = status; 2476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN); 2486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 253d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc) 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r, tu; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 259b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting short listen state (state=%s)", 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2623c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt if (p2p->pending_listen_freq) { 2633c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt /* We have a pending p2p_listen request */ 2643c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p_dbg(p2p, "p2p_listen command pending already"); 2653c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt return; 2663c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt } 2673c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 2684b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 270b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 274661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random((u8 *) &r, sizeof(r)) < 0) 275661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt r = 0; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) + 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int) * 100; 278d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu) 279d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->max_disc_tu; 280d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!dev_disc && tu < 100) 281d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = 100; /* Need to wait in non-device discovery use cases */ 282d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen) 283d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->cfg->max_listen * 1000 / 1024; 284d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 285d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (tu == 0) { 286b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip listen state since duration was 0 TU"); 287d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_set_timeout(p2p, 0, 0); 288d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 289d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 291a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p, NULL, 0); 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2953c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_freq = freq; 2963c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_sec = 0; 2973c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_usec = 1024 * tu; 2983c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000, 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies) < 0) { 301b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start listen mode"); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen(struct p2p_data *p2p, unsigned int timeout) 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 313b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Going to listen(only) state"); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3153c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt if (p2p->pending_listen_freq) { 3163c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt /* We have a pending p2p_listen request */ 3173c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p_dbg(p2p, "p2p_listen command pending already"); 3183c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt return -1; 3193c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt } 3203c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 3214b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 323b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = timeout / 1000; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = (timeout % 1000) * 1000; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 33104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) { 332b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - connect is already pending - skip listen"); 3331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 3341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 335b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - delay start of listen state"); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 340a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p, NULL, 0); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3443c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_freq = freq; 3453c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { 347b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start listen mode"); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_LISTEN_ONLY); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_clear_reported(struct p2p_data *p2p) 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_REPORTED; 3656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dev->sd_reqs = 0; 3666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device - Fetch a peer entry 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr) 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0) 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Interface Address of the peer 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0) 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_create_device - Create a peer entry 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL on failure 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If there is already an entry for the peer, it will be returned instead of 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * creating a new one. 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_device * p2p_create_device(struct p2p_data *p2p, 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *oldest = NULL; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count = 0; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oldest == NULL || 427fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_reltime_before(&dev->last_seen, &oldest->last_seen)) 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldest = dev; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count + 1 > p2p->cfg->max_peers && oldest) { 431b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Remove oldest peer entry to make room for a new peer"); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&oldest->list); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, oldest); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = os_zalloc(sizeof(*dev)); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&p2p->devices, &dev->list); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_client_info(struct p2p_device *dev, 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli) 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 449d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p_copy_filter_devname(dev->info.device_name, 450d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(dev->info.device_name), 451d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cli->dev_name, cli->dev_name_len); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab = cli->dev_capab; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.config_methods = cli->config_methods; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_interface_addr, int freq, 463a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt const u8 *gi, size_t gi_len, 464a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt struct os_reltime *rx_time) 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t c; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Clear old data for this group; if the devices are still in the 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group, the information will be restored in the loop following this. 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(dev->member_in_go_iface, go_interface_addr, 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_iface, 0, ETH_ALEN); 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_dev, 0, ETH_ALEN); 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (c = 0; c < info.num_clients; c++) { 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli = &info.client[c]; 4901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr, 4911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ETH_ALEN) == 0) 4921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; /* ignore our own entry */ 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, cli->p2p_device_addr); 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY | 49604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_PROBE_REQ_ONLY)) { 49704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 49804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Update information since we have not 49904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * received this directly from the client. 50004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 50204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 50304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 50404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Need to update P2P Client Discoverability 50504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * flag since it is valid only in P2P Group 50604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Info attribute. 50704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 50804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= 50904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 51004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= 51104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cli->dev_capab & 51204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 51304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, cli->p2p_device_addr); 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq = freq; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.p2p_device_addr, 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &dev->info, 1); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, cli->p2p_interface_addr, 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 532a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_reltime)); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_iface, go_interface_addr, 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 536a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt dev->flags |= P2P_DEV_LAST_SEEN_AS_GROUP_CLIENT; 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 543b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, 544b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt int probe_req, const struct p2p_message *msg) 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, msg->device_name, 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.device_name)); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->manufacturer && 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len < sizeof(dev->info.manufacturer)) { 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.manufacturer, 0, 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.manufacturer)); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.manufacturer, msg->manufacturer, 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_name && 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len < sizeof(dev->info.model_name)) { 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_name, 0, 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_name)); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_name, msg->model_name, 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_number && 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len < sizeof(dev->info.model_number)) { 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_number, 0, 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_number)); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_number, msg->model_number, 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len); 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->serial_number && 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len < sizeof(dev->info.serial_number)) { 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.serial_number, 0, 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.serial_number)); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.serial_number, msg->serial_number, 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len); 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->pri_dev_type) 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type, 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg->wps_pri_dev_type) 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type, 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_sec_dev_type_list) { 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list, 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len); 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->capability) { 59704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 59804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * P2P Client Discoverability bit is reserved in all frames 59904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * that use this function, so do not change its value here. 60004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 60104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 60204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= msg->capability[0] & 60304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab = msg->capability[1]; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->ext_listen_timing) { 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval = 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing + 2); 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 61204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!probe_req) { 614f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt u16 new_config_methods; 615f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt new_config_methods = msg->config_methods ? 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_methods : msg->wps_config_methods; 617f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (new_config_methods && 618f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods != new_config_methods) { 619b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update peer " MACSTR 620b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " config_methods 0x%x -> 0x%x", 621b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 622b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt dev->info.config_methods, 623b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt new_config_methods); 624f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods = new_config_methods; 625f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6302e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidtstatic void p2p_update_peer_vendor_elems(struct p2p_device *dev, const u8 *ies, 6312e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt size_t ies_len) 6322e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt{ 6332e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt const u8 *pos, *end; 6342e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt u8 id, len; 6352e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6362e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_free(dev->info.vendor_elems); 6372e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt dev->info.vendor_elems = NULL; 6382e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6392e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt end = ies + ies_len; 6402e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 641d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (pos = ies; end - pos > 1; pos += len) { 6422e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt id = *pos++; 6432e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt len = *pos++; 6442e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 645d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (len > end - pos) 6462e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt break; 6472e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6482e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (id != WLAN_EID_VENDOR_SPECIFIC || len < 3) 6492e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt continue; 6502e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6512e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (len >= 4) { 6522e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt u32 type = WPA_GET_BE32(pos); 6532e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6542e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (type == WPA_IE_VENDOR_TYPE || 6552e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt type == WMM_IE_VENDOR_TYPE || 6562e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt type == WPS_IE_VENDOR_TYPE || 6572e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt type == P2P_IE_VENDOR_TYPE || 6582e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt type == WFD_IE_VENDOR_TYPE) 6592e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt continue; 6602e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt } 6612e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6622e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt /* Unknown vendor element - make raw IE data available */ 6632e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (wpabuf_resize(&dev->info.vendor_elems, 2 + len) < 0) 6642e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt break; 6652e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_data(dev->info.vendor_elems, pos - 2, 2 + len); 6662e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt } 6672e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt} 6682e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6692e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int p2p_compare_wfd_info(struct p2p_device *dev, 6716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const struct p2p_message *msg) 6726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 6736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dev->info.wfd_subelems && msg->wfd_subelems) { 6746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dev->info.wfd_subelems->used != msg->wfd_subelems->used) 6756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 1; 6766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return os_memcmp(dev->info.wfd_subelems->buf, 6786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt msg->wfd_subelems->buf, 6796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dev->info.wfd_subelems->used); 6806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 6816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dev->info.wfd_subelems || msg->wfd_subelems) 6826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 1; 6836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 6856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 6866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 68904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * p2p_add_device - Add peer entries based on scan results or P2P frames 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Source address of Beacon or Probe Response frame (may be either 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Address or P2P Interface Address) 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @level: Signal level (signal strength of the received frame from the peer) 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency on which the Beacon or Probe Response frame was received 695f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @rx_time: Time when the result was received 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies: IEs from the Beacon or Probe Response frame 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies_len: Length of ies buffer in octets 69804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @scan_res: Whether this was based on scan results 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If the scan result is for a GO, the clients in the group will also be added 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the peer table. This function can also be used with some other frames 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * like Provision Discovery Request that contains P2P Capability and P2P Device 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Info attributes. 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 706a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtint p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, 707fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime *rx_time, int level, const u8 *ies, 708a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len, int scan_res) 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *p2p_dev_addr; 7136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int wfd_changed; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 715fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime time_now; 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ies, ies_len, &msg)) { 719b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P IE for a device entry"); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg.device_id) 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.device_id; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 729b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore scan data without P2P Device Info or P2P Device Id"); 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(p2p->peer_filter) && 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) { 736b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not add peer filter for " MACSTR 737b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " due to peer filter", MAC2STR(p2p_dev_addr)); 738a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 747a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 748f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (rx_time == NULL) { 749fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&time_now); 750f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt rx_time = &time_now; 751f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 752a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 753a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 754a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Update the device entry only if the new peer 755a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * entry is newer than the one previously stored, or if 756a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * the device was previously seen as a P2P Client in a group 757a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * and the new entry isn't older than a threshold. 758a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 759f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->last_seen.sec > 0 && 760a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_reltime_before(rx_time, &dev->last_seen) && 761a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt (!(dev->flags & P2P_DEV_LAST_SEEN_AS_GROUP_CLIENT) || 762a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_reltime_expired(&dev->last_seen, rx_time, 763a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt P2P_DEV_GROUP_CLIENT_RESP_THRESHOLD))) { 764a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_dbg(p2p, 765a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt "Do not update peer entry based on old frame (rx_time=%u.%06u last_seen=%u.%06u flags=0x%x)", 766f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->sec, 767f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec, 768f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) dev->last_seen.sec, 769a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt (unsigned int) dev->last_seen.usec, 770a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt dev->flags); 771a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 772a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 773a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 774a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 775fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_reltime)); 776a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 777a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY | 778a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt P2P_DEV_LAST_SEEN_AS_GROUP_CLIENT); 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0) 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, addr, ETH_ALEN); 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid && 783fdb708a37d8f7f1483e3cd4e8ded974f53fedaceJouni Malinen msg.ssid[1] <= sizeof(dev->oper_ssid) && 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0)) { 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len = msg.ssid[1]; 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 791216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.adv_service_instance && msg.adv_service_instance_len) { 792216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpabuf_free(dev->info.p2ps_instance); 793216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->info.p2ps_instance = wpabuf_alloc_copy( 794216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.adv_service_instance, msg.adv_service_instance_len); 795216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 796216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 2412 && freq <= 2484 && msg.ds_params && 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.ds_params >= 1 && *msg.ds_params <= 14) { 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ds_freq; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.ds_params == 14) 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2484; 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2407 + *msg.ds_params * 5; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != ds_freq) { 805b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update Listen frequency based on DS Parameter Set IE: %d -> %d MHz", 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, ds_freq); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = ds_freq; 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 81104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (dev->listen_freq && dev->listen_freq != freq && scan_res) { 812b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update Listen frequency based on scan results (" 813b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " %d -> %d MHz (DS param %d)", 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->listen_freq, 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, msg.ds_params ? *msg.ds_params : -1); 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 81704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 81804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->listen_freq = freq; 81904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.group_info) 82004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->oper_freq = freq; 82104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 82275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.level = level; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 824b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, &msg); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_vendor_ext[i] == NULL) 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy( 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]); 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->info.wps_vendor_ext[i] == NULL) 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wfd_changed = p2p_compare_wfd_info(dev, &msg); 8416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 84261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 84361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 84461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 84561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 84661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 84704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 84804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq, 849a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt msg.group_info, msg.group_info_len, 850a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt rx_time); 85104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8552e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p_update_peer_vendor_elems(dev, ies, ies_len); 8562e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 857216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (dev->flags & P2P_DEV_REPORTED && !wfd_changed && 858216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (!msg.adv_service_instance || 859216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (dev->flags & P2P_DEV_P2PS_REPORTED))) 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 862b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer found with Listen frequency %d MHz (rx_time=%u.%06u)", 863b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq, (unsigned int) rx_time->sec, 864f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec); 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 866b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 870f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->info.config_methods == 0 && 871f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (freq == 2412 || freq == 2437 || freq == 2462)) { 872f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 873f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * If we have only seen a Beacon frame from a GO, we do not yet 874f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * know what WPS config methods it supports. Since some 875f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * applications use config_methods value from P2P-DEVICE-FOUND 876f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * events, postpone reporting this peer until we've fully 877f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * discovered its capabilities. 878f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * 879f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * At least for now, do this only if the peer was detected on 880f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * one of the social channels since that peer can be easily be 881f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * found again and there are no limitations of having to use 882f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * passive scan on this channels, so this can be done through 883f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Probe Response frame that includes the config_methods 884f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * information. 885f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 886b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report peer " MACSTR 887b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " with unknown config methods", MAC2STR(addr)); 888f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 889f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 890f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 895216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.adv_service_instance) 896216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->flags |= P2P_DEV_P2PS_REPORTED; 897216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 906497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt if (p2p->go_neg_peer == dev) { 9071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 9081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * If GO Negotiation is in progress, report that it has failed. 9091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 9106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_go_neg_failed(p2p, -1); 911497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt } 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == dev) 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == dev) 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_client_disc_go == dev) 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_go = NULL; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 919c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt /* dev_lost() device, but only if it was previously dev_found() */ 920c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (dev->flags & P2P_DEV_REPORTED_ONCE) 921c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt p2p->cfg->dev_lost(p2p->cfg->cb_ctx, 922c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt dev->info.p2p_device_addr); 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 92961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 9302e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_free(dev->info.vendor_elems); 931413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_free(dev->go_neg_conf); 932216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpabuf_free(dev->info.p2ps_instance); 93361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dev); 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_get_next_prog_freq(struct p2p_data *p2p) 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *c; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *cla; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t cl, ch; 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 reg_class; 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel; 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = &p2p->cfg->channels; 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cl = 0; cl < c->reg_classes; cl++) { 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla = &c->reg_class[cl]; 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->reg_class != p2p->last_prog_scan_class) 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = 0; ch < cla->channels; ch++) { 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->channel[ch] == p2p->last_prog_scan_chan) { 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found) 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start from beginning */ 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[0].reg_class; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[0].channel[0]; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Pick the next channel */ 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch++; 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ch == cla->channels) { 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl++; 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cl == c->reg_classes) 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl = 0; 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch = 0; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[cl].reg_class; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[cl].channel[ch]; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9804b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(reg_class, channel); 981b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Next progressive search channel: reg_class %u channel %u -> %d MHz", 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class, channel, freq); 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_class = reg_class; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_chan = channel; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2412 || freq == 2437 || freq == 2462) 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* No need to add social channels */ 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return freq; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_search(struct p2p_data *p2p) 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq = 0; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_scan_type type; 99604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 pw_id = DEV_PW_DEFAULT; 99761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int res; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 1000b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver is still in Listen state - wait for it to end before continuing"); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 100504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->find_type == P2P_FIND_PROGRESSIVE && 100604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (freq = p2p_get_next_prog_freq(p2p)) > 0) { 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL_PLUS_ONE; 1008b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting search (+ freq %u)", freq); 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL; 1011b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting search"); 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 101461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq, 101561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types, 101661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->find_dev_id, pw_id); 101761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0) { 10186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_dbg(p2p, "Scan request schedule failed"); 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx) 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 1027b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Find timeout -> stop"); 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid p2p_notify_scan_trigger_status(struct p2p_data *p2p, int status) 10336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 10346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (status != 0) { 10356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_dbg(p2p, "Scan request failed"); 10366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* Do continue find even for the first p2p_find_scan */ 10376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_continue_find(p2p); 10386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } else { 10396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_dbg(p2p, "Running p2p_scan"); 10406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p->p2p_scan_running = 1; 10416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 10426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 10436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p, NULL); 10446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 10466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_run_after_scan(struct p2p_data *p2p) 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_after_scan op; 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 10548da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 1; 1055b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Action frame at p2p_scan completion"); 10561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->cfg->send_action(p2p->cfg->cb_ctx, 10571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->freq, 10581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->dst, 10591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->src, 10601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->bssid, 10611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (u8 *) (p2p->after_scan_tx + 1), 10621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->len, 10631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->wait_time); 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op = p2p->start_after_scan; 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (op) { 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_NOTHING: 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_LISTEN: 1075b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start previously requested Listen state"); 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen(p2p, p2p->pending_listen_sec * 1000 + 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec / 1000); 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_CONNECT: 1080b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start previously requested connect with " MACSTR, 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->after_scan_peer)); 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, p2p->after_scan_peer); 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 1084b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer not known anymore"); 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, dev); 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx) 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int running; 1099b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan timeout (running=%d)", p2p->p2p_scan_running); 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt running = p2p->p2p_scan_running; 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we recover from missed scan results callback */ 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (running) 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_run_after_scan(p2p); 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_free_req_dev_types(struct p2p_data *p2p) 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = 0; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->req_dev_types); 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = NULL; 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1117216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int p2ps_gen_hash(struct p2p_data *p2p, const char *str, u8 *hash) 1118216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 1119216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 buf[SHA256_MAC_LEN]; 1120216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt char str_buf[256]; 1121216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *adv_array; 1122216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t i, adv_len; 1123216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1124216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!str || !hash) 1125216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 1126216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1127216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!str[0]) { 1128216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(hash, p2p->wild_card_hash, P2PS_HASH_LEN); 1129216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 1; 1130216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1131216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1132216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_array = (u8 *) str_buf; 1133216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_len = os_strlen(str); 1134a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (adv_len >= sizeof(str_buf)) 1135a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return 0; 1136216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1137d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (i = 0; i < adv_len; i++) { 1138216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (str[i] >= 'A' && str[i] <= 'Z') 1139216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt str_buf[i] = str[i] - 'A' + 'a'; 1140216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 1141216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt str_buf[i] = str[i]; 1142216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1143216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1144216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (sha256_vector(1, &adv_array, &adv_len, buf)) 1145216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 1146216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1147216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(hash, buf, P2PS_HASH_LEN); 1148216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 1; 1149216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 1150216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1151216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_find(struct p2p_data *p2p, unsigned int timeout, 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 1154c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types, 1155216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *dev_id, unsigned int search_delay, 1156203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt u8 seek_count, const char **seek, int freq) 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1160b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting find (type=%d)", type); 1161fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&p2p->find_start); 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 1163b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan is already running"); 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req_dev_types && num_req_dev_types) { 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = os_malloc(num_req_dev_types * 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->req_dev_types == NULL) 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->req_dev_types, req_dev_types, 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types * WPS_DEV_TYPE_LEN); 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = num_req_dev_types; 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1177c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) { 1178c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN); 1179c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = p2p->find_dev_id_buf; 1180c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else 1181c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = NULL; 1182c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1183216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (seek_count == 0 || !seek) { 1184216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Not an ASP search */ 1185216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_seek = 0; 1186216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (seek_count == 1 && seek && (!seek[0] || !seek[0][0])) { 1187216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* 1188216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * An empty seek string means no hash values, but still an ASP 1189216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * search. 1190216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt */ 1191a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_dbg(p2p, "ASP search"); 1192216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_seek_count = 0; 1193216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_seek = 1; 1194216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (seek && seek_count <= P2P_MAX_QUERY_HASH) { 1195216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 buf[P2PS_HASH_LEN]; 1196a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt int i, count = 0; 1197216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1198216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (i = 0; i < seek_count; i++) { 1199216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2ps_gen_hash(p2p, seek[i], buf)) 1200216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt continue; 1201216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1202a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_dbg(p2p, "Seek service %s hash " MACSTR, 1203a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt seek[i], MAC2STR(buf)); 1204a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_memcpy(&p2p->p2ps_seek_hash[count * P2PS_HASH_LEN], 1205a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt buf, P2PS_HASH_LEN); 1206a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt count++; 1207216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1208a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt 1209a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p->p2ps_seek_count = count; 1210216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_seek = 1; 1211216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 1212216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_seek_count = 0; 1213216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_seek = 1; 1214216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1215216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1216216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Special case to perform wildcard search */ 1217216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_seek_count == 0 && p2p->p2ps_seek) { 1218216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_seek_count = 1; 1219a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_memcpy(&p2p->p2ps_seek_hash, p2p->wild_card_hash, 1220a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt P2PS_HASH_LEN); 1221216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1222216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 1225de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (p2p->pending_listen_freq) { 1226de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt p2p_dbg(p2p, "Clear pending_listen_freq for p2p_find"); 1227de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt p2p->pending_listen_freq = 0; 1228de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt } 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->find_type = type; 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_clear_reported(p2p); 1232de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt os_memset(p2p->sd_query_no_ack, 0, ETH_ALEN); 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 123461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay = search_delay; 123561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 12371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->last_p2p_find_timeout = timeout; 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout) 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, p2p_find_timeout, 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_START_WITH_FULL: 1243203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (freq > 0) { 1244203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* 1245203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * Start with the specified channel and then move to 1246203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * social channels only scans. 1247203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt */ 1248203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, 1249203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt P2P_SCAN_SPECIFIC, freq, 1250203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt p2p->num_req_dev_types, 1251203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt p2p->req_dev_types, dev_id, 1252203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt DEV_PW_DEFAULT); 1253203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt break; 1254203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 1255203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* fall through */ 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_PROGRESSIVE: 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 125904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 126004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_ONLY_SOCIAL: 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0, 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 126504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 126604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (res != 0 && p2p->p2p_scan_running) { 1273fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt p2p_dbg(p2p, "Failed to start p2p_scan - another p2p_scan was already running"); 1274fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt /* wait for the previous p2p_scan to complete */ 127596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt res = 0; /* do not report failure */ 12766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } else if (res != 0) { 1277b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start p2p_scan"); 12781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 12791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find_for_freq(struct p2p_data *p2p, int freq) 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1288b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Stopping find"); 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 1291216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->state == P2P_SEARCH || p2p->state == P2P_SD_DURING_FIND) 1292b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->find_stopped(p2p->cfg->cb_ctx); 1293216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1294216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_seek_count = 0; 1295216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 12998c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer) 13008c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 130404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_listen_for_freq(p2p, freq); 13057f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt p2p->send_action_in_progress = 0; 130604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 130704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 130804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 130904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq) 131004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) { 1312b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip stop_listen since we are on correct channel for response"); 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 131504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->in_listen) { 131604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->in_listen = 0; 131704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_clear_timeout(p2p); 131804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 13191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->drv_in_listen) { 13201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 13211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * The driver may not deliver callback to p2p_listen_end() 13221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * when the operation gets canceled, so clear the internal 13231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * variable that is tracking driver state. 13241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 1325b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Clear drv_in_listen (%d)", p2p->drv_in_listen); 13261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->drv_in_listen = 0; 13271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1332391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid p2p_stop_listen(struct p2p_data *p2p) 1333391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 1334391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p->state != P2P_LISTEN_ONLY) { 1335391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dbg(p2p, "Skip stop_listen since not in listen_only state."); 1336391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 1337391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 1338391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1339391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_stop_listen_for_freq(p2p, 0); 1340391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 1341391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 1342391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1343391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find(struct p2p_data *p2p) 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13463c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_freq = 0; 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find_for_freq(p2p, 0); 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1351a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int p2p_prepare_channel_pref(struct p2p_data *p2p, 1352a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int force_freq, 135368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt unsigned int pref_freq, int go) 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1355a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1356a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int freq = force_freq ? force_freq : pref_freq; 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 135868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Prepare channel pref - force_freq=%u pref_freq=%u go=%d", 135968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt force_freq, pref_freq, go); 13604b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_class, &op_channel) < 0) { 1361b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported frequency %u MHz", freq); 1362a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1363a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1364a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 136568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (!p2p_channels_includes(&p2p->cfg->channels, op_class, op_channel) && 136668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt (go || !p2p_channels_includes(&p2p->cfg->cli_channels, op_class, 136768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel))) { 1368b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Frequency %u MHz (oper_class %u channel %u) not allowed for P2P", 1369b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq, op_class, op_channel); 1370a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1371a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1372a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1373a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1374a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1376a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) { 1377a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_classes = 1; 1378a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channels = 1; 1379a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; 1380a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channel[0] = p2p->op_channel; 1381a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct p2p_channels)); 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1385a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1386a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 1387a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1388a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1389a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1390a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void p2p_prepare_channel_best(struct p2p_data *p2p) 1391a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 1392a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1393a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt const int op_classes_5ghz[] = { 124, 125, 115, 0 }; 1394a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt const int op_classes_ht40[] = { 126, 127, 116, 117, 0 }; 1395e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt const int op_classes_vht[] = { 128, 0 }; 1396a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1397b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Prepare channel best"); 1398b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1399a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 && 1400a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_overall) && 14014b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_overall, &op_class, &op_channel) 14024b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt == 0) { 1403b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best overall channel as operating channel preference"); 1404a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1405a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1406a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 && 1407a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_5) && 14084b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_5, &op_class, &op_channel) 14094b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt == 0) { 1410b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best 5 GHz channel as operating channel preference"); 1411a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1412a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1413a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_24 > 0 && 1414a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_24) && 14154b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_24, &op_class, 14164b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt &op_channel) == 0) { 1417b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best 2.4 GHz channel as operating channel preference"); 1418a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1419a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1420b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt } else if (p2p->cfg->num_pref_chan > 0 && 1421b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_channels_includes(&p2p->cfg->channels, 1422b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->cfg->pref_chan[0].op_class, 1423b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->cfg->pref_chan[0].chan)) { 1424b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Select first pref_chan entry as operating channel preference"); 1425b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->op_reg_class = p2p->cfg->pref_chan[0].op_class; 1426b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->op_channel = p2p->cfg->pref_chan[0].chan; 1427e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht, 1428e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &p2p->op_reg_class, &p2p->op_channel) == 1429e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 0) { 1430e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p_dbg(p2p, "Select possible VHT channel (op_class %u channel %u) as operating channel preference", 1431e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1432e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_ht40, 1433e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &p2p->op_reg_class, &p2p->op_channel) == 1434e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 0) { 1435e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p_dbg(p2p, "Select possible HT40 channel (op_class %u channel %u) as operating channel preference", 1436e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1437e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_5ghz, 1438e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &p2p->op_reg_class, &p2p->op_channel) == 1439e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 0) { 1440e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p_dbg(p2p, "Select possible 5 GHz channel (op_class %u channel %u) as operating channel preference", 1441e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1442d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt } else if (p2p_channels_includes(&p2p->cfg->channels, 1443d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->cfg->op_reg_class, 1444d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->cfg->op_channel)) { 1445b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Select pre-configured channel as operating channel preference"); 1446a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = p2p->cfg->op_reg_class; 1447a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = p2p->cfg->op_channel; 1448d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt } else if (p2p_channel_random_social(&p2p->cfg->channels, 1449d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_reg_class, 1450d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_channel) == 0) { 1451661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p_dbg(p2p, "Select random available social channel (op_class %u channel %u) as operating channel preference", 1452661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1453d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt } else { 1454d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt /* Select any random available channel from the first available 1455d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt * operating class */ 1456d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p_channel_select(&p2p->cfg->channels, NULL, 1457d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_reg_class, 1458d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_channel); 1459d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p_dbg(p2p, "Select random available channel %d from operating class %d as operating channel preference", 1460d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->op_channel, p2p->op_reg_class); 1461a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1462a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1463a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 1464a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(struct p2p_channels)); 1465a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1466a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1467a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1468a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1469d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * p2p_prepare_channel - Select operating channel for GO Negotiation or P2PS PD 1470a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @p2p: P2P module context from p2p_init() 1471a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @dev: Selected peer device 1472a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @force_freq: Forced frequency in MHz or 0 if not forced 1473a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @pref_freq: Preferred frequency in MHz or 0 if no preference 147468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @go: Whether the local end will be forced to be GO 1475a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 on success, -1 on failure (channel not supported for P2P) 1476a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1477a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is used to do initial operating channel selection for GO 1478d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Negotiation prior to having received peer information or for P2PS PD 1479d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * signalling. The selected channel may be further optimized in 1480d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * p2p_reselect_channel() once the peer information is available. 1481a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 14827a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtint p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev, 148368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt unsigned int force_freq, unsigned int pref_freq, int go) 1484a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 148568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Prepare channel - force_freq=%u pref_freq=%u go=%d", 148668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt force_freq, pref_freq, go); 1487a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq || pref_freq) { 148868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_prepare_channel_pref(p2p, force_freq, pref_freq, go) < 148968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 0) 1490a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1491a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 1492a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_prepare_channel_best(p2p); 1493a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 149468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "prepared channels", &p2p->channels); 149568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (go) 149668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_remove_freqs(&p2p->channels, &p2p->no_go_freq); 149768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt else if (!force_freq) 14986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_channels_union_inplace(&p2p->channels, 14996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt &p2p->cfg->cli_channels); 150068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "after go/cli filter/add", &p2p->channels); 150168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 1502b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Own preference for operation channel: Operating Class %u Channel %u%s", 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, p2p->op_channel, 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq ? " (forced)" : ""); 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1506a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) 1507a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags |= P2P_DEV_FORCE_FREQ; 1508a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else 1509a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags &= ~P2P_DEV_FORCE_FREQ; 1510a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_set_dev_persistent(struct p2p_device *dev, 15161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int persistent_group) 15171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 15181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (persistent_group) { 15191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 0: 15201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP | 15211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN); 15221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 15231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 1: 15241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP; 15251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN; 15261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 15271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 2: 15281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP | 15291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN; 15301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 15311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 15321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 15331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 15341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 153804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 153904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1540cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int pd_before_go_neg, unsigned int pref_freq, u16 oob_pw_id) 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1544b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 1546cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt " wps_method=%d persistent_group=%d pd_before_go_neg=%d " 1547cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "oob_pw_id=%u", 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1549cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_method, persistent_group, pd_before_go_neg, oob_pw_id); 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 1553b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to unknown P2P Device " MACSTR, 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 155868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq, 155968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt go_intent == 15) < 0) 1560a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1561a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 1565b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) { 1571b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with incomplete information", 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * First, try to connect directly. If the peer does not 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * acknowledge frames, assume it is sleeping and use device 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * discoverability via the GO at that point. 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 158504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 158604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 158704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 158804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 158904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 159004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 159104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 159204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 159704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pd_before_go_neg) 159804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG; 1599a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else { 160004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 1601a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 16029cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * Assign dialog token and tie breaker here to use the same 16039cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * values in each retry within the same GO Negotiation exchange. 1604a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 1605a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token++; 1606a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (dev->dialog_token == 0) 1607a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token = 1; 16089cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt dev->tie_breaker = p2p->next_tie_breaker; 16099cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt p2p->next_tie_breaker = !p2p->next_tie_breaker; 1610a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->connect_reqs = 0; 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 16141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We need to drop the pending frame to avoid issues with the 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new GO Negotiation, e.g., when the pending frame was from a 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previous attempt at starting a GO Negotiation. 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1627b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Dropped previous pending Action frame TX that was waiting for p2p_scan completion"); 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 1633cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_pw_id = oob_pw_id; 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 1637b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - delay connect send"); 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT; 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN); 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect_send(p2p, dev); 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 165104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 1652d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1653cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt unsigned int pref_freq, u16 oob_pw_id) 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1657b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 1659cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt " wps_method=%d persistent_group=%d oob_pw_id=%u", 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1661cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_method, persistent_group, oob_pw_id); 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 1665b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot authorize unknown P2P Device " MACSTR, 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 167068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq, go_intent == 167168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 15) < 0) 1672a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1673a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 167404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 167504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 167604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 167704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 167804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 167904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 168004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 168104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 168204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 16871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 1692cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_pw_id = oob_pw_id; 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, struct p2p_message *msg) 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1702fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1704b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, msg); 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->listen_channel) { 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 17084b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(msg->listen_channel[3], 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 1711b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown peer Listen channel: " 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c(0x%02x) reg_class=%u channel=%u", 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[0], 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[1], 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[2], 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1719b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update peer " MACSTR 1720b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " Listen channel: %u -> %u MHz", 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, freq); 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = freq; 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 172761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg->wfd_subelems) { 172861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 172961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems); 173061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 173161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 1734b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Completed device entry based on data from GO Negotiation Request"); 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1736b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Created device entry based on GO Neg Req: " 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' " 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d", 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab, dev->info.group_capab, 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name, dev->listen_freq); 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY; 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 1747b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len) 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2); 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2], 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len); 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len; 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1769216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->ssid_set) { 1770216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(params->ssid, p2p->ssid, p2p->ssid_len); 1771216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt params->ssid_len = p2p->ssid_len; 1772216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 1773216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_build_ssid(p2p, params->ssid, ¶ms->ssid_len); 1774216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1775216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->ssid_set = 0; 1776216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 17772271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p_random(params->passphrase, p2p->cfg->passphrase_len); 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go = peer->go_state == LOCAL_GO; 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels intersection; 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation with " MACSTR " completed (%s will be GO)", 1789b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(peer->info.p2p_device_addr), go ? "local end" : "peer"); 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.role_go = go; 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN); 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN); 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = peer->wps_method; 17961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { 17971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN) 17981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 2; 17991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 18001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 1; 18011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Setup AP mode for WPS provisioning */ 18054b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt res.freq = p2p_channel_to_freq(p2p->op_reg_class, 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel); 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 18092271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p_random(res.passphrase, p2p->cfg->passphrase_len); 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = peer->oper_freq; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ssid_len) { 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 181868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "own channels", &p2p->channels); 181968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "peer channels", &peer->channels); 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_channels_intersect(&p2p->channels, &peer->channels, 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &intersection); 182268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (go) { 182368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_remove_freqs(&intersection, &p2p->no_go_freq); 182468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "intersection after no-GO removal", 182568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt &intersection); 182668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 18276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 18286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_channels_to_freqs(&intersection, res.freq_list, 18296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt P2P_MAX_CHANNELS); 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout; 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 18341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->ssid_set = 0; 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->go_neg_req_sent = 0; 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->wps_method = WPS_NOT_READY; 1837cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt peer->oob_pw_id = 0; 1838413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_free(peer->go_neg_conf); 1839413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt peer->go_neg_conf = NULL; 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PROVISIONING); 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1849b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "RX P2P Public Action from " MACSTR, MAC2STR(sa)); 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len); 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_REQ: 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_RESP: 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_CONF: 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1); 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_REQ: 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_req(p2p, sa, data + 1, len - 1, 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_freq); 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_RESP: 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_REQ: 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_RESP: 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1); 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_REQ: 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_RESP: 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1); 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1885b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported P2P Public Action frame type %d", 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da, 18931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *sa, const u8 *bssid, const u8 *data, 18941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int freq) 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_VENDOR_SPECIFIC: 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 1903a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (len < 4) 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1905a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (WPA_GET_BE32(data) != P2P_IE_VENDOR_TYPE) 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt data += 4; 1909a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt len -= 4; 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1911a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt p2p_rx_p2p_action(p2p, sa, data, len, freq); 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_REQ: 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq); 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_RESP: 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq); 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_REQ: 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq); 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_RESP: 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq); 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u8 category, 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int freq) 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category == WLAN_ACTION_PUBLIC) { 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq); 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category != WLAN_ACTION_VENDOR_SPECIFIC) 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 4) 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1944a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (WPA_GET_BE32(data) != P2P_IE_VENDOR_TYPE) 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1946a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt data += 4; 1947a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt len -= 4; 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P action frame */ 1950b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "RX P2P Action from " MACSTR, MAC2STR(sa)); 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len); 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NOA: 1957b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - Notice of Absence"); 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_REQ: 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq); 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_RESP: 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1); 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_DISC_REQ: 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq); 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1970b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - unknown type %u", data[0]); 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx) 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1981661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (p2p->pending_listen_freq) { 1982661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p_dbg(p2p, "Clear pending_listen_freq for p2p_go_neg_start"); 1983661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p->pending_listen_freq = 0; 1984661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status = P2P_SC_SUCCESS; 1987661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* 1988661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * Set new timeout to make sure a previously set one does not expire 1989661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * too quickly while waiting for the GO Negotiation to complete. 1990661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt */ 1991661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_invite_start(void *eloop_ctx, void *timeout_ctx) 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == NULL) 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2001661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (p2p->pending_listen_freq) { 2002661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p_dbg(p2p, "Clear pending_listen_freq for p2p_invite_start"); 2003661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p->pending_listen_freq = 0; 2004661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 2006cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr, 2007cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->invite_dev_pw_id); 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL) 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* not a P2P probe */ 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0) { 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* The Probe Request is not part of P2P Device Discovery. It is 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not known whether the source address of the frame is the P2P 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Device Address or P2P Interface Address. Do not add a new 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer entry based on this frames. 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 20389c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt if (msg.listen_channel) { 20399c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt int freq; 20409c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt 20419c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt if (dev->country[0] == 0) 20429c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 20439c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt 20449c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt freq = p2p_channel_to_freq(msg.listen_channel[3], 20459c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt msg.listen_channel[4]); 20469c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt 20479c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt if (freq > 0 && dev->listen_freq != freq) { 20489c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt p2p_dbg(p2p, 20499c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt "Updated peer " MACSTR " Listen channel (Probe Request): %d -> %d MHz", 20509c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt MAC2STR(addr), dev->listen_freq, freq); 20519c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt dev->listen_freq = freq; 20529c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt } 20539c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt } 20549c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt 2055fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* already known */ 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2066fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PROBE_REQ_ONLY; 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.listen_channel) { 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 20714b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->listen_freq = p2p_channel_to_freq(msg.listen_channel[3], 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[4]); 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2075b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 1, &msg); 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 207761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 207861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 207961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 208061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 208161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2084b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Created device entry based on Probe Req: " MACSTR 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d", 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab, 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab, dev->info.device_name, 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq); 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message *msg) 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 2100fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; /* already known */ 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_info(p2p, addr, dev, msg); 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int dev_type_match(const u8 *dev_type, const u8 *req_dev_type) 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0) 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, 2) == 0 && 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE32(&req_dev_type[2]) == 0 && 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(&req_dev_type[6]) == 0) 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Category match with wildcard OUI/sub-category */ 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[], 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_req_dev_type) 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_req_dev_type; i++) { 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_match(dev_type, req_dev_type[i])) 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_match_dev_type - Match local device type with requested type 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs) 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 on match, 0 on mismatch 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to match the Requested Device Type attribute in 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS IE with the local device types for deciding whether to reply to a Probe 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Request frame. 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps) 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(wps, &attr)) 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* assume no Requested Device Type attributes */ 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.num_req_dev_type == 0) 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* no Requested Device Type attributes -> match */ 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type, 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Primary Device Type matches */ 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt for (i = 0; i < p2p->cfg->num_sec_dev_types; i++) { 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->sec_dev_type[i], 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.req_dev_type, 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 21676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 1; /* Own Secondary Device Type matches */ 21686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No matching device type found */ 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2175a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidtstruct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p, 2176a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt const u8 *query_hash, 2177a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt u8 query_count) 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 218104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int pw_id = -1; 218261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 218361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 218461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 218561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 218661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_probe_resp); 218761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21892e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]) 21902e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]); 21912e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 2192a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (query_count) 2193216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt extra += MAX_SVC_ADV_IE_LEN; 2194216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 219561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 219904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer) { 220004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Advertise immediate availability of WPS credential */ 220104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pw_id = p2p_wps_method_pw_id(p2p->go_neg_peer->wps_method); 220204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 220304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 220468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_build_wps_ie(p2p, buf, pw_id, 1) < 0) { 220568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Failed to build WPS IE for Probe Response"); 220668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpabuf_free(buf); 220768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NULL; 220868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 221061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 221161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 221261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp); 221361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 221461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22152e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]) 22162e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(buf, 22172e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]); 22182e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P IE */ 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 222104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 222204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2229a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (query_count) { 2230a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_buf_add_service_instance(buf, p2p, query_count, query_hash, 2231216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_adv_list); 2232216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2233216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int p2p_service_find_asp(struct p2p_data *p2p, const u8 *hash) 2239216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 2240216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_advertisement *adv_data; 2241a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt int any_wfa; 2242216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2243216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "ASP find - ASP list: %p", p2p->p2ps_adv_list); 2244216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2245a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt /* Wildcard org.wi-fi.wfds matches any WFA spec defined service */ 2246a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt any_wfa = os_memcmp(hash, p2p->wild_card_hash, P2PS_HASH_LEN) == 0; 2247216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2248216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data = p2p->p2ps_adv_list; 2249216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt while (adv_data) { 2250216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (os_memcmp(hash, adv_data->hash, P2PS_HASH_LEN) == 0) 2251a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return 1; /* exact hash match */ 2252a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (any_wfa && 2253a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_strncmp(adv_data->svc_name, P2PS_WILD_HASH_STR, 2254a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_strlen(P2PS_WILD_HASH_STR)) == 0) 2255a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return 1; /* WFA service match */ 2256216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data = adv_data->next; 2257216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2258216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2259216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 2260216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 2261216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2262216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 226304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum p2p_probe_req_status 226404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 2265a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len, 2266a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt unsigned int rx_freq) 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 22711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_message msg; 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2273a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt u8 channel, op_class; 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) == 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ParseFailed) { 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ignore invalid Probe Request frames */ 2278ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Could not parse Probe Request frame - ignore it"); 227904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_MALFORMED; 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.p2p == NULL) { 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not a P2P probe - ignore it */ 2284ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Not a P2P probe - ignore it"); 228504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dst && !is_broadcast_ether_addr(dst) && 22891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 22901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the broadcast address or our P2P Device Address 22911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 2292ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req DA " MACSTR " not ours - ignore it", 2293ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt MAC2STR(dst)); 229404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 22951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 22961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 22971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (bssid && !is_broadcast_ether_addr(bssid)) { 22981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the Wildcard BSSID */ 2299ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req BSSID " MACSTR " not wildcard - ignore it", 2300ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt MAC2STR(bssid)); 230104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 23021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 23031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN || 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) != 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not using P2P Wildcard SSID - ignore */ 2308ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req not using P2P Wildcard SSID - ignore it"); 230904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (supp_rates_11b_only(&elems)) { 23131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Indicates support for 11b rates only */ 2314ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req with 11b rates only supported - ignore it"); 231504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 23161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 23171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 23181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 23191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0) { 23201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Could not parse P2P attributes */ 2321ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Could not parse P2P attributes in Probe Req - ignore it"); 232204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 23231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 23241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2325216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.service_hash && msg.service_hash_count) { 2326216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *hash = msg.service_hash; 2327216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 i; 2328a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt int p2ps_svc_found = 0; 2329216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 23304171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt p2p_dbg(p2p, "in_listen=%d drv_in_listen=%d when received P2PS Probe Request at %u MHz; own Listen channel %u, pending listen freq %u MHz", 23314171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt p2p->in_listen, p2p->drv_in_listen, rx_freq, 23324171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt p2p->cfg->channel, p2p->pending_listen_freq); 23334171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt 23344171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt if (!p2p->in_listen && !p2p->drv_in_listen && 23354171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt p2p->pending_listen_freq && rx_freq && 23364171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt rx_freq != p2p->pending_listen_freq) { 23374171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt p2p_dbg(p2p, "Do not reply to Probe Request frame that was received on %u MHz while waiting to start Listen state on %u MHz", 23384171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt rx_freq, p2p->pending_listen_freq); 23394171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt p2p_parse_free(&msg); 23404171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt return P2P_PREQ_NOT_LISTEN; 23414171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt } 23424171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt 2343216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (i = 0; i < msg.service_hash_count; i++) { 2344216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p_service_find_asp(p2p, hash)) { 2345a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_dbg(p2p, "Service Hash match found: " 2346a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt MACSTR, MAC2STR(hash)); 2347a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2ps_svc_found = 1; 2348a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt break; 2349216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2350216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt hash += P2PS_HASH_LEN; 2351216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2352216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2353216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Probed hash unknown */ 2354a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (!p2ps_svc_found) { 2355a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_dbg(p2p, "No Service Hash match found"); 2356216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_parse_free(&msg); 2357216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 2358216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2359216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 2360216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* This is not a P2PS Probe Request */ 2361216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "No P2PS Hash in Probe Request"); 2362216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2363216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2p->in_listen || !p2p->drv_in_listen) { 2364216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* not in Listen state - ignore Probe Request */ 2365216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Not in Listen state (in_listen=%d drv_in_listen=%d) - ignore Probe Request", 2366216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->in_listen, p2p->drv_in_listen); 2367216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_parse_free(&msg); 2368216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2P_PREQ_NOT_LISTEN; 2369216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2370216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2371216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 23721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.device_id && 237304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 23741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Device ID did not match */ 2375ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req requested Device ID " MACSTR " did not match - ignore it", 2376ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt MAC2STR(msg.device_id)); 23771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 237804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 23791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 23801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check Requested Device Type match */ 23821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.wps_attributes && 23831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !p2p_match_dev_type(p2p, msg.wps_attributes)) { 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No match with Requested Device Type */ 2385ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req requestred Device Type did not match - ignore it"); 23861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 238704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 239004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!p2p->cfg->send_probe_resp) { 239104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Response generated elsewhere */ 2392ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Resp generated elsewhere - do not generate additional response"); 2393a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_parse_free(&msg); 239404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 239504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2397b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Reply to P2P Probe Request in Listen state"); 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We do not really have a specific BSS that this frame is advertising, 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so build a frame that has some information in valid format. This is 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * really only used for discovery purposes, not to learn exact BSS 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parameters. 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2405a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p, msg.service_hash, 2406a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt msg.service_hash_count); 2407a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_parse_free(&msg); 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 240904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(200 + wpabuf_len(ies)); 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 241404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24174171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt resp = wpabuf_put(buf, offsetof(struct ieee80211_mgmt, 24184171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt u.probe_resp.variable)); 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) | 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WLAN_FC_STYPE_PROBE_RESP << 4)); 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, addr, ETH_ALEN); 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN); 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN); 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.beacon_int = host_to_le16(100); 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* hardware or low-level driver will setup seq_ctrl and timestamp */ 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.capab_info = 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE | 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_PRIVACY | 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_SHORT_SLOT_TIME); 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SSID); 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN); 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES); 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 8); 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (60 / 5) | 0x80); 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 90 / 5); 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (120 / 5) | 0x80); 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 180 / 5); 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (240 / 5) | 0x80); 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 360 / 5); 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 480 / 5); 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 540 / 5); 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2447a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (!rx_freq) { 2448a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt channel = p2p->cfg->channel; 2449a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt } else if (p2p_freq_to_channel(rx_freq, &op_class, &channel)) { 2450a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpabuf_free(ies); 2451a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpabuf_free(buf); 2452a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 2453a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt } 2454a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS); 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 1); 2457a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpabuf_put_u8(buf, channel); 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(buf, ies); 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2462a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf, rx_freq); 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 246504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2466a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return P2P_PREQ_PROCESSED; 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 247004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtenum p2p_probe_req_status 247104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 2472a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len, 2473a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt unsigned int rx_freq) 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 247504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum p2p_probe_req_status res; 247604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2479a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len, rx_freq); 2480a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (res != P2P_PREQ_PROCESSED && res != P2P_PREQ_NOT_PROCESSED) 2481a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return res; 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2483a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt /* 2484a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * Activate a pending GO Negotiation/Invite flow if a received Probe 2485a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * Request frame is from an expected peer. Some devices may share the 2486a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * same address for P2P and non-P2P STA running simultaneously. The 2487a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * P2P_PREQ_PROCESSED and P2P_PREQ_NOT_PROCESSED p2p_reply_probe() 2488a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * return values verified above ensure we are handling a Probe Request 2489a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * frame from a P2P peer. 2490a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt */ 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer && 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN) 24949cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt == 0 && 24959cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt !(p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from GO Negotiation peer */ 2497b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Found GO Negotiation peer - try to start GO negotiation from timeout"); 24989cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL); 2500a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return res; 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) && 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer && 25053c4793790bf06f1fe08a2ddf604c9caa855151f1Dmitry Shmidt (p2p->invite_peer->flags & P2P_DEV_WAIT_INV_REQ_ACK) && 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN) 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from Invite peer */ 2509b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Found Invite peer - try to start Invite from timeout"); 25107f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt eloop_cancel_timeout(p2p_invite_start, p2p, NULL); 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL); 2512a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return res; 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 251504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return res; 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, struct wpabuf *p2p_ie) 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 252705df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt struct p2p_message msg; 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* WLAN AP is not a P2P manager */ 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 253205df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 253305df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg) < 0) 253405df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt return 0; 253505df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt 253605df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt p2p_dbg(p2p, "BSS P2P manageability %s", 253705df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt msg.manageability ? "enabled" : "disabled"); 253805df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt 253905df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt if (!msg.manageability) 254005df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt return 0; 254105df46a3aef489a33f92efb91b091c1aa6d16f95Dmitry Shmidt 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Interface attribute (present if concurrent device and 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Management is enabled) 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_alloc(200); 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = 0; 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->num_groups > 0) { 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect) 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab); 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_p2p_interface(tmp, p2p); 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int p2p_group, struct wpabuf *p2p_ie) 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *peer; 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 258861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_group) 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie); 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 259361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 259461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 259561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_assoc_req); 259661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 259761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25982e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]) 25992e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]); 26002e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen Timing (may be present) 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Info attribute (shall be present) 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 260761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tmp = wpabuf_alloc(200 + extra); 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 261161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 261261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 261361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req); 261461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 261561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 26162e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]) 26172e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(tmp, 26182e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]); 26192e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = bssid ? p2p_get_device(p2p, bssid) : NULL; 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, 0); 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period, 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(tmp, p2p, peer); 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end) 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE); 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_attr_text(p2p_ie, buf, end); 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstruct p2ps_advertisement * 2659216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtp2p_service_p2ps_id(struct p2p_data *p2p, u32 adv_id) 2660216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 2661216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_advertisement *adv_data; 2662216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2663216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2p) 2664216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return NULL; 2665216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2666216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data = p2p->p2ps_adv_list; 2667216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt while (adv_data) { 2668216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (adv_data->id == adv_id) 2669216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return adv_data; 2670216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data = adv_data->next; 2671216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2672216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2673216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return NULL; 2674216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 2675216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2676216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2677216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtint p2p_service_del_asp(struct p2p_data *p2p, u32 adv_id) 2678216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 2679216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_advertisement *adv_data; 2680216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_advertisement **prior; 2681216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2682216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2p) 2683216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 2684216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2685216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data = p2p->p2ps_adv_list; 2686216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt prior = &p2p->p2ps_adv_list; 2687216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt while (adv_data) { 2688216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (adv_data->id == adv_id) { 2689216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Delete ASP adv_id=0x%x", adv_id); 2690216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *prior = adv_data->next; 2691216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_free(adv_data); 2692216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 2693216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2694216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt prior = &adv_data->next; 2695216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data = adv_data->next; 2696216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2697216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2698216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 2699216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 2700216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2701216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2702216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtint p2p_service_add_asp(struct p2p_data *p2p, int auto_accept, u32 adv_id, 2703216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const char *adv_str, u8 svc_state, u16 config_methods, 2704d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *svc_info, const u8 *cpt_priority) 2705216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 2706216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_advertisement *adv_data, *tmp, **prev; 2707216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 buf[P2PS_HASH_LEN]; 2708216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t adv_data_len, adv_len, info_len = 0; 2709d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int i; 2710216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2711d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!p2p || !adv_str || !adv_str[0] || !cpt_priority) 2712216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 2713216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2714216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!(config_methods & p2p->cfg->config_methods)) { 2715216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Config methods not supported svc: 0x%x dev: 0x%x", 2716216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt config_methods, p2p->cfg->config_methods); 2717216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 2718216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2719216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2720216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2ps_gen_hash(p2p, adv_str, buf)) 2721216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 2722216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2723216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (svc_info) 2724216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt info_len = os_strlen(svc_info); 2725216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_len = os_strlen(adv_str); 2726216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data_len = sizeof(struct p2ps_advertisement) + adv_len + 1 + 2727216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt info_len + 1; 2728216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2729216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data = os_zalloc(adv_data_len); 2730216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!adv_data) 2731216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 2732216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2733216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(adv_data->hash, buf, P2PS_HASH_LEN); 2734216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data->id = adv_id; 2735216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data->state = svc_state; 2736216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data->config_methods = config_methods & p2p->cfg->config_methods; 2737216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data->auto_accept = (u8) auto_accept; 2738216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(adv_data->svc_name, adv_str, adv_len); 2739216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2740d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (i = 0; cpt_priority[i] && i < P2PS_FEATURE_CAPAB_CPT_MAX; i++) { 2741d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt adv_data->cpt_priority[i] = cpt_priority[i]; 2742d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt adv_data->cpt_mask |= cpt_priority[i]; 2743d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2744d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2745216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (svc_info && info_len) { 2746216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data->svc_info = &adv_data->svc_name[adv_len + 1]; 2747216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(adv_data->svc_info, svc_info, info_len); 2748216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2749216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2750216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* 2751216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * Group Advertisements by service string. They do not need to be 2752216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * sorted, but groups allow easier Probe Response instance grouping 2753216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt */ 2754216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp = p2p->p2ps_adv_list; 2755216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt prev = &p2p->p2ps_adv_list; 2756216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt while (tmp) { 2757216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (tmp->id == adv_data->id) { 2758216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (os_strcmp(tmp->svc_name, adv_data->svc_name) != 0) { 2759216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_free(adv_data); 2760216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 2761216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2762216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data->next = tmp->next; 2763216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *prev = adv_data; 2764216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_free(tmp); 2765216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto inserted; 2766216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 2767216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (os_strcmp(tmp->svc_name, adv_data->svc_name) == 0) { 2768216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data->next = tmp->next; 2769216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->next = adv_data; 2770216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto inserted; 2771216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2772216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2773216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt prev = &tmp->next; 2774216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp = tmp->next; 2775216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2776216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2777216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* No svc_name match found */ 2778216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_data->next = p2p->p2ps_adv_list; 2779216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_adv_list = adv_data; 2780216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2781216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtinserted: 2782216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, 2783d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "Added ASP advertisement adv_id=0x%x config_methods=0x%x svc_state=0x%x adv_str='%s' cpt_mask=0x%x", 2784d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt adv_id, adv_data->config_methods, svc_state, adv_str, 2785d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt adv_data->cpt_mask); 2786216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2787216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 2788216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 2789216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2790216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2791dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidtvoid p2p_service_flush_asp(struct p2p_data *p2p) 2792dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt{ 2793dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt struct p2ps_advertisement *adv, *prev; 2794dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt 2795dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt if (!p2p) 2796dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt return; 2797dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt 2798dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt adv = p2p->p2ps_adv_list; 2799dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt while (adv) { 2800dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt prev = adv; 2801dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt adv = adv->next; 2802dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt os_free(prev); 2803dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt } 2804dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt 2805dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt p2p->p2ps_adv_list = NULL; 2806dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt p2p_dbg(p2p, "All ASP advertisements flushed"); 2807dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt} 2808dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt 2809dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt 281004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr) 2811c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 2812c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct p2p_message msg; 2813c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2814c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 281504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 2816c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 2817c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 281804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.p2p_device_addr) { 281904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN); 282004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 282104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (msg.device_id) { 282204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.device_id, ETH_ALEN); 282304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 2824c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 282504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 282604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 2827c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 282804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 282904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr) 283004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 283104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *p2p_ie; 283204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 283304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 283404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 283504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_IE_VENDOR_TYPE); 283604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_ie == NULL) 283704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 283804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr); 2839c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpabuf_free(p2p_ie); 284004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 2841c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 2842c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2843c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_clear_go_neg(struct p2p_data *p2p) 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr) 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 2855b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending Group Formation - ignore WPS registration success notification"); 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) != 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 2861b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore WPS registration success notification for " 2862b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " (GO Negotiation peer " MACSTR ")", 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr), 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Ignore unexpected peer address */ 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2868b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Group Formation completed successfully with " MACSTR, 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr)); 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_group_formation_failed(struct p2p_data *p2p) 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 2878b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending Group Formation - ignore group formation failure notification"); 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2882b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Group Formation failed with " MACSTR, 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_data * p2p_init(const struct p2p_config *cfg) 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p; 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28932271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (cfg->max_peers < 1 || 28942271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt cfg->passphrase_len < 8 || cfg->passphrase_len > 63) 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg)); 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg = (struct p2p_config *) (p2p + 1); 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg, cfg, sizeof(*cfg)); 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->dev_name) 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(cfg->dev_name); 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->manufacturer) 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(cfg->manufacturer); 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_name) 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(cfg->model_name); 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_number) 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(cfg->model_number); 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->serial_number) 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(cfg->serial_number); 291204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (cfg->pref_chan) { 291304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan * 291404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 291504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->cfg->pref_chan) { 291604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan, 291704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cfg->num_pref_chan * 291804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 291904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 292004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = 0; 292104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 292204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2923216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_gen_hash(p2p, P2PS_WILD_HASH_STR, p2p->wild_card_hash); 2924216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int = 1; 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->max_disc_int = 3; 2927d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = -1; 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2929661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random(&p2p->next_tie_breaker, 1) < 0) 2930661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p->next_tie_breaker = 0; 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->next_tie_breaker &= 0x01; 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->sd_request) 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY; 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE; 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->concurrent_operations) 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER; 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_init(&p2p->devices); 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 294161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = 100; 294261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = 20; 294313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt p2p->num_p2p_sd_queries = 0; 294461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 294568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "initialized"); 294668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); 294768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "cli_channels", &p2p->cfg->cli_channels); 294868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p; 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deinit(struct p2p_data *p2p) 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 295561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 295661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 295761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 295861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 295961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 296061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 296161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 296261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 296361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 296461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 296561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 296661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 296761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 296861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 29709cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 29716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eloop_cancel_timeout(p2p_go_neg_wait_timeout, p2p, NULL); 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_flush(p2p); 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 297904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->groups); 2981a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2ps_prov_free(p2p); 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->sd_resp); 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 298568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(p2p->no_go_freq.range); 2986dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt p2p_service_flush_asp(p2p); 2987216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p); 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_flush(struct p2p_data *p2p) 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *prev; 2995d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2996d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p_ext_listen(p2p, 0, 0); 299704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_find(p2p); 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device, 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list) { 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_sd_queries(p2p); 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 3006d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->ssid_set = 0; 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_unauthorize(struct p2p_data *p2p, const u8 *addr) 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3018b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unauthorizing " MACSTR, MAC2STR(addr)); 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (p2p->go_neg_peer == dev) { 30216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eloop_cancel_timeout(p2p_go_neg_wait_timeout, p2p, NULL); 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 30236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = WPS_NOT_READY; 3026cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_pw_id = 0; 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check if after_scan_tx is for this peer. If so free it */ 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx && 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) { 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name) 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_name) { 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(dev_name); 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->dev_name == NULL) 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = NULL; 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer) 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = NULL; 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (manufacturer) { 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(manufacturer); 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->manufacturer == NULL) 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_name(struct p2p_data *p2p, const char *model_name) 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = NULL; 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_name) { 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(model_name); 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_name == NULL) 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_number(struct p2p_data *p2p, const char *model_number) 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = NULL; 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_number) { 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(model_number); 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_number == NULL) 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number) 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = NULL; 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (serial_number) { 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(serial_number); 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->serial_number == NULL) 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods) 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->config_methods = config_methods; 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid) 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->uuid, uuid, 16); 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type) 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8); 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8], 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_dev_types) 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_dev_types > P2P_SEC_DEVICE_TYPES) 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_dev_types = P2P_SEC_DEVICE_TYPES; 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->num_sec_dev_types = num_dev_types; 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8); 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_remove_wps_vendor_extensions(struct p2p_data *p2p) 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->wps_vendor_ext[i]); 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = NULL; 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_add_wps_vendor_extension(struct p2p_data *p2p, 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *vendor_ext) 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor_ext == NULL) 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= P2P_MAX_WPS_VENDOR_EXT) 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext); 31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_country(struct p2p_data *p2p, const char *country) 31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->country, country, 3); 31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int p2p_pre_find_operation(struct p2p_data *p2p, struct p2p_device *dev) 31826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 3183de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt int res; 3184de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 31856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dev->sd_pending_bcast_queries == 0) { 31866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* Initialize with total number of registered broadcast 31876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * SD queries. */ 31886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dev->sd_pending_bcast_queries = p2p->num_p2p_sd_queries; 31896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 31906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3191de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt res = p2p_start_sd(p2p, dev); 3192de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (res == -2) 3193de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt return -2; 3194de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (res == 0) 31956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 1; 31966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 31976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dev->req_config_methods && 31986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !(dev->flags & P2P_DEV_PD_FOR_JOIN)) { 31996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_dbg(p2p, "Send pending Provision Discovery Request to " 32006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt MACSTR " (config methods 0x%x)", 32016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 32026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dev->req_config_methods); 32036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0) 32046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 1; 32056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 32066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 32076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 32086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 32096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 32106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_continue_find(struct p2p_data *p2p) 32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3214de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt int found, res; 32156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 32176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 32186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* Continue from the device following the last iteration */ 32196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt found = 0; 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 32216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dev == p2p->last_p2p_find_oper) { 32226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt found = 1; 32236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt continue; 32246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 32256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!found) 32266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt continue; 3227de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt res = p2p_pre_find_operation(p2p, dev); 3228de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (res > 0) { 32296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p->last_p2p_find_oper = dev; 32306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 323113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 3232de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (res == -2) 3233de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt goto skip_sd; 32346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 323513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 32366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 32376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Wrap around to the beginning of the list and continue until the last 32386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * iteration device. 32396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 32406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3241de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt res = p2p_pre_find_operation(p2p, dev); 3242de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (res > 0) { 32436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p->last_p2p_find_oper = dev; 324413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return; 32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3246de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (res == -2) 3247de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt goto skip_sd; 32486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dev == p2p->last_p2p_find_oper) 32496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3252de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidtskip_sd: 3253de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt os_memset(p2p->sd_query_no_ack, 0, ETH_ALEN); 3254d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 1); 32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_sd_cb(struct p2p_data *p2p, int success) 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3260b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Service Discovery Query TX callback: success=%d", 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 3265de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (p2p->sd_peer) { 3266de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (is_zero_ether_addr(p2p->sd_query_no_ack)) { 3267de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt os_memcpy(p2p->sd_query_no_ack, 3268de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt p2p->sd_peer->info.p2p_device_addr, 3269de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt ETH_ALEN); 3270de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt p2p_dbg(p2p, 3271de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt "First SD Query no-ACK in this search iteration: " 3272de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt MACSTR, MAC2STR(p2p->sd_query_no_ack)); 3273de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt } 32746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3275de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt } 327613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt p2p->sd_peer = NULL; 3277216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->state != P2P_IDLE) 3278216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_continue_find(p2p); 32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == NULL) { 3283b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No SD peer entry known"); 3284216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->state != P2P_IDLE) 3285216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_continue_find(p2p); 32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3289807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (p2p->sd_query && p2p->sd_query->for_all_peers) { 3290661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Update the pending broadcast SD query count for this device 3291661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt */ 3292661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p->sd_peer->sd_pending_bcast_queries--; 3293661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 3294661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* 3295661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * If there are no pending broadcast queries for this device, 3296661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * mark it as done (-1). 3297661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt */ 3298661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (p2p->sd_peer->sd_pending_bcast_queries == 0) 3299661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p->sd_peer->sd_pending_bcast_queries = -1; 3300661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 3301661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SD_DURING_FIND); 33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 330775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 330875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/** 330975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * p2p_retry_pd - Retry any pending provision disc requests in IDLE state 331075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @p2p: P2P module context from p2p_init() 331175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 33121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_retry_pd(struct p2p_data *p2p) 331375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 331475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct p2p_device *dev; 331575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 331675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 331775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Retry the prov disc req attempt only for the peer that the user had 3318d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * requested. 331975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 332075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 332175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 332275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (os_memcmp(p2p->pending_pd_devaddr, 332375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.p2p_device_addr, ETH_ALEN) != 0) 332475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 332575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!dev->req_config_methods) 332675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 332775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3328b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Provision Discovery Request to " 332975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MACSTR " (config methods 0x%x)", 333075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MAC2STR(dev->info.p2p_device_addr), 333175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->req_config_methods); 3332d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_send_prov_disc_req(p2p, dev, 3333051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN, 3334051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p2p->pd_force_freq); 333575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 333675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 333775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 333875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 333975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_prov_disc_cb(struct p2p_data *p2p, int success) 33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3342b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request TX callback: success=%d", 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 334475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 334575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 334675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Postpone resetting the pending action state till after we actually 334775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * time out. This allows us to take some action like notifying any 334875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * interested parties about no response to the request. 334975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 335075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When the timer (below) goes off we check in IDLE, SEARCH, or 335175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * LISTEN_ONLY state, which are the only allowed states to issue a PD 335275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * requests in, if this was still pending and then raise notification. 335375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 335675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 335775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 335861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->user_initiated_pd && 335961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->state == P2P_SEARCH || p2p->state == P2P_LISTEN_ONLY)) 336061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { 336161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Retry request from timeout to avoid busy loops */ 336261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 336361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, 0, 50000); 336461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (p2p->state != P2P_IDLE) 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 336675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else if (p2p->user_initiated_pd) { 336775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 336875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_set_timeout(p2p, 0, 300000); 336975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 337375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 3374d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * If after PD Request the peer doesn't expect to receive PD Response 3375d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * the PD Request ACK indicates a completion of the current PD. This 3376d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * happens only on the advertiser side sending the follow-on PD Request 3377d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * with the status different than 12 (Success: accepted by user). 3378d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 3379d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (p2p->p2ps_prov && !p2p->p2ps_prov->pd_seeker && 3380d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->p2ps_prov->status != P2P_SC_SUCCESS_DEFERRED) { 3381d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p_dbg(p2p, "P2PS PD completion on Follow-on PD Request ACK"); 3382d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3383d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (p2p->send_action_in_progress) { 3384d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->send_action_in_progress = 0; 3385d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3386d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3387d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3388d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 3389d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3390d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (p2p->cfg->p2ps_prov_complete) { 3391d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->cfg->p2ps_prov_complete( 3392d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->cfg->cb_ctx, 3393d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->p2ps_prov->status, 3394d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->p2ps_prov->adv_mac, 3395d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->p2ps_prov->adv_mac, 3396d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->p2ps_prov->session_mac, 3397d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt NULL, p2p->p2ps_prov->adv_id, 3398d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->p2ps_prov->session_id, 3399d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 0, 0, NULL, 0, 0, 0, 3400de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt NULL, NULL, 0, 0, NULL, 0); 3401d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3402d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3403d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (p2p->user_initiated_pd) 3404d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p_reset_pending_pd(p2p); 3405d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3406d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2ps_prov_free(p2p); 3407d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 3408d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3409d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3410d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 341175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * This postponing, of resetting pending_action_state, needs to be 341275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * done only for user initiated PD requests and not internal ones. 341375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 341475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd) 341575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 341675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else 341775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 341875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PD_DURING_FIND); 34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3426216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int p2p_check_after_scan_tx_continuation(struct p2p_data *p2p) 3427216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 3428216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->after_scan_tx_in_progress) { 3429216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 3430216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->start_after_scan != P2P_AFTER_SCAN_NOTHING && 3431216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_run_after_scan(p2p)) 3432216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 1; 3433216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->state == P2P_SEARCH) { 3434216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Continue find after after_scan_tx completion"); 3435216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_continue_find(p2p); 3436216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3437216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3438216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3439216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 3440216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 3441216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3442216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3443216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic void p2p_prov_disc_resp_cb(struct p2p_data *p2p, int success) 3444216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 3445216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Response TX callback: success=%d", 3446216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt success); 3447216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3448216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->send_action_in_progress) { 3449216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->send_action_in_progress = 0; 3450216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3451216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3452216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3453216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 3454216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3455216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!success) 3456216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto continue_search; 3457216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3458216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2p->cfg->prov_disc_resp_cb || 3459216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->prov_disc_resp_cb(p2p->cfg->cb_ctx) < 1) 3460216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto continue_search; 3461216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3462216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, 3463216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "Post-Provision Discovery operations started - do not try to continue other P2P operations"); 3464216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return; 3465216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3466216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtcontinue_search: 3467216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_check_after_scan_tx_continuation(p2p); 3468216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 3469216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3470216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 34718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, 3472fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime *rx_time, int level, const u8 *ies, 3473a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len) 34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3475fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (os_reltime_before(rx_time, &p2p->find_start)) { 3476f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 3477f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * The driver may have cached (e.g., in cfg80211 BSS table) the 3478f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * scan results for relatively long time. To avoid reporting 3479f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * stale information, update P2P peers only based on results 3480f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * that have based on frames received after the last p2p_find 3481f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * operation was started. 3482f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 3483b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore old scan result for " MACSTR 3484de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt " (rx_time=%u.%06u find_start=%u.%06u)", 3485f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt MAC2STR(bssid), (unsigned int) rx_time->sec, 3486de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt (unsigned int) rx_time->usec, 3487de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt (unsigned int) p2p->find_start.sec, 3488de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt (unsigned int) p2p->find_start.usec); 3489f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 3490f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 3491f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 3492f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt p2p_add_device(p2p, bssid, freq, rx_time, level, ies, ies_len, 1); 34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_scan_res_handled(struct p2p_data *p2p) 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->p2p_scan_running) { 3501b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan was not running, but scan results received"); 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 35048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_run_after_scan(p2p)) 35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35139c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidtvoid p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id, 35149c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt unsigned int bands) 35158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3516216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 dev_capab; 351761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len; 351861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 351961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 352061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_req) 352161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(ies, p2p->wfd_ie_probe_req); 352261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 352361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 35242e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]) 35252e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(ies, 35262e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]); 35272e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 352861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len = p2p_buf_add_ie_hdr(ies); 3529216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3530216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev_capab = p2p->dev_capab & ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 3531216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3532216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* P2PS requires Probe Request frames to include SD bit */ 3533216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_seek && p2p->p2ps_seek_count) 3534216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY; 3535216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3536216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_capability(ies, dev_capab, 0); 3537216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3538c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) 3539c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_buf_add_device_id(ies, dev_id); 35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->reg_class && p2p->cfg->channel) 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_listen_channel(ies, p2p->cfg->country, 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class, 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period, 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 3547216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 35489c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt if (bands & BAND_60_GHZ) 35499c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt p2p_buf_add_device_info(ies, p2p, NULL); 35509c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt 3551216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_seek && p2p->p2ps_seek_count) 3552216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_service_hash(ies, p2p); 3553216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: p2p_buf_add_operating_channel() if GO */ 35558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(ies, len); 35568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtsize_t p2p_scan_ie_buf_len(struct p2p_data *p2p) 35601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 356161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 100; 356261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 356361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 356461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p && p2p->wfd_ie_probe_req) 356561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += wpabuf_len(p2p->wfd_ie_probe_req); 356661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 356761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 35682e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p && p2p->vendor_elem && 35692e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]) 35702e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt len += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]); 35712e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 357261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 35731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 35741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end) 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_attr_text(p2p_ie, buf, end); 35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_req_cb(struct p2p_data *p2p, int success) 35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 35858c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt int timeout; 35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3587b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Request TX callback: success=%d", success); 35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 3590b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending GO Negotiation"); 35918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (success) { 35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 359904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (dev->go_neg_req_sent) { 360004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Cancel the increment from p2p_connect_send() on failure */ 360198f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt dev->go_neg_req_sent--; 360298f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt } 36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success && 36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) && 36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(dev->member_in_go_dev)) { 3607b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " did not acknowledge request - try to use device discoverability through its GO", 36088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 36098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 36108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_send_dev_disc_req(p2p, dev); 36118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 36128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 36158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use P2P find, if needed, to find the other device from its listen 36168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 36178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 36188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 36198c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout = success ? 500000 : 100000; 36208c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (!success && p2p->go_neg_peer && 36218c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE)) { 36228c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt unsigned int r; 36238c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt /* 36248c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * Peer is expected to wait our response and we will skip the 36258c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * listen phase. Add some randomness to the wait time here to 36268c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * make it less likely to hit cases where we could end up in 36278c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * sync with peer not listening. 36288c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt */ 3629661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random((u8 *) &r, sizeof(r)) < 0) 3630661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt r = 0; 36318c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout += r % 100000; 36328c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 36338c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, timeout); 36348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success) 36388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3639b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Response TX callback: success=%d", 36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 36418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) { 3642b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore TX callback event - GO Negotiation is not running anymore"); 36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 36448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 36468c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 36478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36504b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtstatic void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success, 36514b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt const u8 *addr) 36528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3653b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Response (failure) TX callback: success=%d", success); 36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) { 36556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer->status); 3656203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt return; 3657203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 3658203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 3659203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (success) { 36604b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt struct p2p_device *dev; 36614b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev = p2p_get_device(p2p, addr); 36624b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (dev && 366334c1202b3e71c63661a850aad81f663e40e48ca1Dmitry Shmidt dev->status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) 36644b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->flags |= P2P_DEV_PEER_WAITING_RESPONSE; 36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3666203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 3667203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (p2p->state == P2P_SEARCH || p2p->state == P2P_SD_DURING_FIND) 3668203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt p2p_continue_find(p2p); 36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_conf_cb(struct p2p_data *p2p, 36738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 36748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3677b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Confirm TX callback: result=%d", result); 36788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_FAILED) { 3679413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 36806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_go_neg_failed(p2p, -1); 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3683413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 3684413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev = p2p->go_neg_peer; 3685413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_NO_ACK) { 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3688413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * Retry GO Negotiation Confirmation 3689413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * P2P_GO_NEG_CNF_MAX_RETRY_COUNT times if we did not receive 3690413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * ACK for confirmation. 3691413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt */ 3692413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt if (dev && dev->go_neg_conf && 3693413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->go_neg_conf_sent <= P2P_GO_NEG_CNF_MAX_RETRY_COUNT) { 3694413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p_dbg(p2p, "GO Negotiation Confirm retry %d", 3695413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->go_neg_conf_sent); 3696413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->pending_action_state = P2P_PENDING_GO_NEG_CONFIRM; 3697413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt if (p2p_send_action(p2p, dev->go_neg_conf_freq, 3698413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->info.p2p_device_addr, 3699413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->cfg->dev_addr, 3700413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->info.p2p_device_addr, 3701413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_head(dev->go_neg_conf), 3702413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_len(dev->go_neg_conf), 0) >= 3703413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 0) { 3704413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->go_neg_conf_sent++; 3705413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt return; 3706413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt } 3707413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p_dbg(p2p, "Failed to re-send Action frame"); 3708413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 3709413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt /* 3710413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * Continue with the assumption that the first attempt 3711413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * went through and just the ACK frame was lost. 3712413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt */ 3713413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt } 3714413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 3715413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt /* 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * It looks like the TX status for GO Negotiation Confirm is 37178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * often showing failure even when the peer has actually 37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received the frame. Since the peer may change channels 37198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately after having received the frame, we may not see 37208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an Ack for retries, so just dropping a single frame may 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * trigger this. To allow the group formation to succeed if the 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer did indeed receive the frame, continue regardless of 37238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the TX status. 37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3725b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Assume GO Negotiation Confirm TX was actually received by the peer even though Ack was not reported"); 37268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3728413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3729413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_complete(p2p, dev); 37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_pending_action_state state; 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int success; 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3744b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Action frame TX callback (state=%d freq=%u dst=" MACSTR 3745216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " src=" MACSTR " bssid=" MACSTR " result=%d p2p_state=%s)", 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src), 3747216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(bssid), result, p2p_state_txt(p2p->state)); 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success = result == P2P_SEND_ACTION_SUCCESS; 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = p2p->pending_action_state; 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NO_PENDING_ACTION: 37534582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt if (p2p->send_action_in_progress) { 37544582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt p2p->send_action_in_progress = 0; 37554582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 37564582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt } 3757216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_check_after_scan_tx_continuation(p2p); 37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_REQUEST: 37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_req_cb(p2p, success); 37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE: 37638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_cb(p2p, success); 37648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE_FAILURE: 37664b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_go_neg_resp_failure_cb(p2p, success, dst); 37678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_CONFIRM: 37698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_conf_cb(p2p, result); 37708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_SD: 37728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_cb(p2p, success); 37738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_PD: 37758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_prov_disc_cb(p2p, success); 37768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3777216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2P_PENDING_PD_RESPONSE: 3778216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_prov_disc_resp_cb(p2p, success); 3779216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 37808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_REQUEST: 37818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_req_cb(p2p, success); 37828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_RESPONSE: 37848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_resp_cb(p2p, success); 37858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_REQUEST: 37878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_req_cb(p2p, success); 37888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_RESPONSE: 37908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_resp_cb(p2p, success); 37918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_DISC_REQ: 37938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_disc_req_cb(p2p, success); 37948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37968da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt 37978da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 37988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_listen_cb(struct p2p_data *p2p, unsigned int freq, 38028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int duration) 38038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == p2p->pending_client_disc_freq) { 3805b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability remain-awake completed"); 38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_freq = 0; 38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != p2p->pending_listen_freq) { 3811b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unexpected listen callback for freq=%u duration=%u (pending_listen_freq=%u)", 38128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration, p2p->pending_listen_freq); 38138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3816b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting Listen timeout(%u,%u) on freq=%u based on callback", 38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec, p2p->pending_listen_usec, 38188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq); 38198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 1; 38208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = freq; 38218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_listen_sec || p2p->pending_listen_usec) { 38228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 38238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Add 20 msec extra wait to avoid race condition with driver 38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * remain-on-channel end event, i.e., give driver more time to 38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * complete the operation before our timeout expires. 38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 38278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, p2p->pending_listen_sec, 38288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec + 20000); 38298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 38328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen_end(struct p2p_data *p2p, unsigned int freq) 38368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3837b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver ended Listen state (freq=%u)", freq); 38388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = 0; 38398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->in_listen) 38408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Internal timeout will trigger the next step */ 38418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) { 38438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 3844b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 38456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_go_neg_failed(p2p, -1); 38468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 38478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 38508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 38528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (p2p->state == P2P_SEARCH) { 3853c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->p2p_scan_running) { 3854c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 3855c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Search is already in progress. This can happen if 3856c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * an Action frame RX is reported immediately after 3857c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * the end of a remain-on-channel operation and the 3858c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * response frame to that is sent using an offchannel 3859c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * operation while in p2p_find. Avoid an attempt to 3860c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * restart a scan here. 3861c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 3862b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan already in progress - do not try to start a new one"); 3863c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 1; 3864c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 386504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->pending_listen_freq) { 386604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 386704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Better wait a bit if the driver is unable to start 386804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * offchannel operation for some reason. p2p_search() 386904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * will be started from internal timeout. 387004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 3871b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Listen operation did not seem to start - delay search phase to avoid busy loop"); 387204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 387304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 387404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 387561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay) { 3876b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay search operation by %u ms", 387761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 387861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 387961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 388061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 388161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 38878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect(struct p2p_data *p2p) 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 389304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer && 389404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 3895b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Wait for GO Negotiation Confirm timed out - assume GO Negotiation failed"); 38966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_go_neg_failed(p2p, -1); 389704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 389804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 38998c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer && 39008c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE) && 39018c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->connect_reqs < 120) { 3902b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer expected to wait our response - skip listen"); 39038c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 39048c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt return; 39058c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 3906cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->oob_go_neg_freq > 0) { 3907cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Skip connect-listen since GO Neg channel known (OOB)"); 3908cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 3909cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_set_timeout(p2p, 0, 30000); 3910cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return; 3911cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 39128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 3913d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect_listen(struct p2p_data *p2p) 39188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer) { 39208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 3921b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver is still in Listen state; wait for it to complete"); 39228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 3926b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 39276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_go_neg_failed(p2p, -1); 39288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 39338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 39358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_connect(struct p2p_data *p2p) 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); 39411846323989242844f0e857458a8939fa5836429cDmitry Shmidt 39421846323989242844f0e857458a8939fa5836429cDmitry Shmidt if (p2p->cfg->is_concurrent_session_active && 39431846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p->cfg->is_concurrent_session_active(p2p->cfg->cb_ctx)) 39441846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 39451846323989242844f0e857458a8939fa5836429cDmitry Shmidt else 39461846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_idle(struct p2p_data *p2p) 39518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 3955b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown GO Neg peer - stop GO Neg wait"); 39568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3959b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Go to Listen state while waiting for the peer to become ready for GO Negotiation"); 39608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); 3961d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 39628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_sd_during_find(struct p2p_data *p2p) 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3967b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Service Discovery Query timeout"); 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p) 39778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3978b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request timeout"); 39798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 39818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void p2p_timeout_prov_disc_req(struct p2p_data *p2p) 398575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 3986216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u32 adv_id = 0; 3987216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 *adv_mac = NULL; 3988216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 398975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 399075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 399175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 399275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * For user initiated PD requests that we have not gotten any responses 399375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * for while in IDLE state, we retry them a couple of times before 399475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * giving up. 399575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 399675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!p2p->user_initiated_pd) 399775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 399875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3999b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "User initiated Provision Discovery Request timeout"); 400075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 400175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pd_retries) { 400275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries--; 400375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_retry_pd(p2p); 400475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 4005d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct p2p_device *dev; 4006d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int for_join = 0; 4007d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4008d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4009d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (os_memcmp(p2p->pending_pd_devaddr, 4010d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dev->info.p2p_device_addr, ETH_ALEN) != 0) 4011d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt continue; 4012d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (dev->req_config_methods && 4013d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (dev->flags & P2P_DEV_PD_FOR_JOIN)) 4014d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join = 1; 4015d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 4016d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4017216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov) { 4018216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id = p2p->p2ps_prov->adv_id; 4019216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_mac = p2p->p2ps_prov->adv_mac; 4020216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 4021216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 402275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 402375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, 402475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_pd_devaddr, 4025d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join ? 4026d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt P2P_PROV_DISC_TIMEOUT_JOIN : 4027216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_PROV_DISC_TIMEOUT, 4028216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, adv_mac, NULL); 402975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 403075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 403175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 403275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 403375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 40348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite(struct p2p_data *p2p) 40358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 40378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE_LISTEN); 40388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { 40398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 40408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Better remain on operating channel instead of listen channel 40418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * when running a group. 40428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4043b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Inviting in active GO role - wait on operating channel"); 40448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 40458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4047d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 40488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite_listen(struct p2p_data *p2p) 40528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) { 40548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE); 40558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, 4056cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->invite_go_dev_addr, p2p->invite_dev_pw_id); 40578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 40588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer) { 4059b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Invitation Request retry limit reached"); 40608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->invitation_result) 40618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->invitation_result( 4062700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->cfg->cb_ctx, -1, NULL, NULL, 4063e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->invite_peer->info.p2p_device_addr, 406415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 0, 0); 40658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 40678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx) 40728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 40748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4075b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout (state=%s)", p2p_state_txt(p2p->state)); 40768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 0; 40786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (p2p->drv_in_listen) { 40796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_dbg(p2p, "Driver is still in listen state - stop it"); 40806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 40816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 40828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p->state) { 40848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 408575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 408675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 408775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 40888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 40898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 409075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 409175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 409275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 409361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay && !p2p->in_search_delay) { 4094b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay search operation by %u ms", 409561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 409661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 1; 409761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 409861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 409961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 410061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 410161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 41028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 41038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 41058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect(p2p); 41068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect_listen(p2p); 41098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 41118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 411375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 411475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 411575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 411675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 41178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_only) { 4118b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Extended Listen Timing - Listen State completed"); 41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 41208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 41218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 41248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_connect(p2p); 41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 41278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_idle(p2p); 41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 41308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_sd_during_find(p2p); 41318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 41338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 41358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_prov_disc_during_find(p2p); 41368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 41388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite(p2p); 41398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 41418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite_listen(p2p); 41428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 41438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_reject(struct p2p_data *p2p, const u8 *peer_addr) 41488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 41508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 4152b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Local request to reject connection attempts by peer " 4153b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(peer_addr)); 41548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 4155b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " unknown", MAC2STR(peer_addr)); 41568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_FAIL_REJECTED_BY_USER; 41598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_USER_REJECTED; 41608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst char * p2p_wps_method_text(enum p2p_wps_method method) 41658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (method) { 41678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_NOT_READY: 41688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "not-ready"; 41698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 41708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Display"; 41718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 41728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Keypad"; 41738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 41748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PBC"; 4175cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case WPS_NFC: 4176cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return "NFC"; 4177216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case WPS_P2PS: 4178216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return "P2PS"; 41798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 41828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_go_state_text(enum p2p_go_state go_state) 41868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (go_state) { 41888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case UNKNOWN_GO: 41898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "unknown"; 41908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case LOCAL_GO: 41918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "local"; 41928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case REMOTE_GO: 41938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "remote"; 41948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 41978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p, 42011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr, int next) 42028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 42048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) 42068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 42078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 42088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 42098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev && next) { 42118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, struct p2p_device, list); 42128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 42138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = NULL; 42148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 42171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 42181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return &dev->info; 42201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 42211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_get_peer_info_txt(const struct p2p_peer_info *info, 42241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *buf, size_t buflen) 42251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 42261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 42271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int res; 42281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *pos, *end; 4229fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now; 42301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (info == NULL) 42328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = (struct p2p_device *) (((u8 *) info) - 42351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offsetof(struct p2p_device, info)); 42361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 42388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 42398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4240fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 42418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 42428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "age=%d\n" 42438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d\n" 42448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wps_method=%s\n" 42458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface_addr=" MACSTR "\n" 42468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_dev=" MACSTR "\n" 42478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_iface=" MACSTR "\n" 42488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_neg_req_sent=%d\n" 42498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_state=%s\n" 42508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dialog_token=%u\n" 42518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "intended_addr=" MACSTR "\n" 42528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c\n" 42538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_freq=%d\n" 42548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "req_config_methods=0x%x\n" 4255a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n" 42568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d\n" 42578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation_reqs=%u\n", 42588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (now.sec - dev->last_seen.sec), 42598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, 42608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_method_text(dev->wps_method), 42618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->interface_addr), 42628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_dev), 42638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_iface), 42648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent, 42658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_state_text(dev->go_state), 42668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token, 42678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->intended_addr), 42688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[0] ? dev->country[0] : '_', 42698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[1] ? dev->country[1] : '_', 42708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq, 42718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 42728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PROBE_REQ_ONLY ? 42738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PROBE_REQ_ONLY]" : "", 42748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "", 42758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_NOT_YET_READY ? 42768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[NOT_YET_READY]" : "", 42778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_DISPLAY ? 42788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_DISPLAY]" : "", 42798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_KEYPAD ? 42808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_KEYPAD]" : "", 4281216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_P2PS ? 4282216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "[PD_PEER_P2PS]" : "", 42838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_USER_REJECTED ? 42848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[USER_REJECTED]" : "", 42858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ? 42868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PEER_WAITING_RESPONSE]" : "", 42878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ? 42888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PREFER_PERSISTENT_GROUP]" : "", 42898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ? 42908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_RESPONSE]" : "", 42918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ? 42928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_CONFIRM]" : "", 42938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ? 42948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[GROUP_CLIENT_ONLY]" : "", 42958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_FORCE_FREQ ? 42968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[FORCE_FREQ]" : "", 42978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN ? 42988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_FOR_JOIN]" : "", 4299a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt dev->flags & P2P_DEV_LAST_SEEN_AS_GROUP_CLIENT ? 4300a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt "[LAST_SEEN_AS_GROUP_CLIENT]" : "", 43018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status, 43028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->invitation_reqs); 43036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, res)) 43048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 43058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 43068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->ext_listen_period) { 43088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 43098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_period=%u\n" 43108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_interval=%u\n", 43118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period, 43128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval); 43136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, res)) 43148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 43158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 43168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_ssid_len) { 43198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 43208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_ssid=%s\n", 43218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(dev->oper_ssid, 43228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len)); 43236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, res)) 43248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 43258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 43268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 432861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 432961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (dev->info.wfd_subelems) { 433061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "wfd_subelems="); 43316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, res)) 433261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 433361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 433461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 433561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, 433661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_head(dev->info.wfd_subelems), 433761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(dev->info.wfd_subelems)); 433861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 433961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "\n"); 43406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, res)) 434161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 434261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 434361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 434461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 434561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 43468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 43478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_peer_known(struct p2p_data *p2p, const u8 *addr) 43511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 43521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_get_device(p2p, addr) != NULL; 43531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 43541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 43551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 43568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_client_discoverability(struct p2p_data *p2p, int enabled) 43578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 43588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 4359b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability enabled"); 43608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 43618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4362b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability disabled"); 43638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 43648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1, 43698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration2, u32 interval2) 43708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 43718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 43728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL; 43738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 43748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = wpabuf_alloc(100); 43768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 43778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 43788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration1 || interval1) { 43808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc1, 0, sizeof(desc1)); 43818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.count_type = 1; 43828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.duration = duration1; 43838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.interval = interval1; 43848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr1 = &desc1; 43858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration2 || interval2) { 43878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc2, 0, sizeof(desc2)); 43888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.count_type = 2; 43898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.duration = duration2; 43908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.interval = interval2; 43918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr2 = &desc2; 43928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1); 43968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(req); 43978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2); 43988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(req, len); 43998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 44018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 44028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr, 44058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *own_interface_addr, unsigned int freq, 44068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration1, u32 interval1, u32 duration2, 44078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval2) 44088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 44098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 44108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4411b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send Presence Request to GO " MACSTR 4412b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " (own interface " MACSTR ") freq=%u dur1=%u int1=%u " 4413b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "dur2=%u int2=%u", 44148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_interface_addr), MAC2STR(own_interface_addr), 44158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration1, interval1, duration2, interval2); 44168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_presence_req(duration1, interval1, duration2, 44188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interval2); 44198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 44208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 44218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 44238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr, 44248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_interface_addr, 44258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 4426b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 44278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 44298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 44318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 44328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa, 44358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t noa_len, u8 dialog_token) 44368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 44378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 44388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 44398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_alloc(100 + noa_len); 44418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 44428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 44438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token); 44458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(resp); 44468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_status(resp, status); 44478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (noa) { 44488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE); 44498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_le16(resp, noa_len); 44508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, noa, noa_len); 44518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 44528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL); 44538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(resp, len); 44548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 44568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 44578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 44608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 44618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq) 44628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 44638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 44648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 status; 44658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 44668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t g; 44678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group = NULL; 44688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int parsed = 0; 44698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 noa[50]; 44708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int noa_len; 44718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4472b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - P2P Presence Request"); 44738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 44758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]), 44768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 44778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p->groups[g]; 44788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 44798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) { 4482b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore P2P Presence Request for unknown group " 44838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(da)); 44848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 44858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 4488b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P Presence Request"); 44898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 44908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 44918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parsed = 1; 44938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.noa == NULL) { 4495b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No NoA attribute in P2P Presence Request"); 44968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 44978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 44988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len); 45018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 45038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->get_noa) 45048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa, 45058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(noa)); 45068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 45078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = -1; 45088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL, 45098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len > 0 ? noa_len : 0, 45108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token); 45118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parsed) 45128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 45138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 45148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 45178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, rx_freq, sa, da, da, 45188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 4519b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 45208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 45228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 45268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len) 45278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 45298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4530b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - P2P Presence Response"); 45318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 4533b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P Presence Response"); 45348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.status == NULL || msg.noa == NULL) { 4538b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No Status or NoA attribute in P2P Presence Response"); 45398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 45408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4543fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p->cfg->presence_resp) { 4544fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt p2p->cfg->presence_resp(p2p->cfg->cb_ctx, sa, *msg.status, 4545fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt msg.noa, msg.noa_len); 4546fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 4547fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 45488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.status) { 4549b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "P2P Presence Request was rejected: status %u", 45508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.status); 45518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 45528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4555b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "P2P Presence Request was accepted"); 45568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA", 45578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.noa, msg.noa_len); 45588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: process NoA */ 45598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 45608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx) 45648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 45668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) { 45688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Schedule next extended listen timeout */ 45698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 45708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 45718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 45728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45746dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt if ((p2p->cfg->is_p2p_in_progress && 45756dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt p2p->cfg->is_p2p_in_progress(p2p->cfg->cb_ctx)) || 45766dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt (p2p->pending_action_state == P2P_PENDING_PD && 45776dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt p2p->pd_retries > 0)) { 45785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt p2p_dbg(p2p, "Operation in progress - skip Extended Listen timeout (%s)", 45795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt p2p_state_txt(p2p->state)); 45805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 45815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 45825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 45838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) { 45848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 45858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This should not really happen, but it looks like the Listen 45868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * command may fail is something else (e.g., a scan) was 45878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * running at an inconvenient time. As a workaround, allow new 45888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen operation to be started. 45898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4590b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Previous Extended Listen operation had not been completed - try again"); 45918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 45928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 45938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) { 4596b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip Extended Listen timeout in active state (%s)", p2p_state_txt(p2p->state)); 45978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4600b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Extended Listen timeout"); 46018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 1; 46028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen(p2p, p2p->ext_listen_period) < 0) { 4603b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start Listen state for Extended Listen Timing"); 46048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 46058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ext_listen(struct p2p_data *p2p, unsigned int period, 46108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 46118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (period > 65535 || interval > 65535 || period > interval || 46138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (period == 0 && interval > 0) || (period > 0 && interval == 0)) { 4614b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Invalid Extended Listen Timing request: period=%u interval=%u", 4615b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt period, interval); 46168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 46178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 46208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (interval == 0) { 4622b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disabling Extended Listen Timing"); 46238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = 0; 46248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = 0; 46258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 46268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4628b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Enabling Extended Listen Timing: period %u msec, interval %u msec", 4629b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt period, interval); 46308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = period; 46318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = interval; 46328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_sec = interval / 1000; 46338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec = (interval % 1000) * 1000; 46348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 46368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 46378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 46388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 46408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 46448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 46458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 46478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 46498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 46508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 46528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 46538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 46549767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt if (msg.minor_reason_code == NULL) { 46559767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt p2p_parse_free(&msg); 46568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 46579767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt } 46588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4659b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Deauthentication notification BSSID " MACSTR 46608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 46618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 46628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 46648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 46688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 46698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 46718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 46738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 46748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 46768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 46778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 46789767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt if (msg.minor_reason_code == NULL) { 46799767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt p2p_parse_free(&msg); 46808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 46819767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt } 46828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4683b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disassociation notification BSSID " MACSTR 46848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 46858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 46868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 46888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_managed_oper(struct p2p_data *p2p, int enabled) 46928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 4694b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Managed P2P Device operations enabled"); 46958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED; 46968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4697b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Managed P2P Device operations disabled"); 46988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED; 46998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 47008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4703661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtint p2p_config_get_random_social(struct p2p_config *p2p, u8 *op_class, 4704661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt u8 *op_channel) 4705661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt{ 4706661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return p2p_channel_random_social(&p2p->channels, op_class, op_channel); 4707661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt} 4708661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 4709661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 471043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtint p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel, 471143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u8 forced) 47128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 47134b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(reg_class, channel) < 0) 47148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 47158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 471643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* 471743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * Listen channel was set in configuration or set by control interface; 471843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * cannot override it. 471943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt */ 4720216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->channel_forced && forced == 0) { 4721216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, 4722216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "Listen channel was previously configured - do not override based on optimization"); 472343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return -1; 4724216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 4725216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 4726216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Set Listen channel: reg_class %u channel %u", 4727216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reg_class, channel); 472843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 472943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p->state == P2P_IDLE) { 473043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->reg_class = reg_class; 473143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->channel = channel; 473243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->channel_forced = forced; 473343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } else { 473443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p_dbg(p2p, "Defer setting listen channel"); 473543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_reg_class = reg_class; 473643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_channel = channel; 473743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_channel_forced = forced; 473843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 47398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 47418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 474443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtu8 p2p_get_listen_channel(struct p2p_data *p2p) 474543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{ 474643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return p2p->cfg->channel; 474743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt} 474843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 474943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 47508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len) 47518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4752b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "New SSID postfix: %s", wpa_ssid_txt(postfix, len)); 47538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (postfix == NULL) { 47548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = 0; 47558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 47568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 47578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(p2p->cfg->ssid_postfix)) 47588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 47598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->ssid_postfix, postfix, len); 47608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = len; 47618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 47628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 476575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenint p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel, 476675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int cfg_op_channel) 476775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 47684b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(op_reg_class, op_channel) < 0) 476975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 477075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4771b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set Operating channel: reg_class %u channel %u", 4772b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt op_reg_class, op_channel); 477375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_reg_class = op_reg_class; 477475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_channel = op_channel; 477575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->cfg_op_channel = cfg_op_channel; 477675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return 0; 477775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 477875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 477975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 478004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan, 478104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const struct p2p_channel *pref_chan) 478204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 478304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct p2p_channel *n; 478404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 478504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pref_chan) { 478604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = os_malloc(num_pref_chan * sizeof(struct p2p_channel)); 478704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (n == NULL) 478804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 478904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(n, pref_chan, 479004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_pref_chan * sizeof(struct p2p_channel)); 479104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 479204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = NULL; 479304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 479404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 479504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = n; 479604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = num_pref_chan; 479704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 479804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 479904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 480004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 480104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 480268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_set_no_go_freq(struct p2p_data *p2p, 480368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct wpa_freq_range_list *list) 480468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 480568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct wpa_freq_range *tmp; 480668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 480768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (list == NULL || list->num == 0) { 480868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(p2p->no_go_freq.range); 480968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.range = NULL; 481068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.num = 0; 481168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 481268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 481368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 481468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt tmp = os_calloc(list->num, sizeof(struct wpa_freq_range)); 481568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (tmp == NULL) 481668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return -1; 481768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(tmp, list->range, list->num * sizeof(struct wpa_freq_range)); 481868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(p2p->no_go_freq.range); 481968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.range = tmp; 482068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.num = list->num; 482168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Updated no GO chan list"); 482268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 482368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 482468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 482568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 482668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 48278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr, 48288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *iface_addr) 48298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device(p2p, dev_addr); 48318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || is_zero_ether_addr(dev->interface_addr)) 48328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN); 48348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 48358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr, 48398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *dev_addr) 48408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 48428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 48438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN); 48458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 48468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr) 48508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->peer_filter, addr, ETH_ALEN); 48528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(p2p->peer_filter)) 4853b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disable peer filter"); 48548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4855b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Enable peer filter for " MACSTR, 4856b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(p2p->peer_filter)); 48578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_cross_connect(struct p2p_data *p2p, int enabled) 48618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4862b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cross connection %s", enabled ? "enabled" : "disabled"); 48638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cross_connect == enabled) 48648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 48658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect = enabled; 48668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: may need to tear down any action group where we are GO(?) */ 48678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr) 48718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 48738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 48748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) 48768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev->oper_freq; 48788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled) 48828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4883b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Intra BSS distribution %s", 48848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 48858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->p2p_intra_bss = enabled; 48868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_update_channel_list(struct p2p_data *p2p, 489068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_channels *chan, 489168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_channels *cli_chan) 48928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4893b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update channel list"); 48948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels)); 489568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); 489668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(&p2p->cfg->cli_channels, cli_chan, 489768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt sizeof(struct p2p_channels)); 489868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "cli_channels", &p2p->cfg->cli_channels); 48998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 49038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 49048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 49058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 4907b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay Action frame TX until p2p_scan completes"); 49088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 4909b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Dropped previous pending Action frame TX"); 49108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 49118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) + 49138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 49148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx == NULL) 49158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->freq = freq; 49178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN); 49188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN); 49198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN); 49208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->len = len; 49218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->wait_time = wait_time; 49228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx + 1, buf, len); 49238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 49248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, 49278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len, wait_time); 49288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, 49328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_overall) 49338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4934b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Best channel: 2.4 GHz: %d, 5 GHz: %d, overall: %d", 4935b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq_24, freq_5, freq_overall); 49368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24 = freq_24; 49378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_5 = freq_5; 49388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_overall = freq_overall; 49398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4942700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtvoid p2p_set_own_freq_preference(struct p2p_data *p2p, int freq) 4943700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 4944b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Own frequency preference: %d MHz", freq); 4945700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->own_freq_preference = freq; 4946700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 4947700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 4948700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 49498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_neg_peer(struct p2p_data *p2p) 49508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || p2p->go_neg_peer == NULL) 49528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 49538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->go_neg_peer->info.p2p_device_addr; 49548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct p2p_peer_info * 49588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtp2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next) 49598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 49618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 49638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 49648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 49658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 49668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!next) { 49688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) 49698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 49708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 49728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 49738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 49748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 49758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 49768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 49777832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (!dev || &dev->list == &p2p->devices) 49788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 49798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY); 49808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 49828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 49838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 49848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 49858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 49868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 49878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 49888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 49897832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (!dev || &dev->list == &p2p->devices) 49908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 49918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 49958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 49971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 49981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_in_progress(struct p2p_data *p2p) 49991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 50001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 50011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 5002fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p->state == P2P_SEARCH) 500361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 2; 50041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING; 50051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 500661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 500761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 500861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout, 500961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 client_timeout) 501061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 501161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p) { 501261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = go_timeout; 501361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = client_timeout; 501461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 501561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 501661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 501761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 501861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 501961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 502061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void p2p_update_wfd_ie_groups(struct p2p_data *p2p) 502161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 502261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t g; 502361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_group *group; 502461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 502561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 502661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt group = p2p->groups[g]; 5027b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt p2p_group_force_beacon_update_ies(group); 502861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 502961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 503061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 503161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 503261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_beacon(struct p2p_data *p2p, struct wpabuf *ie) 503361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 503461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 503561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_beacon = ie; 503661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 503761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 503861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 503961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 504061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 504161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_req(struct p2p_data *p2p, struct wpabuf *ie) 504261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 504361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 504461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_req = ie; 504561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 504661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 504761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 504861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 504961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_resp(struct p2p_data *p2p, struct wpabuf *ie) 505061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 505161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 505261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_resp = ie; 505361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 505461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 505561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 505661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 505761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 505861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_assoc_req(struct p2p_data *p2p, struct wpabuf *ie) 505961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 506061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 506161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_assoc_req = ie; 506261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 506361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 506461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 506561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 506661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_invitation(struct p2p_data *p2p, struct wpabuf *ie) 506761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 506861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 506961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_invitation = ie; 507061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 507161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 507261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 507361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 507461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_req(struct p2p_data *p2p, struct wpabuf *ie) 507561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 507661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 507761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_req = ie; 507861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 507961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 508061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 508161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 508261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_resp(struct p2p_data *p2p, struct wpabuf *ie) 508361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 508461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 508561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_resp = ie; 508661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 508761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 508861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 508961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 509061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_go_neg(struct p2p_data *p2p, struct wpabuf *ie) 509161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 509261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 509361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_go_neg = ie; 509461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 509561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 509661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 509761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 509861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_dev_info(struct p2p_data *p2p, const struct wpabuf *elem) 509961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 510061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 510161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 510261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = wpabuf_dup(elem); 510361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_dev_info == NULL) 510461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 510561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 510661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = NULL; 510761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 510861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 510961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 511061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 511161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 511261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_assoc_bssid(struct p2p_data *p2p, const struct wpabuf *elem) 511361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 511461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 511561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 511661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = wpabuf_dup(elem); 511761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_assoc_bssid == NULL) 511861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 511961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 512061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = NULL; 512161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 512261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 512361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 512461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 512561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 512661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p, 512761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpabuf *elem) 512861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 512961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 513061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 513161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = wpabuf_dup(elem); 513261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_coupled_sink_info == NULL) 513361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 513461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 513561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = NULL; 513661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 513761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 513861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 513961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 514061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 5141d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5142d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5143d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int, 5144d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int max_disc_tu) 5145d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 5146d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (min_disc_int > max_disc_int || min_disc_int < 0 || max_disc_int < 0) 5147d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 5148d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5149d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->min_disc_int = min_disc_int; 5150d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_int = max_disc_int; 5151d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = max_disc_tu; 5152b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set discoverable interval: min=%d max=%d max_tu=%d", 5153b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt min_disc_int, max_disc_int, max_disc_tu); 5154d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5155d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 5156d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 5157b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5158b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5159b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_dbg(struct p2p_data *p2p, const char *fmt, ...) 5160b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 5161b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 5162b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 5163b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5164b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 5165b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 5166b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5167b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 5168b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 5169b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 5170b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 5171b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_DEBUG, buf); 5172b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 5173b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5174b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5175b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_info(struct p2p_data *p2p, const char *fmt, ...) 5176b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 5177b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 5178b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 5179b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5180b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 5181b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 5182b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5183b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 5184b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 5185b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 5186b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 5187b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_INFO, buf); 5188b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 5189b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5190b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5191b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_err(struct p2p_data *p2p, const char *fmt, ...) 5192b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 5193b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 5194b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 5195b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5196b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 5197b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 5198b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5199b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 5200b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 5201b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 5202b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 5203b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_ERROR, buf); 5204b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 5205cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5206cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5207d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtvoid p2p_loop_on_known_peers(struct p2p_data *p2p, 5208d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt void (*peer_callback)(struct p2p_peer_info *peer, 5209d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt void *user_data), 5210d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt void *user_data) 5211d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{ 5212d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt struct p2p_device *dev, *n; 5213d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 5214d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 5215d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt peer_callback(&dev->info, user_data); 5216d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt } 5217d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt} 5218d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 5219d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 5220cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC 5221cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5222cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic struct wpabuf * p2p_build_nfc_handover(struct p2p_data *p2p, 5223cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int client_freq, 5224cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *go_dev_addr, 5225cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 5226cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 5227cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *buf; 5228cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 op_class, channel; 5229cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt enum p2p_role_indication role = P2P_DEVICE_NOT_IN_GROUP; 5230cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5231cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt buf = wpabuf_alloc(1000); 5232cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (buf == NULL) 5233cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 5234cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5235cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt op_class = p2p->cfg->reg_class; 5236cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt channel = p2p->cfg->channel; 5237cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5238cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 5239cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 5240cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 5241cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5242cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p->num_groups > 0) { 52437832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt int freq = p2p_group_get_freq(p2p->groups[0]); 5244cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt role = P2P_GO_IN_A_GROUP; 52457832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_class, &channel) < 0) { 52467832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt p2p_dbg(p2p, 52477832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt "Unknown GO operating frequency %d MHz for NFC handover", 52487832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt freq); 52497832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt wpabuf_free(buf); 52507832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt return NULL; 52517832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt } 5252cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (client_freq > 0) { 5253cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt role = P2P_CLIENT_IN_A_GROUP; 52547832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (p2p_freq_to_channel(client_freq, &op_class, &channel) < 0) { 52557832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt p2p_dbg(p2p, 52567832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt "Unknown client operating frequency %d MHz for NFC handover", 52577832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt client_freq); 52587832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt wpabuf_free(buf); 52597832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt return NULL; 52607832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt } 5261cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5262cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5263cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_oob_go_neg_channel(buf, p2p->cfg->country, op_class, 5264cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt channel, role); 5265cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5266cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p->num_groups > 0) { 5267cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt /* Limit number of clients to avoid very long message */ 5268cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_group_info(p2p->groups[0], buf, 5); 5269cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_group_buf_add_id(p2p->groups[0], buf); 5270cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (client_freq > 0 && 5271cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt go_dev_addr && !is_zero_ether_addr(go_dev_addr) && 5272cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid && ssid_len > 0) { 5273cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt /* 5274cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt * Add the optional P2P Group ID to indicate in which group this 5275cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt * device is a P2P Client. 5276cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt */ 5277cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_group_id(buf, go_dev_addr, ssid, ssid_len); 5278cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5279cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5280cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return buf; 5281cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 5282cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5283cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5284cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * p2p_build_nfc_handover_req(struct p2p_data *p2p, 5285cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int client_freq, 5286cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *go_dev_addr, 5287cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 5288cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 5289cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return p2p_build_nfc_handover(p2p, client_freq, go_dev_addr, ssid, 5290cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid_len); 5291cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 5292cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5293cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5294cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * p2p_build_nfc_handover_sel(struct p2p_data *p2p, 5295cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int client_freq, 5296cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *go_dev_addr, 5297cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 5298cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 5299cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return p2p_build_nfc_handover(p2p, client_freq, go_dev_addr, ssid, 5300cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid_len); 5301cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 5302cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5303cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5304cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint p2p_process_nfc_connection_handover(struct p2p_data *p2p, 5305cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_nfc_params *params) 5306cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 5307cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_message msg; 5308cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_device *dev; 5309cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *p2p_dev_addr; 5310cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int freq; 5311cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt enum p2p_role_indication role; 5312cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5313cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = NO_ACTION; 5314cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5315cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p_parse_ies_separate(params->wsc_attr, params->wsc_len, 5316cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->p2p_attr, params->p2p_len, &msg)) { 5317cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Failed to parse WSC/P2P attributes from NFC"); 5318cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(&msg); 5319cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 5320cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5321cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5322cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.p2p_device_addr) 5323cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 5324cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (msg.device_id) 5325cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dev_addr = msg.device_id; 5326cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else { 5327cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Ignore scan data without P2P Device Info or P2P Device Id"); 5328cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(&msg); 5329cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 5330cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5331cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5332cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.oob_dev_password) { 5333cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(params->oob_dev_pw, msg.oob_dev_password, 5334cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg.oob_dev_password_len); 5335cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->oob_dev_pw_len = msg.oob_dev_password_len; 5336cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5337cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5338cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 5339cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dev == NULL) { 5340cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(&msg); 5341cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 5342cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5343cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5344cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->peer = &dev->info; 5345cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5346cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_get_reltime(&dev->last_seen); 5347cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 5348cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, &msg); 5349cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5350cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!msg.oob_go_neg_channel) { 5351cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "OOB GO Negotiation Channel attribute not included"); 5352a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_parse_free(&msg); 5353cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 5354cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5355cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5356cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.oob_go_neg_channel[3] == 0 && 5357cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg.oob_go_neg_channel[4] == 0) 5358cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq = 0; 5359cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else 5360cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq = p2p_channel_to_freq(msg.oob_go_neg_channel[3], 5361cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg.oob_go_neg_channel[4]); 5362cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (freq < 0) { 5363cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Unknown peer OOB GO Neg channel"); 5364a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_parse_free(&msg); 5365cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 5366cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5367cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt role = msg.oob_go_neg_channel[5]; 5368cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5369cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (role == P2P_GO_IN_A_GROUP) { 5370cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Peer OOB GO operating channel: %u MHz", freq); 5371cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_freq = freq; 5372cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (role == P2P_CLIENT_IN_A_GROUP) { 5373cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Peer (client) OOB GO operating channel: %u MHz", 5374cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq); 5375cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_freq = freq; 5376cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else 5377cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Peer OOB GO Neg channel: %u MHz", freq); 5378cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_go_neg_freq = freq; 5379cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5380cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!params->sel && role != P2P_GO_IN_A_GROUP) { 5381cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, 5382cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->cfg->channel); 5383cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (freq < 0) { 5384cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Own listen channel not known"); 5385a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p_parse_free(&msg); 5386cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 5387cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5388cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Use own Listen channel as OOB GO Neg channel: %u MHz", freq); 5389cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_go_neg_freq = freq; 5390cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5391cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5392cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.group_id) { 5393cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(params->go_dev_addr, msg.group_id, ETH_ALEN); 5394cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_ssid_len = msg.group_id_len - ETH_ALEN; 5395cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(params->go_ssid, msg.group_id + ETH_ALEN, 5396cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_ssid_len); 5397cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5398cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5399cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 5400cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 5401717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt p2p_parse_free(&msg); 5402cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 5403cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5404cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5405cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!(dev->flags & P2P_DEV_REPORTED)) { 5406cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, p2p_dev_addr, &dev->info, 5407cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 5408cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 5409cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5410717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt p2p_parse_free(&msg); 5411cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5412cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (role == P2P_GO_IN_A_GROUP && p2p->num_groups > 0) 5413cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = BOTH_GO; 5414cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (role == P2P_GO_IN_A_GROUP) 5415cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = JOIN_GROUP; 5416cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (role == P2P_CLIENT_IN_A_GROUP) { 5417cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 5418cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = PEER_CLIENT; 5419cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (p2p->num_groups > 0) 5420cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = AUTH_JOIN; 5421cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (params->sel) 5422cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = INIT_GO_NEG; 5423cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else 5424cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = RESP_GO_NEG; 5425cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5426cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 5427cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 5428cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5429cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5430cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtvoid p2p_set_authorized_oob_dev_pw_id(struct p2p_data *p2p, u16 dev_pw_id, 5431cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int go_intent, 5432cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *own_interface_addr) 5433cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 5434cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5435cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->authorized_oob_dev_pw_id = dev_pw_id; 5436cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dev_pw_id == 0) { 5437cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "NFC OOB Password unauthorized for static handover"); 5438cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return; 5439cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 5440cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5441cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "NFC OOB Password (id=%u) authorized for static handover", 5442cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev_pw_id); 5443cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5444cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->go_intent = go_intent; 5445cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 5446cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 5447cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5448cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */ 54492271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 54502271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 54512271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidtint p2p_set_passphrase_len(struct p2p_data *p2p, unsigned int len) 54522271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt{ 54532271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (len < 8 || len > 63) 54542271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt return -1; 54552271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p->cfg->passphrase_len = len; 54562271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt return 0; 54572271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt} 54582e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 54592e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 54602e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidtvoid p2p_set_vendor_elems(struct p2p_data *p2p, struct wpabuf **vendor_elem) 54612e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt{ 54622e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt p2p->vendor_elem = vendor_elem; 54632e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt} 54646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 54656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 54666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid p2p_go_neg_wait_timeout(void *eloop_ctx, void *timeout_ctx) 54676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 54686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct p2p_data *p2p = eloop_ctx; 54696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 54706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_dbg(p2p, 54716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Timeout on waiting peer to become ready for GO Negotiation"); 54726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_go_neg_failed(p2p, -1); 54736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 5474d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 5475d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 5476d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid p2p_set_own_pref_freq_list(struct p2p_data *p2p, 5477d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const unsigned int *pref_freq_list, 5478d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int size) 5479d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 5480d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int i; 5481d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 5482d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (size > P2P_MAX_PREF_CHANNELS) 5483d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size = P2P_MAX_PREF_CHANNELS; 5484d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->num_pref_freq = size; 5485d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (i = 0; i < size; i++) { 5486d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p->pref_freq_list[i] = pref_freq_list[i]; 5487d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p_dbg(p2p, "Own preferred frequency list[%u]=%u MHz", 5488d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt i, p2p->pref_freq_list[i]); 5489d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 5490d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 5491