p2p.c revision d30ac604c9f6da71a0dd7f46d25be05a2a62cfbb
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Wi-Fi Direct - P2P module 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx); 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev); 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq); 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len); 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx); 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_scan recovery timeout 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Many drivers are using 30 second timeout on scan results. Allow a bit larger 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * timeout for this to avoid hitting P2P timeout unnecessarily. 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_SCAN_TIMEOUT 35 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P_PEER_EXPIRATION_AGE - Number of seconds after which inactive peer 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entries will be removed 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 442093d0658d2f0f8b5a98df7accc97fff3b2bb7d5Dmitry Shmidt#ifndef P2P_PEER_EXPIRATION_AGE 452093d0658d2f0f8b5a98df7accc97fff3b2bb7d5Dmitry Shmidt#define P2P_PEER_EXPIRATION_AGE 60 461846323989242844f0e857458a8939fa5836429cDmitry Shmidt#endif /* P2P_PEER_EXPIRATION_AGE */ 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_PEER_EXPIRATION_INTERVAL (P2P_PEER_EXPIRATION_AGE / 2) 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expire_peers(struct p2p_data *p2p) 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *n; 53fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now; 54c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t i; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec) 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 60c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 619e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt if (dev == p2p->go_neg_peer) { 629e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt /* 639e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * GO Negotiation is in progress with the peer, so 649e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * don't expire the peer entry until GO Negotiation 659e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * fails or times out. 669e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt */ 679e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt continue; 689e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt } 699e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt 70c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->cfg->go_connected && 71c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->cfg->go_connected(p2p->cfg->cb_ctx, 72c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt dev->info.p2p_device_addr)) { 73c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 74c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * We are connected as a client to a group in which the 75c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * peer is the GO, so do not expire the peer entry. 76c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 77fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 78c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 79c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 80c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 81c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 82c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p_group_is_client_connected( 83c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->groups[i], dev->info.p2p_device_addr)) 84c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt break; 85c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 86c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (i < p2p->num_groups) { 87c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 88c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * The peer is connected as a client in a group where 89c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * we are the GO, so do not expire the peer entry. 90c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 91fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 92c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 93c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 94c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 95b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Expiring old peer entry " MACSTR, 96b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_expiration_timeout(void *eloop_ctx, void *timeout_ctx) 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expire_peers(p2p); 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_state_txt(int state) 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SEARCH"; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT"; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECT_LISTEN"; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "GO_NEG"; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "LISTEN_ONLY"; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_CONNECT"; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "WAIT_PEER_IDLE"; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SD_DURING_FIND"; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PROVISIONING"; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PD_DURING_FIND"; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE"; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INVITE_LISTEN"; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "?"; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 147b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidtconst char * p2p_get_state_txt(struct p2p_data *p2p) 148b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt{ 149b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return p2p_state_txt(p2p->state); 150b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt} 151b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 152b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!addr || !p2p) 1581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return dev->wps_prov_info; 1631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 1641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 16804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr) 1691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev = NULL; 1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!addr || !p2p) 1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 1741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev = p2p_get_device(p2p, addr); 1761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev) 1771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 1781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_state(struct p2p_data *p2p, int new_state) 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 183b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "State %s -> %s", 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), p2p_state_txt(new_state)); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->state = new_state; 18643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 18743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (new_state == P2P_IDLE && p2p->pending_channel) { 18843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p_dbg(p2p, "Apply change in listen channel"); 18943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->reg_class = p2p->pending_reg_class; 19043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->channel = p2p->pending_channel; 19143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_reg_class = 0; 19243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_channel = 0; 19343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec) 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 199b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set timeout (state=%s): %u.%06u sec", 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state), sec, usec); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_clear_timeout(struct p2p_data *p2p) 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 208b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Clear timeout (state=%s)", p2p_state_txt(p2p->state)); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_state_timeout, p2p, NULL); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer, 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int status) 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 2198c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer) { 2208c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 2211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->go_neg_peer->wps_method = WPS_NOT_READY; 222cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->go_neg_peer->oob_pw_id = 0; 2238c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.status = status; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer) { 229413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_free(peer->go_neg_conf); 230413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt peer->go_neg_conf = NULL; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 240d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r, tu; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 246b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting short listen state (state=%s)", 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_state_txt(p2p->state)); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2493c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt if (p2p->pending_listen_freq) { 2503c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt /* We have a pending p2p_listen request */ 2513c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p_dbg(p2p, "p2p_listen command pending already"); 2523c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt return; 2533c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt } 2543c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 2554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 257b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) + 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int) * 100; 264d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu) 265d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->max_disc_tu; 266d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!dev_disc && tu < 100) 267d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = 100; /* Need to wait in non-device discovery use cases */ 268d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen) 269d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tu = p2p->cfg->max_listen * 1000 / 1024; 270d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 271d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (tu == 0) { 272b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip listen state since duration was 0 TU"); 273d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_set_timeout(p2p, 0, 0); 274d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 275d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2813c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_freq = freq; 2823c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_sec = 0; 2833c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_usec = 1024 * tu; 2843c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000, 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies) < 0) { 287b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start listen mode"); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen(struct p2p_data *p2p, unsigned int timeout) 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 299b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Going to listen(only) state"); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3013c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt if (p2p->pending_listen_freq) { 3023c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt /* We have a pending p2p_listen request */ 3033c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p_dbg(p2p, "p2p_listen command pending already"); 3043c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt return -1; 3053c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt } 3063c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 3074b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 309b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec = timeout / 1000; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec = (timeout % 1000) * 1000; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 31704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) { 318b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - connect is already pending - skip listen"); 3191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 3201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 321b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - delay start of listen state"); 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_LISTEN; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3303c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_freq = freq; 3313c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { 333b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start listen mode"); 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_LISTEN_ONLY); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_clear_reported(struct p2p_data *p2p) 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_REPORTED; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device - Fetch a peer entry 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr) 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->info.p2p_device_addr, addr, ETH_ALEN) == 0) 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_get_device_interface - Fetch a peer entry based on P2P Interface Address 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Interface Address of the peer 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL if not found 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev->interface_addr, addr, ETH_ALEN) == 0) 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_create_device - Create a peer entry 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: P2P Device Address of the peer 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the device entry or %NULL on failure 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If there is already an entry for the peer, it will be returned instead of 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * creating a new one. 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_device * p2p_create_device(struct p2p_data *p2p, 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr) 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *oldest = NULL; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count = 0; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oldest == NULL || 411fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_reltime_before(&dev->last_seen, &oldest->last_seen)) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldest = dev; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count + 1 > p2p->cfg->max_peers && oldest) { 415b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Remove oldest peer entry to make room for a new peer"); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&oldest->list); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, oldest); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = os_zalloc(sizeof(*dev)); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&p2p->devices, &dev->list); 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_copy_client_info(struct p2p_device *dev, 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli) 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, cli->dev_name, cli->dev_name_len); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name[cli->dev_name_len] = '\0'; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab = cli->dev_capab; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.config_methods = cli->config_methods; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_interface_addr, int freq, 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *gi, size_t gi_len) 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t c; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Clear old data for this group; if the devices are still in the 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group, the information will be restored in the loop following this. 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(dev->member_in_go_iface, go_interface_addr, 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_iface, 0, ETH_ALEN); 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->member_in_go_dev, 0, ETH_ALEN); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (c = 0; c < info.num_clients; c++) { 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli = &info.client[c]; 4721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(cli->p2p_device_addr, p2p->cfg->dev_addr, 4731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ETH_ALEN) == 0) 4741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; /* ignore our own entry */ 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, cli->p2p_device_addr); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY | 47804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_PROBE_REQ_ONLY)) { 47904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 48004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Update information since we have not 48104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * received this directly from the client. 48204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 48404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 48504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 48604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Need to update P2P Client Discoverability 48704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * flag since it is valid only in P2P Group 48804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Info attribute. 48904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 49004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= 49104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 49204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= 49304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cli->dev_capab & 49404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 49504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, cli->p2p_device_addr); 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_copy_client_info(dev, cli); 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq = freq; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.p2p_device_addr, 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &dev->info, 1); 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, cli->p2p_interface_addr, 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 514fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN); 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->member_in_go_iface, go_interface_addr, 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 524b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, 525b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt int probe_req, const struct p2p_message *msg) 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.device_name, msg->device_name, 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.device_name)); 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->manufacturer && 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len < sizeof(dev->info.manufacturer)) { 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.manufacturer, 0, 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.manufacturer)); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.manufacturer, msg->manufacturer, 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len); 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_name && 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len < sizeof(dev->info.model_name)) { 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_name, 0, 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_name)); 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_name, msg->model_name, 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len); 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->model_number && 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len < sizeof(dev->info.model_number)) { 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.model_number, 0, 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.model_number)); 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.model_number, msg->model_number, 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->serial_number && 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len < sizeof(dev->info.serial_number)) { 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(dev->info.serial_number, 0, 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.serial_number)); 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.serial_number, msg->serial_number, 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len); 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->pri_dev_type) 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->pri_dev_type, 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg->wps_pri_dev_type) 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.pri_dev_type, msg->wps_pri_dev_type, 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dev->info.pri_dev_type)); 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_sec_dev_type_list) { 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->info.wps_sec_dev_type_list, 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list, 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len); 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_sec_dev_type_list_len = 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->capability) { 57804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 57904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * P2P Client Discoverability bit is reserved in all frames 58004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * that use this function, so do not change its value here. 58104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 58204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 58304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->info.dev_capab |= msg->capability[0] & 58404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab = msg->capability[1]; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->ext_listen_timing) { 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing); 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval = 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing + 2); 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 59304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!probe_req) { 595f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt u16 new_config_methods; 596f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt new_config_methods = msg->config_methods ? 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_methods : msg->wps_config_methods; 598f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (new_config_methods && 599f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods != new_config_methods) { 600b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update peer " MACSTR 601b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " config_methods 0x%x -> 0x%x", 602b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 603b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt dev->info.config_methods, 604b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt new_config_methods); 605f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt dev->info.config_methods = new_config_methods; 606f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 61204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * p2p_add_device - Add peer entries based on scan results or P2P frames 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Source address of Beacon or Probe Response frame (may be either 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Address or P2P Interface Address) 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @level: Signal level (signal strength of the received frame from the peer) 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency on which the Beacon or Probe Response frame was received 618f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @rx_time: Time when the result was received 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies: IEs from the Beacon or Probe Response frame 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ies_len: Length of ies buffer in octets 62104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @scan_res: Whether this was based on scan results 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If the scan result is for a GO, the clients in the group will also be added 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the peer table. This function can also be used with some other frames 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * like Provision Discovery Request that contains P2P Capability and P2P Device 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Info attributes. 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 629a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtint p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, 630fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime *rx_time, int level, const u8 *ies, 631a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len, int scan_res) 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *p2p_dev_addr; 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 637fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime time_now; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ies, ies_len, &msg)) { 641b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P IE for a device entry"); 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (msg.device_id) 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_addr = msg.device_id; 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 651b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore scan data without P2P Device Info or P2P Device Id"); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(p2p->peer_filter) && 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(p2p_dev_addr, p2p->peer_filter, ETH_ALEN) != 0) { 658b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not add peer filter for " MACSTR 659b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " due to peer filter", MAC2STR(p2p_dev_addr)); 660a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 669a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 670f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (rx_time == NULL) { 671fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&time_now); 672f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt rx_time = &time_now; 673f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 674a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 675a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 676a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Update the device entry only if the new peer 677a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * entry is newer than the one previously stored. 678a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 679f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->last_seen.sec > 0 && 680fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_reltime_before(rx_time, &dev->last_seen)) { 681b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not update peer entry based on old frame (rx_time=%u.%06u last_seen=%u.%06u)", 682f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->sec, 683f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec, 684f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) dev->last_seen.sec, 685f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) dev->last_seen.usec); 686a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_parse_free(&msg); 687a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 688a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 689a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 690fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_reltime)); 691a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0) 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->interface_addr, addr, ETH_ALEN); 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid && 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0)) { 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->oper_ssid, msg.ssid + 2, msg.ssid[1]); 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len = msg.ssid[1]; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 2412 && freq <= 2484 && msg.ds_params && 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.ds_params >= 1 && *msg.ds_params <= 14) { 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ds_freq; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.ds_params == 14) 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2484; 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ds_freq = 2407 + *msg.ds_params * 5; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != ds_freq) { 712b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update Listen frequency based on DS Parameter Set IE: %d -> %d MHz", 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, ds_freq); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = ds_freq; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 71804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (dev->listen_freq && dev->listen_freq != freq && scan_res) { 719b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update Listen frequency based on scan results (" 720b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " %d -> %d MHz (DS param %d)", 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->listen_freq, 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, msg.ds_params ? *msg.ds_params : -1); 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 72404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 72504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->listen_freq = freq; 72604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.group_info) 72704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->oper_freq = freq; 72804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 72975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.level = level; 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 731b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, &msg); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_vendor_ext[i] == NULL) 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = wpabuf_alloc_copy( 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_vendor_ext[i], msg.wps_vendor_ext_len[i]); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->info.wps_vendor_ext[i] == NULL) 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 74761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 74861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 74961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 75061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 75161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 75204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (scan_res) { 75304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_add_group_clients(p2p, p2p_dev_addr, addr, freq, 75404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_info, msg.group_info_len); 75504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_REPORTED) 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 762b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer found with Listen frequency %d MHz (rx_time=%u.%06u)", 763b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq, (unsigned int) rx_time->sec, 764f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec); 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 766b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 770f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (dev->info.config_methods == 0 && 771f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (freq == 2412 || freq == 2437 || freq == 2462)) { 772f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 773f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * If we have only seen a Beacon frame from a GO, we do not yet 774f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * know what WPS config methods it supports. Since some 775f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * applications use config_methods value from P2P-DEVICE-FOUND 776f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * events, postpone reporting this peer until we've fully 777f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * discovered its capabilities. 778f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * 779f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * At least for now, do this only if the peer was detected on 780f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * one of the social channels since that peer can be easily be 781f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * found again and there are no limitations of having to use 782f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * passive scan on this channels, so this can be done through 783f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Probe Response frame that includes the config_methods 784f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * information. 785f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 786b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report peer " MACSTR 787b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " with unknown config methods", MAC2STR(addr)); 788f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 789f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 790f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 803497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt if (p2p->go_neg_peer == dev) { 8041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 8051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * If GO Negotiation is in progress, report that it has failed. 8061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 807497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 809497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt } 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == dev) 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == dev) 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_client_disc_go == dev) 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_go = NULL; 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 817c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt /* dev_lost() device, but only if it was previously dev_found() */ 818c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (dev->flags & P2P_DEV_REPORTED_ONCE) 819c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt p2p->cfg->dev_lost(p2p->cfg->cb_ctx, 820c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt dev->info.p2p_device_addr); 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(dev->info.wps_vendor_ext[i]); 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.wps_vendor_ext[i] = NULL; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 82761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 828413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_free(dev->go_neg_conf); 82961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dev); 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_get_next_prog_freq(struct p2p_data *p2p) 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *c; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *cla; 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t cl, ch; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 reg_class; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = &p2p->cfg->channels; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cl = 0; cl < c->reg_classes; cl++) { 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla = &c->reg_class[cl]; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->reg_class != p2p->last_prog_scan_class) 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = 0; ch < cla->channels; ch++) { 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cla->channel[ch] == p2p->last_prog_scan_chan) { 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found) 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start from beginning */ 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[0].reg_class; 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[0].channel[0]; 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Pick the next channel */ 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch++; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ch == cla->channels) { 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl++; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cl == c->reg_classes) 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cl = 0; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ch = 0; 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class = c->reg_class[cl].reg_class; 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt channel = c->reg_class[cl].channel[ch]; 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8764b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(reg_class, channel); 877b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Next progressive search channel: reg_class %u channel %u -> %d MHz", 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg_class, channel, freq); 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_class = reg_class; 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->last_prog_scan_chan = channel; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2412 || freq == 2437 || freq == 2462) 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* No need to add social channels */ 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return freq; 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_search(struct p2p_data *p2p) 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq = 0; 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_scan_type type; 89204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 pw_id = DEV_PW_DEFAULT; 89361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int res; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 896b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver is still in Listen state - wait for it to end before continuing"); 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 90104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->find_type == P2P_FIND_PROGRESSIVE && 90204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (freq = p2p_get_next_prog_freq(p2p)) > 0) { 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL_PLUS_ONE; 904b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting search (+ freq %u)", freq); 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = P2P_SCAN_SOCIAL; 907b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting search"); 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 91061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq, 91161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->num_req_dev_types, p2p->req_dev_types, 91261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->find_dev_id, pw_id); 91361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0) { 914b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Scan request failed"); 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 917b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Running p2p_scan"); 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_find_timeout(void *eloop_ctx, void *timeout_ctx) 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 929b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Find timeout -> stop"); 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_run_after_scan(struct p2p_data *p2p) 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_after_scan op; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 9408da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 1; 941b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Action frame at p2p_scan completion"); 9421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->cfg->send_action(p2p->cfg->cb_ctx, 9431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->freq, 9441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->dst, 9451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->src, 9461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->bssid, 9471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (u8 *) (p2p->after_scan_tx + 1), 9481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->len, 9491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->after_scan_tx->wait_time); 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op = p2p->start_after_scan; 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (op) { 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_NOTHING: 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_LISTEN: 961b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start previously requested Listen state"); 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen(p2p, p2p->pending_listen_sec * 1000 + 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec / 1000); 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_AFTER_SCAN_CONNECT: 966b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start previously requested connect with " MACSTR, 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->after_scan_peer)); 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, p2p->after_scan_peer); 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 970b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer not known anymore"); 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, dev); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx) 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int running; 985b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan timeout (running=%d)", p2p->p2p_scan_running); 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt running = p2p->p2p_scan_running; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we recover from missed scan results callback */ 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (running) 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_run_after_scan(p2p); 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_free_req_dev_types(struct p2p_data *p2p) 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = 0; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->req_dev_types); 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = NULL; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_find(struct p2p_data *p2p, unsigned int timeout, 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 1005c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types, 100661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *dev_id, unsigned int search_delay) 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1010b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting find (type=%d)", type); 1011fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&p2p->find_start); 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 1013b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan is already running"); 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req_dev_types && num_req_dev_types) { 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->req_dev_types = os_malloc(num_req_dev_types * 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->req_dev_types == NULL) 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->req_dev_types, req_dev_types, 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types * WPS_DEV_TYPE_LEN); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types = num_req_dev_types; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1027c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) { 1028c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN); 1029c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = p2p->find_dev_id_buf; 1030c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else 1031c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->find_dev_id = NULL; 1032c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->find_type = type; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_clear_reported(p2p); 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 103961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay = search_delay; 104061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 10421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->last_p2p_find_timeout = timeout; 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout) 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, p2p_find_timeout, 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_START_WITH_FULL: 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_PROGRESSIVE: 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 105104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 105204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_FIND_ONLY_SOCIAL: 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0, 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->num_req_dev_types, 105704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->req_dev_types, dev_id, 105804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT); 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) { 1065b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Running p2p_scan"); 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 1; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout, 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, NULL); 1070fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else if (p2p->p2p_scan_running) { 1071fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt p2p_dbg(p2p, "Failed to start p2p_scan - another p2p_scan was already running"); 1072fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt /* wait for the previous p2p_scan to complete */ 107396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt res = 0; /* do not report failure */ 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1075b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start p2p_scan"); 10761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 10771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find_for_freq(struct p2p_data *p2p, int freq) 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1086b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Stopping find"); 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_find_timeout, p2p, NULL); 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 1089fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p->state == P2P_SEARCH) 1090b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->find_stopped(p2p->cfg->cb_ctx); 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 10948c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer) 10958c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE; 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer = NULL; 109904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_listen_for_freq(p2p, freq); 110004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 110104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 110204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 110304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq) 110404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) { 1106b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip stop_listen since we are on correct channel for response"); 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 110904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->in_listen) { 111004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->in_listen = 0; 111104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_clear_timeout(p2p); 111204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 11131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p->drv_in_listen) { 11141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 11151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * The driver may not deliver callback to p2p_listen_end() 11161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * when the operation gets canceled, so clear the internal 11171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * variable that is tracking driver state. 11181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 1119b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Clear drv_in_listen (%d)", p2p->drv_in_listen); 11201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->drv_in_listen = 0; 11211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1126391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid p2p_stop_listen(struct p2p_data *p2p) 1127391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 1128391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p->state != P2P_LISTEN_ONLY) { 1129391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dbg(p2p, "Skip stop_listen since not in listen_only state."); 1130391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 1131391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 1132391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1133391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_stop_listen_for_freq(p2p, 0); 1134391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 1135391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 1136391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1137391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_stop_find(struct p2p_data *p2p) 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11403c57b3f85a2d1d586b8b42014a806df23d309824Dmitry Shmidt p2p->pending_listen_freq = 0; 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find_for_freq(p2p, 0); 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1145a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int p2p_prepare_channel_pref(struct p2p_data *p2p, 1146a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int force_freq, 114768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt unsigned int pref_freq, int go) 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1149a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1150a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int freq = force_freq ? force_freq : pref_freq; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 115268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Prepare channel pref - force_freq=%u pref_freq=%u go=%d", 115368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt force_freq, pref_freq, go); 11544b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_class, &op_channel) < 0) { 1155b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported frequency %u MHz", freq); 1156a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1157a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1158a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 115968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (!p2p_channels_includes(&p2p->cfg->channels, op_class, op_channel) && 116068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt (go || !p2p_channels_includes(&p2p->cfg->cli_channels, op_class, 116168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel))) { 1162b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Frequency %u MHz (oper_class %u channel %u) not allowed for P2P", 1163b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq, op_class, op_channel); 1164a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1165a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1166a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1167a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1168a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1170a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) { 1171a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_classes = 1; 1172a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channels = 1; 1173a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; 1174a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->channels.reg_class[0].channel[0] = p2p->op_channel; 1175a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct p2p_channels)); 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1179a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1180a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 1181a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1182a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1183a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1184a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void p2p_prepare_channel_best(struct p2p_data *p2p) 1185a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 1186a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 op_class, op_channel; 1187a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt const int op_classes_5ghz[] = { 124, 115, 0 }; 1188a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt const int op_classes_ht40[] = { 126, 127, 116, 117, 0 }; 1189e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt const int op_classes_vht[] = { 128, 0 }; 1190a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1191b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Prepare channel best"); 1192b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1193a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!p2p->cfg->cfg_op_channel && p2p->best_freq_overall > 0 && 1194a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_overall) && 11954b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_overall, &op_class, &op_channel) 11964b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt == 0) { 1197b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best overall channel as operating channel preference"); 1198a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1199a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1200a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_5 > 0 && 1201a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_5) && 12024b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_5, &op_class, &op_channel) 12034b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt == 0) { 1204b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best 5 GHz channel as operating channel preference"); 1205a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1206a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1207a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else if (!p2p->cfg->cfg_op_channel && p2p->best_freq_24 > 0 && 1208a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_supported_freq(p2p, p2p->best_freq_24) && 12094b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_freq_to_channel(p2p->best_freq_24, &op_class, 12104b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt &op_channel) == 0) { 1211b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Select best 2.4 GHz channel as operating channel preference"); 1212a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = op_class; 1213a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = op_channel; 1214b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt } else if (p2p->cfg->num_pref_chan > 0 && 1215b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_channels_includes(&p2p->cfg->channels, 1216b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->cfg->pref_chan[0].op_class, 1217b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->cfg->pref_chan[0].chan)) { 1218b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Select first pref_chan entry as operating channel preference"); 1219b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->op_reg_class = p2p->cfg->pref_chan[0].op_class; 1220b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p->op_channel = p2p->cfg->pref_chan[0].chan; 1221e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht, 1222e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &p2p->op_reg_class, &p2p->op_channel) == 1223e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 0) { 1224e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p_dbg(p2p, "Select possible VHT channel (op_class %u channel %u) as operating channel preference", 1225e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1226e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_ht40, 1227e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &p2p->op_reg_class, &p2p->op_channel) == 1228e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 0) { 1229e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p_dbg(p2p, "Select possible HT40 channel (op_class %u channel %u) as operating channel preference", 1230e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1231e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_5ghz, 1232e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &p2p->op_reg_class, &p2p->op_channel) == 1233e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 0) { 1234e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p_dbg(p2p, "Select possible 5 GHz channel (op_class %u channel %u) as operating channel preference", 1235e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->op_reg_class, p2p->op_channel); 1236d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt } else if (p2p_channels_includes(&p2p->cfg->channels, 1237d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->cfg->op_reg_class, 1238d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->cfg->op_channel)) { 1239b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_dbg(p2p, "Select pre-configured channel as operating channel preference"); 1240a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_reg_class = p2p->cfg->op_reg_class; 1241a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p->op_channel = p2p->cfg->op_channel; 1242d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt } else if (p2p_channel_random_social(&p2p->cfg->channels, 1243d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_reg_class, 1244d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_channel) == 0) { 1245d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p_dbg(p2p, "Select random available social channel %d from 2.4 GHz band as operating channel preference", 1246d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->op_channel); 1247d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt } else { 1248d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt /* Select any random available channel from the first available 1249d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt * operating class */ 1250d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p_channel_select(&p2p->cfg->channels, NULL, 1251d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_reg_class, 1252d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt &p2p->op_channel); 1253d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p_dbg(p2p, "Select random available channel %d from operating class %d as operating channel preference", 1254d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt p2p->op_channel, p2p->op_reg_class); 1255a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1256a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1257a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(&p2p->channels, &p2p->cfg->channels, 1258a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(struct p2p_channels)); 1259a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1260a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1261a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1262a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1263a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * p2p_prepare_channel - Select operating channel for GO Negotiation 1264a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @p2p: P2P module context from p2p_init() 1265a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @dev: Selected peer device 1266a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @force_freq: Forced frequency in MHz or 0 if not forced 1267a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @pref_freq: Preferred frequency in MHz or 0 if no preference 126868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @go: Whether the local end will be forced to be GO 1269a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 on success, -1 on failure (channel not supported for P2P) 1270a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1271a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is used to do initial operating channel selection for GO 1272a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Negotiation prior to having received peer information. The selected channel 1273a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * may be further optimized in p2p_reselect_channel() once the peer information 1274a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * is available. 1275a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 12767a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtint p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev, 127768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt unsigned int force_freq, unsigned int pref_freq, int go) 1278a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 127968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Prepare channel - force_freq=%u pref_freq=%u go=%d", 128068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt force_freq, pref_freq, go); 1281a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq || pref_freq) { 128268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_prepare_channel_pref(p2p, force_freq, pref_freq, go) < 128368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 0) 1284a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1285a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 1286a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p2p_prepare_channel_best(p2p); 1287a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 128868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "prepared channels", &p2p->channels); 128968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (go) 129068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_remove_freqs(&p2p->channels, &p2p->no_go_freq); 129168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt else if (!force_freq) 129268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_union(&p2p->channels, &p2p->cfg->cli_channels, 129368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt &p2p->channels); 129468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "after go/cli filter/add", &p2p->channels); 129568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 1296b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Own preference for operation channel: Operating Class %u Channel %u%s", 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_reg_class, p2p->op_channel, 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq ? " (forced)" : ""); 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1300a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (force_freq) 1301a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags |= P2P_DEV_FORCE_FREQ; 1302a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else 1303a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->flags &= ~P2P_DEV_FORCE_FREQ; 1304a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_set_dev_persistent(struct p2p_device *dev, 13101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int persistent_group) 13111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 13121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (persistent_group) { 13131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 0: 13141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~(P2P_DEV_PREFER_PERSISTENT_GROUP | 13151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN); 13161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 1: 13181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP; 13191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags &= ~P2P_DEV_PREFER_PERSISTENT_RECONN; 13201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 2: 13221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->flags |= P2P_DEV_PREFER_PERSISTENT_GROUP | 13231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt P2P_DEV_PREFER_PERSISTENT_RECONN; 13241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 13251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 13261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 13271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 13281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 133204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 133304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1334cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int pd_before_go_neg, unsigned int pref_freq, u16 oob_pw_id) 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 1340cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt " wps_method=%d persistent_group=%d pd_before_go_neg=%d " 1341cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "oob_pw_id=%u", 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1343cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_method, persistent_group, pd_before_go_neg, oob_pw_id); 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 1347b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to unknown P2P Device " MACSTR, 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 135268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq, 135368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt go_intent == 15) < 0) 1354a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1355a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 1359b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) { 1365b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with incomplete information", 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * First, try to connect directly. If the peer does not 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * acknowledge frames, assume it is sleeping and use device 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * discoverability via the GO at that point. 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 137804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 137904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 138004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 138104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 138204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 138304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 138404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 138504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 138604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 139104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pd_before_go_neg) 139204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG; 1393a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else { 139404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 1395a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 13969cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * Assign dialog token and tie breaker here to use the same 13979cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt * values in each retry within the same GO Negotiation exchange. 1398a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 1399a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token++; 1400a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (dev->dialog_token == 0) 1401a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token = 1; 14029cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt dev->tie_breaker = p2p->next_tie_breaker; 14039cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt p2p->next_tie_breaker = !p2p->next_tie_breaker; 1404a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->connect_reqs = 0; 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 14081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(p2p); 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We need to drop the pending frame to avoid issues with the 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new GO Negotiation, e.g., when the pending frame was from a 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previous attempt at starting a GO Negotiation. 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1421b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Dropped previous pending Action frame TX that was waiting for p2p_scan completion"); 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 1427cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_pw_id = oob_pw_id; 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 1431b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan running - delay connect send"); 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT; 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN); 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect_send(p2p, dev); 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 144504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 1446d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const u8 *force_ssid, size_t force_ssid_len, 1447cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt unsigned int pref_freq, u16 oob_pw_id) 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1451b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " GO Intent=%d Intended Interface Address=" MACSTR 1453cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt " wps_method=%d persistent_group=%d oob_pw_id=%u", 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), 1455cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_method, persistent_group, oob_pw_id); 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 1459b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot authorize unknown P2P Device " MACSTR, 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 146468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq, go_intent == 146568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 15) < 0) 1466a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 1467a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 146804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 0; 146904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (force_ssid) { 147004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID", 147104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt force_ssid, force_ssid_len); 147204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->ssid, force_ssid, force_ssid_len); 147304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_len = force_ssid_len; 147404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->ssid_set = 1; 147504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 147604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_NOT_YET_READY; 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_USER_REJECTED; 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent = 0; 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_state = UNKNOWN_GO; 14811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_set_dev_persistent(dev, persistent_group); 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_intent = go_intent; 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = wps_method; 1486cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_pw_id = oob_pw_id; 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_SUCCESS; 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, struct p2p_message *msg) 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1496fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, msg); 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->listen_channel) { 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 15024b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(msg->listen_channel[3], 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 1505b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown peer Listen channel: " 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c(0x%02x) reg_class=%u channel=%u", 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[0], 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[1], 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[2], 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[3], 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel[4]); 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1513b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update peer " MACSTR 1514b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " Listen channel: %u -> %u MHz", 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, freq); 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq = freq; 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 152161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg->wfd_subelems) { 152261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 152361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems); 152461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 152561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY; 1528b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Completed device entry based on data from GO Negotiation Request"); 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1530b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Created device entry based on GO Neg Req: " 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " dev_capab=0x%x group_capab=0x%x name='%s' " 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d", 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.dev_capab, dev->info.group_capab, 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.device_name, dev->listen_freq); 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_GROUP_CLIENT_ONLY; 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 1541b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, addr, &dev->info, 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len) 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_random((char *) &ssid[P2P_WILDCARD_SSID_LEN], 2); 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&ssid[P2P_WILDCARD_SSID_LEN + 2], 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix, p2p->cfg->ssid_postfix_len); 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *ssid_len = P2P_WILDCARD_SSID_LEN + 2 + p2p->cfg->ssid_postfix_len; 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_ssid(p2p, params->ssid, ¶ms->ssid_len); 15642271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p_random(params->passphrase, p2p->cfg->passphrase_len); 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go = peer->go_state == LOCAL_GO; 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels intersection; 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freqs; 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1577b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation with " MACSTR " completed (%s will be GO)", 1578b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(peer->info.p2p_device_addr), go ? "local end" : "peer"); 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.role_go = go; 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr, ETH_ALEN); 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, peer->intended_addr, ETH_ALEN); 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = peer->wps_method; 15851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP) { 15861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (peer->flags & P2P_DEV_PREFER_PERSISTENT_RECONN) 15871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 2; 15881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 15891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res.persistent_group = 1; 15901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Setup AP mode for WPS provisioning */ 15944b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt res.freq = p2p_channel_to_freq(p2p->op_reg_class, 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->op_channel); 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 15982271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p_random(res.passphrase, p2p->cfg->passphrase_len); 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq = peer->oper_freq; 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ssid_len) { 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.ssid, p2p->ssid, p2p->ssid_len); 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.ssid_len = p2p->ssid_len; 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 160768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "own channels", &p2p->channels); 160868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "peer channels", &peer->channels); 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_channels_intersect(&p2p->channels, &peer->channels, 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &intersection); 161168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (go) { 161268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_remove_freqs(&intersection, &p2p->no_go_freq); 161368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "intersection after no-GO removal", 161468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt &intersection); 161568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freqs = 0; 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < intersection.reg_classes; i++) { 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *c = &intersection.reg_class[i]; 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < c->channels; j++) { 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freqs + 1 == P2P_MAX_CHANNELS) 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16254b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(c->reg_class, c->channel[j]); 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.freq_list[freqs++] = freq; 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.peer_config_timeout = go ? peer->client_timeout : peer->go_timeout; 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 16351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p->ssid_set = 0; 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->go_neg_req_sent = 0; 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer->wps_method = WPS_NOT_READY; 1638cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt peer->oob_pw_id = 0; 1639413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_free(peer->go_neg_conf); 1640413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt peer->go_neg_conf = NULL; 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PROVISIONING); 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1650b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "RX P2P Public Action from " MACSTR, MAC2STR(sa)); 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Public Action contents", data, len); 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_REQ: 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_RESP: 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG_CONF: 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1); 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_REQ: 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_req(p2p, sa, data + 1, len - 1, 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_freq); 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITATION_RESP: 1671051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_REQ: 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROV_DISC_RESP: 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1); 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_REQ: 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_DEV_DISC_RESP: 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_dev_disc_resp(p2p, sa, data + 1, len - 1); 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1687b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported P2P Public Action frame type %d", 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_rx_action_public(struct p2p_data *p2p, const u8 *da, 16951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *sa, const u8 *bssid, const u8 *data, 16961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int freq) 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_VENDOR_SPECIFIC: 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data++; 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 1705a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (len < 4) 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1707a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (WPA_GET_BE32(data) != P2P_IE_VENDOR_TYPE) 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1710a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt data += 4; 1711a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt len -= 4; 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1713a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt p2p_rx_p2p_action(p2p, sa, data, len, freq); 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_REQ: 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_req(p2p, sa, data + 1, len - 1, freq); 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_INITIAL_RESP: 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_initial_resp(p2p, sa, data + 1, len - 1, freq); 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_REQ: 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_req(p2p, sa, data + 1, len - 1, freq); 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_PA_GAS_COMEBACK_RESP: 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_gas_comeback_resp(p2p, sa, data + 1, len - 1, freq); 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u8 category, 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int freq) 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category == WLAN_ACTION_PUBLIC) { 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action_public(p2p, da, sa, bssid, data, len, freq); 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (category != WLAN_ACTION_VENDOR_SPECIFIC) 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 4) 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1746a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (WPA_GET_BE32(data) != P2P_IE_VENDOR_TYPE) 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1748a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt data += 4; 1749a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt len -= 4; 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P action frame */ 1752b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "RX P2P Action from " MACSTR, MAC2STR(sa)); 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: P2P Action contents", data, len); 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data[0]) { 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NOA: 1759b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - Notice of Absence"); 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_REQ: 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_req(p2p, da, sa, data + 1, len - 1, freq); 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PRESENCE_RESP: 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_presence_resp(p2p, da, sa, data + 1, len - 1); 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_DISC_REQ: 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_process_go_disc_req(p2p, da, sa, data + 1, len - 1, freq); 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1772b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - unknown type %u", data[0]); 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx) 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status = P2P_SC_SUCCESS; 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_invite_start(void *eloop_ctx, void *timeout_ctx) 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer == NULL) 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->stop_listen(p2p->cfg->cb_ctx); 1795cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr, 1796cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->invite_dev_pw_id); 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0 || msg.p2p_attributes == NULL) 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* not a P2P probe */ 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.ssid == NULL || msg.ssid[1] != P2P_WILDCARD_SSID_LEN || 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(msg.ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0) { 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* The Probe Request is not part of P2P Device Discovery. It is 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not known whether the source address of the frame is the P2P 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Device Address or P2P Interface Address. Do not add a new 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer entry based on this frames. 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->country[0] == 0 && msg.listen_channel) 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 1829fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* already known */ 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1840fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PROBE_REQ_ONLY; 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.listen_channel) { 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev->country, msg.listen_channel, 3); 18454b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->listen_freq = p2p_channel_to_freq(msg.listen_channel[3], 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.listen_channel[4]); 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1849b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_copy_wps_info(p2p, dev, 1, &msg); 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 185161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (msg.wfd_subelems) { 185261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 185361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 185461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 185561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Created device entry based on Probe Req: " MACSTR 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x group_capab=0x%x name='%s' listen_freq=%d", 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab, 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->info.group_capab, dev->info.device_name, 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq); 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr, 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message *msg) 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) { 1874fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&dev->last_seen); 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; /* already known */ 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_create_device(p2p, addr); 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_info(p2p, addr, dev, msg); 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev; 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int dev_type_match(const u8 *dev_type, const u8 *req_dev_type) 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, WPS_DEV_TYPE_LEN) == 0) 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(dev_type, req_dev_type, 2) == 0 && 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE32(&req_dev_type[2]) == 0 && 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(&req_dev_type[6]) == 0) 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Category match with wildcard OUI/sub-category */ 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[], 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_req_dev_type) 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_req_dev_type; i++) { 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_match(dev_type, req_dev_type[i])) 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_match_dev_type - Match local device type with requested type 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @p2p: P2P module context from p2p_init() 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs) 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 on match, 0 on mismatch 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to match the Requested Device Type attribute in 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS IE with the local device types for deciding whether to reply to a Probe 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Request frame. 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_match_dev_type(struct p2p_data *p2p, struct wpabuf *wps) 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(wps, &attr)) 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* assume no Requested Device Type attributes */ 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.num_req_dev_type == 0) 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* no Requested Device Type attributes -> match */ 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->pri_dev_type, attr.req_dev_type, 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Primary Device Type matches */ 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < p2p->cfg->num_sec_dev_types; i++) 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_type_list_match(p2p->cfg->sec_dev_type[i], 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.req_dev_type, 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr.num_req_dev_type)) 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Own Secondary Device Type matches */ 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No matching device type found */ 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p) 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 195204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int pw_id = -1; 195361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 195461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 195561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 195661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 195761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_probe_resp); 195861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 196061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 196404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer) { 196504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Advertise immediate availability of WPS credential */ 196604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pw_id = p2p_wps_method_pw_id(p2p->go_neg_peer->wps_method); 196704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 196804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 196968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_build_wps_ie(p2p, buf, pw_id, 1) < 0) { 197068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Failed to build WPS IE for Probe Response"); 197168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpabuf_free(buf); 197268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NULL; 197368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 197561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 197661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_resp) 197761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp); 197861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 197961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P IE */ 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 198204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 198304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 199404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum p2p_probe_req_status 199504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 199604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 20011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_message msg; 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ies; 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->in_listen || !p2p->drv_in_listen) { 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not in Listen state - ignore Probe Request */ 20067f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt p2p_dbg(p2p, "Not in Listen state (in_listen=%d drv_in_listen=%d) - ignore Probe Request", 20077f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt p2p->in_listen, p2p->drv_in_listen); 200804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_LISTEN; 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) == 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ParseFailed) { 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ignore invalid Probe Request frames */ 2014ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Could not parse Probe Request frame - ignore it"); 201504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_MALFORMED; 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.p2p == NULL) { 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not a P2P probe - ignore it */ 2020ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Not a P2P probe - ignore it"); 202104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dst && !is_broadcast_ether_addr(dst) && 20251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(dst, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 20261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the broadcast address or our P2P Device Address 20271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 2028ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req DA " MACSTR " not ours - ignore it", 2029ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt MAC2STR(dst)); 203004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (bssid && !is_broadcast_ether_addr(bssid)) { 20341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not sent to the Wildcard BSSID */ 2035ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req BSSID " MACSTR " not wildcard - ignore it", 2036ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt MAC2STR(bssid)); 203704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid == NULL || elems.ssid_len != P2P_WILDCARD_SSID_LEN || 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(elems.ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) != 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not using P2P Wildcard SSID - ignore */ 2044ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req not using P2P Wildcard SSID - ignore it"); 204504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (supp_rates_11b_only(&elems)) { 20491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Indicates support for 11b rates only */ 2050ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req with 11b rates only supported - ignore it"); 205104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 20551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg) < 0) { 20561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Could not parse P2P attributes */ 2057ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Could not parse P2P attributes in Probe Req - ignore it"); 205804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_P2P; 20591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.device_id && 206204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(msg.device_id, p2p->cfg->dev_addr, ETH_ALEN) != 0) { 20631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Device ID did not match */ 2064ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req requested Device ID " MACSTR " did not match - ignore it", 2065ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt MAC2STR(msg.device_id)); 20661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 206704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check Requested Device Type match */ 20711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (msg.wps_attributes && 20721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !p2p_match_dev_type(p2p, msg.wps_attributes)) { 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No match with Requested Device Type */ 2074ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Req requestred Device Type did not match - ignore it"); 20751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 207604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_parse_free(&msg); 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!p2p->cfg->send_probe_resp) { 208104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Response generated elsewhere */ 2082ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt p2p_dbg(p2p, "Probe Resp generated elsewhere - do not generate additional response"); 208304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 208404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2086b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Reply to P2P Probe Request in Listen state"); 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We do not really have a specific BSS that this frame is advertising, 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so build a frame that has some information in valid format. This is 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * really only used for discovery purposes, not to learn exact BSS 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parameters. 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies = p2p_build_probe_resp_ies(p2p); 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 209604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(200 + wpabuf_len(ies)); 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 210104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = NULL; 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_put(buf, resp->u.probe_resp.variable - (u8 *) resp); 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) | 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WLAN_FC_STYPE_PROBE_RESP << 4)); 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, addr, ETH_ALEN); 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, p2p->cfg->dev_addr, ETH_ALEN); 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, p2p->cfg->dev_addr, ETH_ALEN); 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.beacon_int = host_to_le16(100); 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* hardware or low-level driver will setup seq_ctrl and timestamp */ 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.capab_info = 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE | 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_PRIVACY | 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_CAPABILITY_SHORT_SLOT_TIME); 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SSID); 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, P2P_WILDCARD_SSID_LEN); 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_SUPP_RATES); 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 8); 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (60 / 5) | 0x80); 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 90 / 5); 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (120 / 5) | 0x80); 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 180 / 5); 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, (240 / 5) | 0x80); 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 360 / 5); 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 480 / 5); 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 540 / 5); 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS); 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, 1); 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, p2p->cfg->channel); 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(buf, ies); 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_probe_resp(p2p->cfg->cb_ctx, buf); 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 214404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 214504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_NOT_PROCESSED; 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 214904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtenum p2p_probe_req_status 215004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtp2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, 215104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid, const u8 *ie, size_t ie_len) 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 215304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum p2p_probe_req_status res; 215404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 215704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len); 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer && 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->go_neg_peer->info.p2p_device_addr, ETH_ALEN) 21629cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt == 0 && 21639cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt !(p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from GO Negotiation peer */ 2165b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Found GO Negotiation peer - try to start GO negotiation from timeout"); 21669cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_go_neg_start, p2p, NULL); 216804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->state == P2P_INVITE || p2p->state == P2P_INVITE_LISTEN) && 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->invite_peer && 21733c4793790bf06f1fe08a2ddf604c9caa855151f1Dmitry Shmidt (p2p->invite_peer->flags & P2P_DEV_WAIT_INV_REQ_ACK) && 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->invite_peer->info.p2p_device_addr, ETH_ALEN) 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Received a Probe Request from Invite peer */ 2177b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Found Invite peer - try to start Invite from timeout"); 21787f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt eloop_cancel_timeout(p2p_invite_start, p2p, NULL); 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, p2p_invite_start, p2p, NULL); 218004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return P2P_PREQ_PROCESSED; 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return res; 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, struct wpabuf *p2p_ie) 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* WLAN AP is not a P2P manager */ 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Interface attribute (present if concurrent device and 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Management is enabled) 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_alloc(200); 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = 0; 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->num_groups > 0) { 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect) 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab); 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_p2p_interface(tmp, p2p); 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int p2p_group, struct wpabuf *p2p_ie) 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tmp; 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *lpos; 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *peer; 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tmplen; 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 224561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_group) 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie); 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 225061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 225161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 225261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_assoc_req); 225361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 225461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (Re)Association Request - P2P IE 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Capability attribute (shall be present) 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen Timing (may be present) 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P Device Info attribute (shall be present) 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 226161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tmp = wpabuf_alloc(200 + extra); 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 226561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 226661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_assoc_req) 226761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req); 226861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 226961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = bssid ? p2p_get_device(p2p, bssid) : NULL; 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lpos = p2p_buf_add_ie_hdr(tmp); 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(tmp, p2p->dev_capab, 0); 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(tmp, p2p->ext_listen_period, 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(tmp, p2p, peer); 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(tmp, lpos); 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmplen = wpabuf_len(tmp); 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmplen > len) 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, wpabuf_head(tmp), tmplen); 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tmplen; 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end) 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, P2P_IE_VENDOR_TYPE); 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_ie == NULL) 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_attr_text(p2p_ie, buf, end); 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 230804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr) 2309c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 2310c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct p2p_message msg; 2311c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2312c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 231304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 2314c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return -1; 2315c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 231604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.p2p_device_addr) { 231704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN); 231804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 231904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (msg.device_id) { 232004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(dev_addr, msg.device_id, ETH_ALEN); 232104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 2322c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 232304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 232404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 2325c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 232604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 232704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr) 232804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 232904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *p2p_ie; 233004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 233104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 233204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 233304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_IE_VENDOR_TYPE); 233404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_ie == NULL) 233504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 233604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr); 2337c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpabuf_free(p2p_ie); 233804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 2339c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 2340c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2341c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_clear_go_neg(struct p2p_data *p2p) 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_timeout(p2p); 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr) 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 2353b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending Group Formation - ignore WPS registration success notification"); 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mac_addr, p2p->go_neg_peer->intended_addr, ETH_ALEN) != 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 2359b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore WPS registration success notification for " 2360b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " (GO Negotiation peer " MACSTR ")", 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr), 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Ignore unexpected peer address */ 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2366b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Group Formation completed successfully with " MACSTR, 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mac_addr)); 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_group_formation_failed(struct p2p_data *p2p) 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == NULL) { 2376b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending Group Formation - ignore group formation failure notification"); 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending Group Formation */ 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2380b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Group Formation failed with " MACSTR, 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(p2p->go_neg_peer->intended_addr)); 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_clear_go_neg(p2p); 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_data * p2p_init(const struct p2p_config *cfg) 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p; 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23912271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (cfg->max_peers < 1 || 23922271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt cfg->passphrase_len < 8 || cfg->passphrase_len > 63) 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg)); 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg = (struct p2p_config *) (p2p + 1); 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg, cfg, sizeof(*cfg)); 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->dev_name) 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(cfg->dev_name); 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->manufacturer) 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(cfg->manufacturer); 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_name) 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(cfg->model_name); 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->model_number) 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(cfg->model_number); 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->serial_number) 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(cfg->serial_number); 241004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (cfg->pref_chan) { 241104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan * 241204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 241304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->cfg->pref_chan) { 241404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan, 241504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cfg->num_pref_chan * 241604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct p2p_channel)); 241704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 241804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = 0; 241904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 242004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->min_disc_int = 1; 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->max_disc_int = 3; 2423d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = -1; 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random(&p2p->next_tie_breaker, 1); 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->next_tie_breaker &= 0x01; 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->sd_request) 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY; 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE; 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg->concurrent_operations) 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER; 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_init(&p2p->devices); 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0, 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_expiration_timeout, p2p, NULL); 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 243961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = 100; 244061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = 20; 244113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt p2p->num_p2p_sd_queries = 0; 244261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 244368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "initialized"); 244468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); 244568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "cli_channels", &p2p->cfg->cli_channels); 244668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p; 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deinit(struct p2p_data *p2p) 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 245361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 245461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 245561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 245661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 245761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 245861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 245961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 246061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 246161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 246261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 246361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 246461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 246561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 246661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL); 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 24709cdf1b905fae57dea42506a1af67f6ece544b261Dmitry Shmidt eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_flush(p2p); 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_req_dev_types(p2p); 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 247804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->groups); 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->sd_resp); 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 248368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(p2p->no_go_freq.range); 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p); 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_flush(struct p2p_data *p2p) 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev, *prev; 249104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_find(p2p); 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device, 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list) { 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&dev->list); 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_device_free(p2p, dev); 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_free_sd_queries(p2p); 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_unauthorize(struct p2p_data *p2p, const u8 *addr) 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2511b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unauthorizing " MACSTR, MAC2STR(addr)); 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer == dev) 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer = NULL; 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->wps_method = WPS_NOT_READY; 2517cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_pw_id = 0; 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM; 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Check if after_scan_tx is for this peer. If so free it */ 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx && 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(addr, p2p->after_scan_tx->dst, ETH_ALEN) == 0) { 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = NULL; 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name) 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->dev_name); 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev_name) { 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = os_strdup(dev_name); 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->dev_name == NULL) 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_name = NULL; 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer) 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->manufacturer); 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = NULL; 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (manufacturer) { 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->manufacturer = os_strdup(manufacturer); 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->manufacturer == NULL) 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_name(struct p2p_data *p2p, const char *model_name) 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_name); 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = NULL; 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_name) { 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_name = os_strdup(model_name); 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_name == NULL) 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_model_number(struct p2p_data *p2p, const char *model_number) 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->model_number); 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = NULL; 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (model_number) { 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->model_number = os_strdup(model_number); 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->model_number == NULL) 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number) 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->cfg->serial_number); 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = NULL; 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (serial_number) { 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->serial_number = os_strdup(serial_number); 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->serial_number == NULL) 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods) 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->config_methods = config_methods; 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid) 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->uuid, uuid, 16); 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type) 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8); 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_sec_dev_types(struct p2p_data *p2p, const u8 dev_types[][8], 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_dev_types) 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_dev_types > P2P_SEC_DEVICE_TYPES) 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_dev_types = P2P_SEC_DEVICE_TYPES; 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->num_sec_dev_types = num_dev_types; 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->sec_dev_type, dev_types, num_dev_types * 8); 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_remove_wps_vendor_extensions(struct p2p_data *p2p) 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p->wps_vendor_ext[i]); 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = NULL; 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_add_wps_vendor_extension(struct p2p_data *p2p, 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *vendor_ext) 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor_ext == NULL) 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= P2P_MAX_WPS_VENDOR_EXT) 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->wps_vendor_ext[i] = wpabuf_dup(vendor_ext); 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->wps_vendor_ext[i] == NULL) 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_country(struct p2p_data *p2p, const char *country) 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->country, country, 3); 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_continue_find(struct p2p_data *p2p) 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SEARCH); 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 267713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (dev->sd_pending_bcast_queries == 0) { 267813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt /* Initialize with total number of registered broadcast 267913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt * SD queries. */ 268013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt dev->sd_pending_bcast_queries = p2p->num_p2p_sd_queries; 268113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 268213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 268313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (p2p_start_sd(p2p, dev) == 0) 268413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return; 268513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (dev->req_config_methods && 268613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt !(dev->flags & P2P_DEV_PD_FOR_JOIN)) { 2687b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Provision Discovery Request to " 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (config methods 0x%x)", 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr), 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods); 26911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0) 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2696d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 1); 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_sd_cb(struct p2p_data *p2p, int success) 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2702b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Service Discovery Query TX callback: success=%d", 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 270713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt p2p->sd_peer = NULL; 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer == NULL) { 2713b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No SD peer entry known"); 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_SD_DURING_FIND); 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 272375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 272475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/** 272575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * p2p_retry_pd - Retry any pending provision disc requests in IDLE state 272675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @p2p: P2P module context from p2p_init() 272775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 27281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void p2p_retry_pd(struct p2p_data *p2p) 272975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 273075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct p2p_device *dev; 273175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 273275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->state != P2P_IDLE) 273375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 273475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 273575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 273675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Retry the prov disc req attempt only for the peer that the user had 2737d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * requested. 273875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 273975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 274075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 274175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (os_memcmp(p2p->pending_pd_devaddr, 274275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->info.p2p_device_addr, ETH_ALEN) != 0) 274375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 274475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!dev->req_config_methods) 274575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen continue; 274675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 2747b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send pending Provision Discovery Request to " 274875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MACSTR " (config methods 0x%x)", 274975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen MAC2STR(dev->info.p2p_device_addr), 275075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen dev->req_config_methods); 2751d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_send_prov_disc_req(p2p, dev, 2752051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN, 2753051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p2p->pd_force_freq); 275475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 275575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 275675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 275775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 275875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_prov_disc_cb(struct p2p_data *p2p, int success) 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2761b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request TX callback: success=%d", 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 276375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 276475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 276575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Postpone resetting the pending action state till after we actually 276675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * time out. This allows us to take some action like notifying any 276775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * interested parties about no response to the request. 276875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 276975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When the timer (below) goes off we check in IDLE, SEARCH, or 277075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * LISTEN_ONLY state, which are the only allowed states to issue a PD 277175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * requests in, if this was still pending and then raise notification. 277275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 277575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 277675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 277761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->user_initiated_pd && 277861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->state == P2P_SEARCH || p2p->state == P2P_LISTEN_ONLY)) 277961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { 278061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Retry request from timeout to avoid busy loops */ 278161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 278261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, 0, 50000); 278361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (p2p->state != P2P_IDLE) 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 278575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else if (p2p->user_initiated_pd) { 278675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 278775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_set_timeout(p2p, 0, 300000); 278875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 279275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 279375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * This postponing, of resetting pending_action_state, needs to be 279475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * done only for user initiated PD requests and not internal ones. 279575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 279675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd) 279775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_PENDING_PD; 279875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else 279975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 280075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wait for response from the peer */ 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_PD_DURING_FIND); 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, 2809fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime *rx_time, int level, const u8 *ies, 2810a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t ies_len) 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2812fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (os_reltime_before(rx_time, &p2p->find_start)) { 2813f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 2814f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * The driver may have cached (e.g., in cfg80211 BSS table) the 2815f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * scan results for relatively long time. To avoid reporting 2816f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * stale information, update P2P peers only based on results 2817f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * that have based on frames received after the last p2p_find 2818f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * operation was started. 2819f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 2820b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore old scan result for " MACSTR 2821b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " (rx_time=%u.%06u)", 2822f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt MAC2STR(bssid), (unsigned int) rx_time->sec, 2823f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt (unsigned int) rx_time->usec); 2824f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return 0; 2825f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 2826f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 2827f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt p2p_add_device(p2p, bssid, freq, rx_time, level, ies, ies_len, 1); 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_scan_res_handled(struct p2p_data *p2p) 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->p2p_scan_running) { 2836b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan was not running, but scan results received"); 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->p2p_scan_running = 0; 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_run_after_scan(p2p)) 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_SEARCH) 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id) 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 285061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len; 285161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 285261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 285361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_probe_req) 285461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(ies, p2p->wfd_ie_probe_req); 285561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 285661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 285761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len = p2p_buf_add_ie_hdr(ies); 285804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(ies, p2p->dev_capab & 285904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 2860c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (dev_id) 2861c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_buf_add_device_id(ies, dev_id); 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->reg_class && p2p->cfg->channel) 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_listen_channel(ies, p2p->cfg->country, 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class, 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_ext_listen_timing(ies, p2p->ext_listen_period, 28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval); 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: p2p_buf_add_operating_channel() if GO */ 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(ies, len); 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtsize_t p2p_scan_ie_buf_len(struct p2p_data *p2p) 28751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 287661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 100; 287761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 287861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 287961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p && p2p->wfd_ie_probe_req) 288061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += wpabuf_len(p2p->wfd_ie_probe_req); 288161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 288261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 288361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 28841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 28851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 28861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end) 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_attr_text(p2p_ie, buf, end); 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_req_cb(struct p2p_data *p2p, int success) 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 28968c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt int timeout; 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2898b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Request TX callback: success=%d", success); 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 2901b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No pending GO Negotiation"); 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (success) { 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 291004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (dev->go_neg_req_sent) { 291104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Cancel the increment from p2p_connect_send() on failure */ 291298f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt dev->go_neg_req_sent--; 291398f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt } 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success && 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY) && 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(dev->member_in_go_dev)) { 2918b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " did not acknowledge request - try to use device discoverability through its GO", 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_send_dev_disc_req(p2p, dev); 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use P2P find, if needed, to find the other device from its listen 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 29308c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout = success ? 500000 : 100000; 29318c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (!success && p2p->go_neg_peer && 29328c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE)) { 29338c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt unsigned int r; 29348c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt /* 29358c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * Peer is expected to wait our response and we will skip the 29368c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * listen phase. Add some randomness to the wait time here to 29378c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * make it less likely to hit cases where we could end up in 29388c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt * sync with peer not listening. 29398c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt */ 29408c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 29418c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt timeout += r % 100000; 29428c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 29438c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, timeout); 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success) 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2949b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Response TX callback: success=%d", 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success); 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p->go_neg_peer && p2p->state == P2P_PROVISIONING) { 2952b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore TX callback event - GO Negotiation is not running anymore"); 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 29568c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29604b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtstatic void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success, 29614b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt const u8 *addr) 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2963b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Response (failure) TX callback: success=%d", success); 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->status != P2P_SC_SUCCESS) { 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->go_neg_peer->status); 29674b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } else if (success) { 29684b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt struct p2p_device *dev; 29694b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev = p2p_get_device(p2p, addr); 29704b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (dev && 29714b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) 29724b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt dev->flags |= P2P_DEV_PEER_WAITING_RESPONSE; 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_neg_conf_cb(struct p2p_data *p2p, 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2982b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "GO Negotiation Confirm TX callback: result=%d", result); 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_FAILED) { 2984413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2988413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 2989413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev = p2p->go_neg_peer; 2990413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (result == P2P_SEND_ACTION_NO_ACK) { 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2993413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * Retry GO Negotiation Confirmation 2994413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * P2P_GO_NEG_CNF_MAX_RETRY_COUNT times if we did not receive 2995413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * ACK for confirmation. 2996413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt */ 2997413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt if (dev && dev->go_neg_conf && 2998413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->go_neg_conf_sent <= P2P_GO_NEG_CNF_MAX_RETRY_COUNT) { 2999413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p_dbg(p2p, "GO Negotiation Confirm retry %d", 3000413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->go_neg_conf_sent); 3001413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->pending_action_state = P2P_PENDING_GO_NEG_CONFIRM; 3002413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt if (p2p_send_action(p2p, dev->go_neg_conf_freq, 3003413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->info.p2p_device_addr, 3004413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->cfg->dev_addr, 3005413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->info.p2p_device_addr, 3006413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_head(dev->go_neg_conf), 3007413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt wpabuf_len(dev->go_neg_conf), 0) >= 3008413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 0) { 3009413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt dev->go_neg_conf_sent++; 3010413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt return; 3011413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt } 3012413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p_dbg(p2p, "Failed to re-send Action frame"); 3013413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 3014413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt /* 3015413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * Continue with the assumption that the first attempt 3016413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt * went through and just the ACK frame was lost. 3017413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt */ 3018413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt } 3019413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 3020413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt /* 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * It looks like the TX status for GO Negotiation Confirm is 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * often showing failure even when the peer has actually 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received the frame. Since the peer may change channels 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * immediately after having received the frame, we may not see 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * an Ack for retries, so just dropping a single frame may 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * trigger this. To allow the group formation to succeed if the 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer did indeed receive the frame, continue regardless of 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the TX status. 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3030b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Assume GO Negotiation Confirm TX was actually received by the peer even though Ack was not reported"); 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3033413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3034413dde71f7bc166de54229f337c24b61f4d909fdDmitry Shmidt 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_complete(p2p, dev); 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_send_action_result result) 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_pending_action_state state; 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int success; 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3049b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Action frame TX callback (state=%d freq=%u dst=" MACSTR 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " src=" MACSTR " bssid=" MACSTR " result=%d", 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src), 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), result); 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt success = result == P2P_SEND_ACTION_SUCCESS; 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = p2p->pending_action_state; 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_NO_PENDING_ACTION: 30584582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt if (p2p->send_action_in_progress) { 30594582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt p2p->send_action_in_progress = 0; 30604582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 30614582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt } 30628da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->after_scan_tx_in_progress) { 30638da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 30648da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->start_after_scan != P2P_AFTER_SCAN_NOTHING && 30658da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p_run_after_scan(p2p)) 30668da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt break; 30678da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (p2p->state == P2P_SEARCH) { 3068b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Continue find after after_scan_tx completion"); 30698da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p_continue_find(p2p); 30708da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 30718da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_REQUEST: 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_req_cb(p2p, success); 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE: 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_resp_cb(p2p, success); 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_RESPONSE_FAILURE: 30804b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt p2p_go_neg_resp_failure_cb(p2p, success, dst); 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_NEG_CONFIRM: 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_conf_cb(p2p, result); 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_SD: 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_cb(p2p, success); 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_PD: 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_prov_disc_cb(p2p, success); 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_REQUEST: 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_req_cb(p2p, success); 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_INVITATION_RESPONSE: 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invitation_resp_cb(p2p, success); 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_REQUEST: 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_req_cb(p2p, success); 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_DEV_DISC_RESPONSE: 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_dev_disc_resp_cb(p2p, success); 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PENDING_GO_DISC_REQ: 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_disc_req_cb(p2p, success); 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31078da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt 31088da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt p2p->after_scan_tx_in_progress = 0; 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_listen_cb(struct p2p_data *p2p, unsigned int freq, 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int duration) 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == p2p->pending_client_disc_freq) { 3116b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability remain-awake completed"); 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_client_disc_freq = 0; 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq != p2p->pending_listen_freq) { 3122b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unexpected listen callback for freq=%u duration=%u (pending_listen_freq=%u)", 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration, p2p->pending_listen_freq); 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3127b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Starting Listen timeout(%u,%u) on freq=%u based on callback", 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_sec, p2p->pending_listen_usec, 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq); 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 1; 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = freq; 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->pending_listen_sec || p2p->pending_listen_usec) { 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Add 20 msec extra wait to avoid race condition with driver 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * remain-on-channel end event, i.e., give driver more time to 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * complete the operation before our timeout expires. 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, p2p->pending_listen_sec, 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_usec + 20000); 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_listen_freq = 0; 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_listen_end(struct p2p_data *p2p, unsigned int freq) 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3148b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver ended Listen state (freq=%u)", freq); 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->drv_in_listen = 0; 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->in_listen) 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Internal timeout will trigger the next step */ 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_CONNECT_LISTEN && p2p->go_neg_peer) { 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 3155b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (p2p->state == P2P_SEARCH) { 3164c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->p2p_scan_running) { 3165c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 3166c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Search is already in progress. This can happen if 3167c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * an Action frame RX is reported immediately after 3168c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * the end of a remain-on-channel operation and the 3169c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * response frame to that is sent using an offchannel 3170c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * operation while in p2p_find. Avoid an attempt to 3171c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * restart a scan here. 3172c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 3173b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "p2p_scan already in progress - do not try to start a new one"); 3174c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 1; 3175c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 317604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->pending_listen_freq) { 317704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 317804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Better wait a bit if the driver is unable to start 317904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * offchannel operation for some reason. p2p_search() 318004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * will be started from internal timeout. 318104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 3182b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Listen operation did not seem to start - delay search phase to avoid busy loop"); 318304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 318404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 318504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 318661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay) { 3187b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay search operation by %u ms", 318861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 318961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 319061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 319161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 319261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect(struct p2p_data *p2p) 32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 320404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->go_neg_peer && 320504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) { 3206b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Wait for GO Negotiation Confirm timed out - assume GO Negotiation failed"); 320704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 320804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 320904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 32108c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt if (p2p->go_neg_peer && 32118c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE) && 32128c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p->go_neg_peer->connect_reqs < 120) { 3213b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer expected to wait our response - skip listen"); 32148c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 32158c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt return; 32168c65289885e84727226d81b3d32856f79c31ee5fDmitry Shmidt } 3217cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p->go_neg_peer && p2p->go_neg_peer->oob_go_neg_freq > 0) { 3218cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Skip connect-listen since GO Neg channel known (OOB)"); 3219cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 3220cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_set_timeout(p2p, 0, 30000); 3221cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return; 3222cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT_LISTEN); 3224d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_connect_listen(struct p2p_data *p2p) 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer) { 32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->drv_in_listen) { 3232b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Driver is still in Listen state; wait for it to complete"); 32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->go_neg_peer->connect_reqs >= 120) { 3237b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on sending GO Negotiation Request without getting response"); 32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1); 32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_CONNECT); 32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_connect_send(p2p, p2p->go_neg_peer); 32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_connect(struct p2p_data *p2p) 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); 32521846323989242844f0e857458a8939fa5836429cDmitry Shmidt 32531846323989242844f0e857458a8939fa5836429cDmitry Shmidt if (p2p->cfg->is_concurrent_session_active && 32541846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p->cfg->is_concurrent_session_active(p2p->cfg->cb_ctx)) 32551846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p_set_timeout(p2p, 0, 500000); 32561846323989242844f0e857458a8939fa5836429cDmitry Shmidt else 32571846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p_set_timeout(p2p, 0, 200000); 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_wait_peer_idle(struct p2p_data *p2p) 32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p->go_neg_peer; 32646dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt struct os_reltime now; 32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 3267b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown GO Neg peer - stop GO Neg wait"); 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32716dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt os_get_reltime(&now); 32726dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt if (os_reltime_expired(&now, &dev->go_neg_wait_started, 120)) { 3273b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout on waiting peer to become ready for GO Negotiation"); 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_neg_failed(p2p, dev, -1); 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Go to Listen state while waiting for the peer to become ready for GO Negotiation"); 32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); 3280d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_sd_during_find(struct p2p_data *p2p) 32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3286b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Service Discovery Query timeout"); 32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->sd_peer) { 32888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 32898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->sd_peer = NULL; 32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_prov_disc_during_find(struct p2p_data *p2p) 32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3297b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request timeout"); 32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_continue_find(p2p); 33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 330375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void p2p_timeout_prov_disc_req(struct p2p_data *p2p) 330475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 330575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 330675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 330775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 330875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * For user initiated PD requests that we have not gotten any responses 330975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * for while in IDLE state, we retry them a couple of times before 331075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * giving up. 331175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 331275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!p2p->user_initiated_pd) 331375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 331475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3315b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "User initiated Provision Discovery Request timeout"); 331675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 331775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pd_retries) { 331875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries--; 331975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_retry_pd(p2p); 332075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 3321d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct p2p_device *dev; 3322d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int for_join = 0; 3323d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3324d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3325d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (os_memcmp(p2p->pending_pd_devaddr, 3326d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dev->info.p2p_device_addr, ETH_ALEN) != 0) 3327d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt continue; 3328d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (dev->req_config_methods && 3329d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (dev->flags & P2P_DEV_PD_FOR_JOIN)) 3330d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join = 1; 3331d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 3332d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 333375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 333475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, 333575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_pd_devaddr, 3336d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for_join ? 3337d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt P2P_PROV_DISC_TIMEOUT_JOIN : 333875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_TIMEOUT); 333975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 334075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 334175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 334275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 334375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite(struct p2p_data *p2p) 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE_LISTEN); 33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO) { 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Better remain on operating channel instead of listen channel 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * when running a group. 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3353b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Inviting in active GO role - wait on operating channel"); 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_timeout(p2p, 0, 100000); 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3357d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p_listen_in_find(p2p, 0); 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_timeout_invite_listen(struct p2p_data *p2p) 33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer && p2p->invite_peer->invitation_reqs < 100) { 33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_INVITE); 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_invite_send(p2p, p2p->invite_peer, 3366cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->invite_go_dev_addr, p2p->invite_dev_pw_id); 33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->invite_peer) { 3369b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Invitation Request retry limit reached"); 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->invitation_result) 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->invitation_result( 3372700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->cfg->cb_ctx, -1, NULL, NULL, 3373e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt p2p->invite_peer->info.p2p_device_addr, 337415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 0, 0); 33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx) 33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3385b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Timeout (state=%s)", p2p_state_txt(p2p->state)); 33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->in_listen = 0; 33888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p->state) { 33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_IDLE: 339175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 339275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 339375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SEARCH: 339675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 339775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 339875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 339961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->search_delay && !p2p->in_search_delay) { 3400b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay search operation by %u ms", 340161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->search_delay); 340261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 1; 340361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_timeout(p2p, p2p->search_delay / 1000, 340461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (p2p->search_delay % 1000) * 1000); 340561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 340661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 340761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->in_search_delay = 0; 34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_search(p2p); 34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT: 34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect(p2p); 34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_CONNECT_LISTEN: 34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_connect_listen(p2p); 34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GO_NEG: 34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_LISTEN_ONLY: 341975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Check if we timed out waiting for PD req */ 342075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) 342175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_timeout_prov_disc_req(p2p); 342275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_only) { 3424b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Extended Listen Timing - Listen State completed"); 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_CONNECT: 34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_connect(p2p); 34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_WAIT_PEER_IDLE: 34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_wait_peer_idle(p2p); 34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SD_DURING_FIND: 34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_sd_during_find(p2p); 34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PROVISIONING: 34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_PD_DURING_FIND: 34418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_prov_disc_during_find(p2p); 34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE: 34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite(p2p); 34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_INVITE_LISTEN: 34478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_timeout_invite_listen(p2p); 34488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 34498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_reject(struct p2p_data *p2p, const u8 *peer_addr) 34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 3458b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Local request to reject connection attempts by peer " 3459b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(peer_addr)); 34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) { 3461b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " unknown", MAC2STR(peer_addr)); 34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status = P2P_SC_FAIL_REJECTED_BY_USER; 34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_USER_REJECTED; 34668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst char * p2p_wps_method_text(enum p2p_wps_method method) 34718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (method) { 34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_NOT_READY: 34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "not-ready"; 34758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 34768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Display"; 34778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Keypad"; 34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PBC"; 3481cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case WPS_NFC: 3482cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return "NFC"; 34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * p2p_go_state_text(enum p2p_go_state go_state) 34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (go_state) { 34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case UNKNOWN_GO: 34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "unknown"; 34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case LOCAL_GO: 34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "local"; 34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case REMOTE_GO: 34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "remote"; 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "??"; 35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst struct p2p_peer_info * p2p_get_peer_info(struct p2p_data *p2p, 35051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr, int next) 35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) 35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev && next) { 35158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, struct p2p_device, list); 35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (&dev->list == &p2p->devices) 35178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = NULL; 35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 35211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 35221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return &dev->info; 35241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 35251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_get_peer_info_txt(const struct p2p_peer_info *info, 35281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *buf, size_t buflen) 35291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 35301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 35311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int res; 35321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *pos, *end; 3533fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now; 35341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (info == NULL) 35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev = (struct p2p_device *) (((u8 *) info) - 35391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offsetof(struct p2p_device, info)); 35401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3544fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "age=%d\n" 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "listen_freq=%d\n" 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wps_method=%s\n" 35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface_addr=" MACSTR "\n" 35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_dev=" MACSTR "\n" 35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "member_in_go_iface=" MACSTR "\n" 35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_neg_req_sent=%d\n" 35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_state=%s\n" 35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dialog_token=%u\n" 35558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "intended_addr=" MACSTR "\n" 35568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "country=%c%c\n" 35578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_freq=%d\n" 35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "req_config_methods=0x%x\n" 355913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s\n" 35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d\n" 35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation_reqs=%u\n", 35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (now.sec - dev->last_seen.sec), 35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->listen_freq, 35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_method_text(dev->wps_method), 35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->interface_addr), 35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_dev), 35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->member_in_go_iface), 35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->go_neg_req_sent, 35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_state_text(dev->go_state), 35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token, 35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->intended_addr), 35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[0] ? dev->country[0] : '_', 35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->country[1] ? dev->country[1] : '_', 35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_freq, 35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PROBE_REQ_ONLY ? 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PROBE_REQ_ONLY]" : "", 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "", 35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_NOT_YET_READY ? 35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[NOT_YET_READY]" : "", 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_DISPLAY ? 35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_DISPLAY]" : "", 35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_PEER_KEYPAD ? 35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_PEER_KEYPAD]" : "", 35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_USER_REJECTED ? 35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[USER_REJECTED]" : "", 35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PEER_WAITING_RESPONSE ? 35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PEER_WAITING_RESPONSE]" : "", 35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PREFER_PERSISTENT_GROUP ? 35908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PREFER_PERSISTENT_GROUP]" : "", 35918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE ? 35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_RESPONSE]" : "", 35938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM ? 35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[WAIT_GO_NEG_CONFIRM]" : "", 35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_GROUP_CLIENT_ONLY ? 35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[GROUP_CLIENT_ONLY]" : "", 35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_FORCE_FREQ ? 35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[FORCE_FREQ]" : "", 35998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags & P2P_DEV_PD_FOR_JOIN ? 36008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[PD_FOR_JOIN]" : "", 36018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->status, 36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->invitation_reqs); 36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->ext_listen_period) { 36088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 36098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_period=%u\n" 36108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ext_listen_interval=%u\n", 36118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_period, 36128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->ext_listen_interval); 36138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_ssid_len) { 36198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = os_snprintf(pos, end - pos, 36208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "oper_ssid=%s\n", 36218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(dev->oper_ssid, 36228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->oper_ssid_len)); 36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || res >= end - pos) 36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res; 36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 362861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 362961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (dev->info.wfd_subelems) { 363061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "wfd_subelems="); 363161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 363261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 363361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 363461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 363561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, 363661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_head(dev->info.wfd_subelems), 363761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(dev->info.wfd_subelems)); 363861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 363961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = os_snprintf(pos, end - pos, "\n"); 364061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0 || res >= end - pos) 364161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return pos - buf; 364261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += res; 364361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 364461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 364561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 36478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_peer_known(struct p2p_data *p2p, const u8 *addr) 36511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 36521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_get_device(p2p, addr) != NULL; 36531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 36541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_client_discoverability(struct p2p_data *p2p, int enabled) 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 3659b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability enabled"); 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 36618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3662b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Client discoverability disabled"); 36638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_req(u32 duration1, u32 interval1, 36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration2, u32 interval2) 36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_noa_desc desc1, desc2, *ptr1 = NULL, *ptr2 = NULL; 36738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 36748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = wpabuf_alloc(100); 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 36778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 36788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration1 || interval1) { 36808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc1, 0, sizeof(desc1)); 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.count_type = 1; 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.duration = duration1; 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc1.interval = interval1; 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr1 = &desc1; 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (duration2 || interval2) { 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&desc2, 0, sizeof(desc2)); 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.count_type = 2; 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.duration = duration2; 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc2.interval = interval2; 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ptr2 = &desc2; 36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(req, P2P_PRESENCE_REQ, 1); 36968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(req); 36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(req, 0, 0, 0, ptr1, ptr2); 36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(req, len); 36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 37018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr, 37058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *own_interface_addr, unsigned int freq, 37068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 duration1, u32 interval1, u32 duration2, 37078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval2) 37088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 37108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3711b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Send Presence Request to GO " MACSTR 3712b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " (own interface " MACSTR ") freq=%u dur1=%u int1=%u " 3713b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "dur2=%u int2=%u", 37148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_interface_addr), MAC2STR(own_interface_addr), 37158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, duration1, interval1, duration2, interval2); 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_presence_req(duration1, interval1, duration2, 37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interval2); 37198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 37208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 37238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr, 37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_interface_addr, 37258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 3726b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 37298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_presence_resp(u8 status, const u8 *noa, 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t noa_len, u8 dialog_token) 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_alloc(100 + noa_len); 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_action_hdr(resp, P2P_PRESENCE_RESP, dialog_token); 37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(resp); 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_status(resp, status); 37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (noa) { 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_ATTR_NOTICE_OF_ABSENCE); 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_le16(resp, noa_len); 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, noa, noa_len); 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_noa(resp, 0, 0, 0, NULL, NULL); 37538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(resp, len); 37548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 37568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_req(struct p2p_data *p2p, const u8 *da, 37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len, 37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rx_freq) 37628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 37648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 status; 37658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 37668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t g; 37678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group = NULL; 37688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int parsed = 0; 37698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 noa[50]; 37708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int noa_len; 37718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3772b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - P2P Presence Request"); 37738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 37758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(da, p2p_group_get_interface_addr(p2p->groups[g]), 37768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN) == 0) { 37778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p->groups[g]; 37788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) { 3782b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore P2P Presence Request for unknown group " 37838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(da)); 37848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 37858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 3788b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P Presence Request"); 37898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 37908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 37918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parsed = 1; 37938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.noa == NULL) { 3795b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No NoA attribute in P2P Presence Request"); 37968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 37978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 37988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = p2p_group_presence_req(group, sa, msg.noa, msg.noa_len); 38018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 38038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->get_noa) 38048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = p2p->cfg->get_noa(p2p->cfg->cb_ctx, da, noa, 38058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(noa)); 38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len = -1; 38088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_presence_resp(status, noa_len > 0 ? noa : NULL, 38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt noa_len > 0 ? noa_len : 0, 38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token); 38118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parsed) 38128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 38148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, rx_freq, sa, da, da, 38188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 3819b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 38208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 38228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_process_presence_resp(struct p2p_data *p2p, const u8 *da, 38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *data, size_t len) 38278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 38298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3830b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received P2P Action - P2P Presence Response"); 38318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg) < 0) { 3833b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to parse P2P Presence Response"); 38348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.status == NULL || msg.noa == NULL) { 3838b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No Status or NoA attribute in P2P Presence Response"); 38398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3843fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p->cfg->presence_resp) { 3844fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt p2p->cfg->presence_resp(p2p->cfg->cb_ctx, sa, *msg.status, 3845fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt msg.noa, msg.noa_len); 3846fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3847fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 38488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*msg.status) { 3849b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "P2P Presence Request was rejected: status %u", 38508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg.status); 38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3855b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "P2P Presence Request was accepted"); 38568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: P2P Presence Response - NoA", 38578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.noa, msg.noa_len); 38588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: process NoA */ 38598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 38608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_ext_listen_timeout(void *eloop_ctx, void *timeout_ctx) 38648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = eloop_ctx; 38668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->ext_listen_interval) { 38688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Schedule next extended listen timeout */ 38698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 38708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 38718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 38728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38746dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt if ((p2p->cfg->is_p2p_in_progress && 38756dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt p2p->cfg->is_p2p_in_progress(p2p->cfg->cb_ctx)) || 38766dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt (p2p->pending_action_state == P2P_PENDING_PD && 38776dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt p2p->pd_retries > 0)) { 38785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt p2p_dbg(p2p, "Operation in progress - skip Extended Listen timeout (%s)", 38795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt p2p_state_txt(p2p->state)); 38805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 38815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 38825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state == P2P_LISTEN_ONLY && p2p->ext_listen_only) { 38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 38858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This should not really happen, but it looks like the Listen 38868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * command may fail is something else (e.g., a scan) was 38878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * running at an inconvenient time. As a workaround, allow new 38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Extended Listen operation to be started. 38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3890b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Previous Extended Listen operation had not been completed - try again"); 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_state(p2p, P2P_IDLE); 38938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->state != P2P_IDLE) { 3896b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Skip Extended Listen timeout in active state (%s)", p2p_state_txt(p2p->state)); 38978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3900b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Extended Listen timeout"); 39018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 1; 39028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen(p2p, p2p->ext_listen_period) < 0) { 3903b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to start Listen state for Extended Listen Timing"); 39048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_only = 0; 39058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_ext_listen(struct p2p_data *p2p, unsigned int period, 39108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (period > 65535 || interval > 65535 || period > interval || 39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (period == 0 && interval > 0) || (period > 0 && interval == 0)) { 3914b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Invalid Extended Listen Timing request: period=%u interval=%u", 3915b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt period, interval); 39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); 39208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (interval == 0) { 3922b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disabling Extended Listen Timing"); 39238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = 0; 39248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = 0; 39258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3928b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Enabling Extended Listen Timing: period %u msec, interval %u msec", 3929b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt period, interval); 39308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_period = period; 39318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval = interval; 39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_sec = interval / 1000; 39338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec = (interval % 1000) * 1000; 39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(p2p->ext_listen_interval_sec, 39368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->ext_listen_interval_usec, 39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ext_listen_timeout, p2p, NULL); 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_deauth_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 39528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39549767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt if (msg.minor_reason_code == NULL) { 39559767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt p2p_parse_free(&msg); 39568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39579767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt } 39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3959b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Deauthentication notification BSSID " MACSTR 39608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 39618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 39628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_disassoc_notif(struct p2p_data *p2p, const u8 *bssid, u16 reason_code, 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie, size_t ie_len) 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid == NULL || ie == NULL) 39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_ies(ie, ie_len, &msg)) 39778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39789767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt if (msg.minor_reason_code == NULL) { 39799767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt p2p_parse_free(&msg); 39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39819767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt } 39828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3983b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disassociation notification BSSID " MACSTR 39848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%u minor_reason_code=%u", 39858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), reason_code, *msg.minor_reason_code); 39868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 39888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_managed_oper(struct p2p_data *p2p, int enabled) 39928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enabled) { 3994b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Managed P2P Device operations enabled"); 39958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab |= P2P_DEV_CAPAB_INFRA_MANAGED; 39968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3997b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Managed P2P Device operations disabled"); 39988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->dev_capab &= ~P2P_DEV_CAPAB_INFRA_MANAGED; 39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 400343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtint p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel, 400443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u8 forced) 40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40064b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(reg_class, channel) < 0) 40078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4009b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set Listen channel: reg_class %u channel %u", 4010b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt reg_class, channel); 401143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 401243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* 401343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * Listen channel was set in configuration or set by control interface; 401443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * cannot override it. 401543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt */ 401643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p->cfg->channel_forced && forced == 0) 401743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return -1; 401843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 401943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p->state == P2P_IDLE) { 402043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->reg_class = reg_class; 402143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->channel = channel; 402243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->cfg->channel_forced = forced; 402343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } else { 402443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p_dbg(p2p, "Defer setting listen channel"); 402543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_reg_class = reg_class; 402643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_channel = channel; 402743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p->pending_channel_forced = forced; 402843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 40298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 403443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtu8 p2p_get_listen_channel(struct p2p_data *p2p) 403543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{ 403643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return p2p->cfg->channel; 403743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt} 403843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 403943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 40408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_set_ssid_postfix(struct p2p_data *p2p, const u8 *postfix, size_t len) 40418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4042b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "New SSID postfix: %s", wpa_ssid_txt(postfix, len)); 40438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (postfix == NULL) { 40448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = 0; 40458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(p2p->cfg->ssid_postfix)) 40488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->cfg->ssid_postfix, postfix, len); 40508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->ssid_postfix_len = len; 40518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 405575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenint p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel, 405675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int cfg_op_channel) 405775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 40584b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(op_reg_class, op_channel) < 0) 405975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 406075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4061b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set Operating channel: reg_class %u channel %u", 4062b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt op_reg_class, op_channel); 406375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_reg_class = op_reg_class; 406475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->op_channel = op_channel; 406575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->cfg_op_channel = cfg_op_channel; 406675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return 0; 406775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 406875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 406975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 407004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan, 407104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const struct p2p_channel *pref_chan) 407204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 407304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct p2p_channel *n; 407404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 407504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (pref_chan) { 407604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = os_malloc(num_pref_chan * sizeof(struct p2p_channel)); 407704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (n == NULL) 407804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 407904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(n, pref_chan, 408004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_pref_chan * sizeof(struct p2p_channel)); 408104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else 408204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt n = NULL; 408304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 408404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(p2p->cfg->pref_chan); 408504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->pref_chan = n; 408604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p->cfg->num_pref_chan = num_pref_chan; 408704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 408804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 408904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 409004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 409104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 409268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_set_no_go_freq(struct p2p_data *p2p, 409368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct wpa_freq_range_list *list) 409468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 409568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct wpa_freq_range *tmp; 409668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 409768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (list == NULL || list->num == 0) { 409868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(p2p->no_go_freq.range); 409968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.range = NULL; 410068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.num = 0; 410168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 410268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 410368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 410468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt tmp = os_calloc(list->num, sizeof(struct wpa_freq_range)); 410568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (tmp == NULL) 410668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return -1; 410768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(tmp, list->range, list->num * sizeof(struct wpa_freq_range)); 410868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(p2p->no_go_freq.range); 410968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.range = tmp; 411068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p->no_go_freq.num = list->num; 411168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_dbg(p2p, "Updated no GO chan list"); 411268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 411368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 411468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 411568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 411668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 41178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr, 41188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *iface_addr) 41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device(p2p, dev_addr); 41218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || is_zero_ether_addr(dev->interface_addr)) 41228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, dev->interface_addr, ETH_ALEN); 41248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_dev_addr(struct p2p_data *p2p, const u8 *iface_addr, 41298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *dev_addr) 41308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 41328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 41338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, dev->info.p2p_device_addr, ETH_ALEN); 41358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr) 41408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->peer_filter, addr, ETH_ALEN); 41428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(p2p->peer_filter)) 4143b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Disable peer filter"); 41448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4145b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Enable peer filter for " MACSTR, 4146b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(p2p->peer_filter)); 41478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_cross_connect(struct p2p_data *p2p, int enabled) 41518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4152b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cross connection %s", enabled ? "enabled" : "disabled"); 41538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cross_connect == enabled) 41548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 41558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cross_connect = enabled; 41568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: may need to tear down any action group where we are GO(?) */ 41578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr) 41618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev = p2p_get_device_interface(p2p, iface_addr); 41638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 41648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->oper_freq <= 0) 41668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return dev->oper_freq; 41688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_intra_bss_dist(struct p2p_data *p2p, int enabled) 41728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4173b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Intra BSS distribution %s", 41748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enabled ? "enabled" : "disabled"); 41758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->p2p_intra_bss = enabled; 41768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 417968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_update_channel_list(struct p2p_data *p2p, 418068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_channels *chan, 418168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_channels *cli_chan) 41828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4183b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Update channel list"); 41848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels)); 418568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); 418668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(&p2p->cfg->cli_channels, cli_chan, 418768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt sizeof(struct p2p_channels)); 418868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_dump(p2p, "cli_channels", &p2p->cfg->cli_channels); 41898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, 41938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 41948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 41958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->p2p_scan_running) { 4197b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Delay Action frame TX until p2p_scan completes"); 41988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx) { 4199b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Dropped previous pending Action frame TX"); 42008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p2p->after_scan_tx); 42018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) + 42038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 42048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->after_scan_tx == NULL) 42058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->freq = freq; 42078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN); 42088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN); 42098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN); 42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->len = len; 42118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->after_scan_tx->wait_time = wait_time; 42128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p->after_scan_tx + 1, buf, len); 42138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, 42178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len, wait_time); 42188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, 42228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_overall) 42238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4224b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Best channel: 2.4 GHz: %d, 5 GHz: %d, overall: %d", 4225b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt freq_24, freq_5, freq_overall); 42268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_24 = freq_24; 42278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_5 = freq_5; 42288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->best_freq_overall = freq_overall; 42298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4232700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtvoid p2p_set_own_freq_preference(struct p2p_data *p2p, int freq) 4233700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 4234b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Own frequency preference: %d MHz", freq); 4235700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p->own_freq_preference = freq; 4236700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 4237700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 4238700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 42398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_neg_peer(struct p2p_data *p2p) 42408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || p2p->go_neg_peer == NULL) 42428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p->go_neg_peer->info.p2p_device_addr; 42448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct p2p_peer_info * 42488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtp2p_get_peer_found(struct p2p_data *p2p, const u8 *addr, int next) 42498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 42518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 42538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, addr); 42548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 42558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!next) { 42588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) 42598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 42628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 42638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 42648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 42658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 42668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 42677832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (!dev || &dev->list == &p2p->devices) 42688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (dev->flags & P2P_DEV_PROBE_REQ_ONLY); 42708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 42728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&p2p->devices, struct p2p_device, list); 42738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dev) 42748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dev->flags & P2P_DEV_PROBE_REQ_ONLY) { 42768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = dl_list_first(&dev->list, 42778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device, 42788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list); 42797832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (!dev || &dev->list == &p2p->devices) 42808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &dev->info; 42858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint p2p_in_progress(struct p2p_data *p2p) 42891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 42901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (p2p == NULL) 42911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 4292fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p->state == P2P_SEARCH) 429361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 2; 42941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING; 42951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 429661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 429761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 429861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout, 429961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 client_timeout) 430061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 430161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p) { 430261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->go_timeout = go_timeout; 430361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->client_timeout = client_timeout; 430461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 430561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 430661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 430761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 430861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 430961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 431061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void p2p_update_wfd_ie_groups(struct p2p_data *p2p) 431161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 431261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t g; 431361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_group *group; 431461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 431561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (g = 0; g < p2p->num_groups; g++) { 431661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt group = p2p->groups[g]; 4317b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt p2p_group_force_beacon_update_ies(group); 431861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 431961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 432061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 432161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 432261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_beacon(struct p2p_data *p2p, struct wpabuf *ie) 432361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 432461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_beacon); 432561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_beacon = ie; 432661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 432761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 432861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 432961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 433061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 433161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_req(struct p2p_data *p2p, struct wpabuf *ie) 433261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 433361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_req); 433461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_req = ie; 433561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 433661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 433761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 433861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 433961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_probe_resp(struct p2p_data *p2p, struct wpabuf *ie) 434061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 434161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_probe_resp); 434261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_probe_resp = ie; 434361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_update_wfd_ie_groups(p2p); 434461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 434561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 434661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 434761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 434861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_assoc_req(struct p2p_data *p2p, struct wpabuf *ie) 434961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 435061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_assoc_req); 435161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_assoc_req = ie; 435261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 435361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 435461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 435561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 435661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_invitation(struct p2p_data *p2p, struct wpabuf *ie) 435761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 435861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_invitation); 435961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_invitation = ie; 436061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 436161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 436261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 436361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 436461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_req(struct p2p_data *p2p, struct wpabuf *ie) 436561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 436661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_req); 436761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_req = ie; 436861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 436961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 437061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 437161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 437261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_prov_disc_resp(struct p2p_data *p2p, struct wpabuf *ie) 437361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 437461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_prov_disc_resp); 437561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_prov_disc_resp = ie; 437661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 437761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 437861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 437961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 438061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_ie_go_neg(struct p2p_data *p2p, struct wpabuf *ie) 438161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 438261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_ie_go_neg); 438361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_ie_go_neg = ie; 438461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 438561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 438661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 438761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 438861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_dev_info(struct p2p_data *p2p, const struct wpabuf *elem) 438961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 439061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_dev_info); 439161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 439261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = wpabuf_dup(elem); 439361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_dev_info == NULL) 439461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 439561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 439661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_dev_info = NULL; 439761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 439861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 439961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 440061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 440161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 440261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_assoc_bssid(struct p2p_data *p2p, const struct wpabuf *elem) 440361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 440461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_assoc_bssid); 440561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 440661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = wpabuf_dup(elem); 440761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_assoc_bssid == NULL) 440861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 440961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 441061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_assoc_bssid = NULL; 441161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 441261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 441361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 441461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 441561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 441661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p, 441761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpabuf *elem) 441861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 441961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(p2p->wfd_coupled_sink_info); 442061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elem) { 442161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = wpabuf_dup(elem); 442261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_coupled_sink_info == NULL) 442361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 442461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 442561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p->wfd_coupled_sink_info = NULL; 442661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 442761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 442861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 442961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 443061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 4431d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4432d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4433d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int, 4434d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int max_disc_tu) 4435d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 4436d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (min_disc_int > max_disc_int || min_disc_int < 0 || max_disc_int < 0) 4437d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 4438d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4439d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->min_disc_int = min_disc_int; 4440d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_int = max_disc_int; 4441d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->max_disc_tu = max_disc_tu; 4442b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Set discoverable interval: min=%d max=%d max_tu=%d", 4443b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt min_disc_int, max_disc_int, max_disc_tu); 4444d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4445d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 4446d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 4447b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4448b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4449b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_dbg(struct p2p_data *p2p, const char *fmt, ...) 4450b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 4451b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 4452b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 4453b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4454b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 4455b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 4456b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4457b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 4458b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 4459b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4460b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 4461b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_DEBUG, buf); 4462b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 4463b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4464b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4465b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_info(struct p2p_data *p2p, const char *fmt, ...) 4466b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 4467b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 4468b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 4469b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4470b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 4471b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 4472b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4473b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 4474b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 4475b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4476b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 4477b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_INFO, buf); 4478b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 4479b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4480b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4481b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtvoid p2p_err(struct p2p_data *p2p, const char *fmt, ...) 4482b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 4483b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_list ap; 4484b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt char buf[500]; 4485b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4486b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (!p2p->cfg->debug_print) 4487b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 4488b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 4489b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_start(ap, fmt); 4490b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt vsnprintf(buf, sizeof(buf), fmt, ap); 4491b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4492b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt va_end(ap); 4493b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p->cfg->debug_print(p2p->cfg->cb_ctx, MSG_ERROR, buf); 4494b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 4495cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4496cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4497d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtvoid p2p_loop_on_known_peers(struct p2p_data *p2p, 4498d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt void (*peer_callback)(struct p2p_peer_info *peer, 4499d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt void *user_data), 4500d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt void *user_data) 4501d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{ 4502d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt struct p2p_device *dev, *n; 4503d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 4504d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { 4505d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt peer_callback(&dev->info, user_data); 4506d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt } 4507d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt} 4508d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 4509d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 4510cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC 4511cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4512cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic struct wpabuf * p2p_build_nfc_handover(struct p2p_data *p2p, 4513cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int client_freq, 4514cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *go_dev_addr, 4515cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 4516cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4517cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *buf; 4518cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 op_class, channel; 4519cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt enum p2p_role_indication role = P2P_DEVICE_NOT_IN_GROUP; 4520cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4521cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt buf = wpabuf_alloc(1000); 4522cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (buf == NULL) 4523cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 4524cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4525cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt op_class = p2p->cfg->reg_class; 4526cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt channel = p2p->cfg->channel; 4527cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4528cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 4529cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 4530cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 4531cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4532cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p->num_groups > 0) { 45337832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt int freq = p2p_group_get_freq(p2p->groups[0]); 4534cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt role = P2P_GO_IN_A_GROUP; 45357832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_class, &channel) < 0) { 45367832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt p2p_dbg(p2p, 45377832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt "Unknown GO operating frequency %d MHz for NFC handover", 45387832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt freq); 45397832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt wpabuf_free(buf); 45407832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt return NULL; 45417832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt } 4542cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (client_freq > 0) { 4543cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt role = P2P_CLIENT_IN_A_GROUP; 45447832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (p2p_freq_to_channel(client_freq, &op_class, &channel) < 0) { 45457832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt p2p_dbg(p2p, 45467832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt "Unknown client operating frequency %d MHz for NFC handover", 45477832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt client_freq); 45487832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt wpabuf_free(buf); 45497832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt return NULL; 45507832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt } 4551cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4552cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4553cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_oob_go_neg_channel(buf, p2p->cfg->country, op_class, 4554cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt channel, role); 4555cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4556cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p->num_groups > 0) { 4557cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt /* Limit number of clients to avoid very long message */ 4558cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_group_info(p2p->groups[0], buf, 5); 4559cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_group_buf_add_id(p2p->groups[0], buf); 4560cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (client_freq > 0 && 4561cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt go_dev_addr && !is_zero_ether_addr(go_dev_addr) && 4562cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid && ssid_len > 0) { 4563cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt /* 4564cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt * Add the optional P2P Group ID to indicate in which group this 4565cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt * device is a P2P Client. 4566cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt */ 4567cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_buf_add_group_id(buf, go_dev_addr, ssid, ssid_len); 4568cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4569cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4570cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return buf; 4571cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4572cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4573cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4574cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * p2p_build_nfc_handover_req(struct p2p_data *p2p, 4575cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int client_freq, 4576cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *go_dev_addr, 4577cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 4578cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4579cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return p2p_build_nfc_handover(p2p, client_freq, go_dev_addr, ssid, 4580cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid_len); 4581cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4582cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4583cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4584cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * p2p_build_nfc_handover_sel(struct p2p_data *p2p, 4585cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int client_freq, 4586cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *go_dev_addr, 4587cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 4588cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4589cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return p2p_build_nfc_handover(p2p, client_freq, go_dev_addr, ssid, 4590cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid_len); 4591cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4592cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4593cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4594cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint p2p_process_nfc_connection_handover(struct p2p_data *p2p, 4595cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_nfc_params *params) 4596cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4597cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_message msg; 4598cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_device *dev; 4599cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *p2p_dev_addr; 4600cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int freq; 4601cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt enum p2p_role_indication role; 4602cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4603cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = NO_ACTION; 4604cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4605cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p_parse_ies_separate(params->wsc_attr, params->wsc_len, 4606cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->p2p_attr, params->p2p_len, &msg)) { 4607cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Failed to parse WSC/P2P attributes from NFC"); 4608cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(&msg); 4609cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4610cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4611cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4612cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.p2p_device_addr) 4613cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dev_addr = msg.p2p_device_addr; 4614cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (msg.device_id) 4615cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dev_addr = msg.device_id; 4616cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else { 4617cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Ignore scan data without P2P Device Info or P2P Device Id"); 4618cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(&msg); 4619cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4620cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4621cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4622cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.oob_dev_password) { 4623cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(params->oob_dev_pw, msg.oob_dev_password, 4624cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg.oob_dev_password_len); 4625cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->oob_dev_pw_len = msg.oob_dev_password_len; 4626cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4627cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4628cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev = p2p_create_device(p2p, p2p_dev_addr); 4629cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dev == NULL) { 4630cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(&msg); 4631cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4632cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4633cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4634cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->peer = &dev->info; 4635cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4636cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_get_reltime(&dev->last_seen); 4637cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); 4638cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_copy_wps_info(p2p, dev, 0, &msg); 4639cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4640cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!msg.oob_go_neg_channel) { 4641cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "OOB GO Negotiation Channel attribute not included"); 4642cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4643cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4644cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4645cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.oob_go_neg_channel[3] == 0 && 4646cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg.oob_go_neg_channel[4] == 0) 4647cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq = 0; 4648cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else 4649cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq = p2p_channel_to_freq(msg.oob_go_neg_channel[3], 4650cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg.oob_go_neg_channel[4]); 4651cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (freq < 0) { 4652cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Unknown peer OOB GO Neg channel"); 4653cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4654cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4655cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt role = msg.oob_go_neg_channel[5]; 4656cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4657cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (role == P2P_GO_IN_A_GROUP) { 4658cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Peer OOB GO operating channel: %u MHz", freq); 4659cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_freq = freq; 4660cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (role == P2P_CLIENT_IN_A_GROUP) { 4661cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Peer (client) OOB GO operating channel: %u MHz", 4662cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq); 4663cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_freq = freq; 4664cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else 4665cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Peer OOB GO Neg channel: %u MHz", freq); 4666cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_go_neg_freq = freq; 4667cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4668cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!params->sel && role != P2P_GO_IN_A_GROUP) { 4669cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, 4670cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->cfg->channel); 4671cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (freq < 0) { 4672cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Own listen channel not known"); 4673cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 4674cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4675cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Use own Listen channel as OOB GO Neg channel: %u MHz", freq); 4676cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->oob_go_neg_freq = freq; 4677cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4678cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4679cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg.group_id) { 4680cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(params->go_dev_addr, msg.group_id, ETH_ALEN); 4681cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_ssid_len = msg.group_id_len - ETH_ALEN; 4682cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(params->go_ssid, msg.group_id + ETH_ALEN, 4683cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_ssid_len); 4684cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4685cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4686cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dev->flags & P2P_DEV_USER_REJECTED) { 4687cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "Do not report rejected device"); 4688717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt p2p_parse_free(&msg); 4689cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 4690cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4691cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4692cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!(dev->flags & P2P_DEV_REPORTED)) { 4693cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->cfg->dev_found(p2p->cfg->cb_ctx, p2p_dev_addr, &dev->info, 4694cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt !(dev->flags & P2P_DEV_REPORTED_ONCE)); 4695cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE; 4696cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4697717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt p2p_parse_free(&msg); 4698cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4699cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (role == P2P_GO_IN_A_GROUP && p2p->num_groups > 0) 4700cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = BOTH_GO; 4701cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (role == P2P_GO_IN_A_GROUP) 4702cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = JOIN_GROUP; 4703cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (role == P2P_CLIENT_IN_A_GROUP) { 4704cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev->flags |= P2P_DEV_GROUP_CLIENT_ONLY; 4705cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = PEER_CLIENT; 4706cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (p2p->num_groups > 0) 4707cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = AUTH_JOIN; 4708cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else if (params->sel) 4709cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = INIT_GO_NEG; 4710cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt else 4711cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->next_step = RESP_GO_NEG; 4712cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4713cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 4714cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4715cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4716cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4717cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtvoid p2p_set_authorized_oob_dev_pw_id(struct p2p_data *p2p, u16 dev_pw_id, 4718cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int go_intent, 4719cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *own_interface_addr) 4720cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 4721cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4722cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->authorized_oob_dev_pw_id = dev_pw_id; 4723cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (dev_pw_id == 0) { 4724cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "NFC OOB Password unauthorized for static handover"); 4725cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return; 4726cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 4727cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4728cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_dbg(p2p, "NFC OOB Password (id=%u) authorized for static handover", 4729cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt dev_pw_id); 4730cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4731cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p->go_intent = go_intent; 4732cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); 4733cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 4734cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4735cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */ 47362271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 47372271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 47382271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidtint p2p_set_passphrase_len(struct p2p_data *p2p, unsigned int len) 47392271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt{ 47402271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (len < 8 || len > 63) 47412271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt return -1; 47422271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p->cfg->passphrase_len = len; 47432271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt return 0; 47442271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt} 4745