18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant - P2P 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications 4fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * Copyright (c) 2010-2014, Jouni Malinen <j@w1.fi> 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 7c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/hostapd.h" 201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "ap/ap_config.h" 21391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "ap/sta_info.h" 22391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "ap/ap_drv_ops.h" 23cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#include "ap/wps_hostapd.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/p2p_hostapd.h" 25203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#include "ap/dfs.h" 2675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "eapol_supp/eapol_supp_sm.h" 2775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "rsn_supp/wpa.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config_ssid.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h" 361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "offchannel.h" 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h" 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h" 3904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt#include "wifi_display.h" 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * How many times to try to scan to find the GO before giving up on join 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request. 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_MAX_JOIN_SCAN_ATTEMPTS 10 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#define P2P_AUTO_PD_SCAN_ATTEMPTS 5 4904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef P2P_MAX_CLIENT_IDLE 511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/* 521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * How many seconds to try to reconnect to the GO when connection in P2P client 531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * role has been lost. 541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define P2P_MAX_CLIENT_IDLE 10 561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* P2P_MAX_CLIENT_IDLE */ 571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifndef P2P_MAX_INITIAL_CONN_WAIT 5904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/* 6004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * How many seconds to wait for initial 4-way handshake to get completed after 6115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt * WPS provisioning step or after the re-invocation of a persistent group on a 6215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt * P2P Client. 6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#define P2P_MAX_INITIAL_CONN_WAIT 10 6504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* P2P_MAX_INITIAL_CONN_WAIT */ 6604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6792c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt#ifndef P2P_MAX_INITIAL_CONN_WAIT_GO 6892c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt/* 6992c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * How many seconds to wait for initial 4-way handshake to get completed after 7092c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * WPS provisioning step on the GO. This controls the extra time the P2P 7192c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * operation is considered to be in progress (e.g., to delay other scans) after 7292c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * WPS provisioning has been completed on the GO during group formation. 7392c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt */ 7492c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt#define P2P_MAX_INITIAL_CONN_WAIT_GO 10 7592c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt#endif /* P2P_MAX_INITIAL_CONN_WAIT_GO */ 7692c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt 775605286c30e1701491bd3af974ae423727750eddDmitry Shmidt#ifndef P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE 785605286c30e1701491bd3af974ae423727750eddDmitry Shmidt/* 795605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * How many seconds to wait for initial 4-way handshake to get completed after 805605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * re-invocation of a persistent group on the GO when the client is expected 815605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * to connect automatically (no user interaction). 825605286c30e1701491bd3af974ae423727750eddDmitry Shmidt */ 835605286c30e1701491bd3af974ae423727750eddDmitry Shmidt#define P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE 15 845605286c30e1701491bd3af974ae423727750eddDmitry Shmidt#endif /* P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE */ 855605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 8634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-" 8734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 8861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtenum p2p_group_removal_reason { 8961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_UNKNOWN, 9061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_SILENT, 9161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_FORMATION_FAILED, 9261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_REQUESTED, 9361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_IDLE_TIMEOUT, 9461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_UNAVAILABLE, 9561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_GO_ENDING_SESSION, 9604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt P2P_GROUP_REMOVAL_PSK_FAILURE, 9704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt P2P_GROUP_REMOVAL_FREQ_CONFLICT 9861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}; 9961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 100dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go); 105cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq, 106cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len); 107344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidtstatic void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq, 108344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt const u8 *ssid, size_t ssid_len); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr, 11104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *dev_addr, enum p2p_wps_method wps_method, 112cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int auto_join, int freq, 113cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s); 118f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstatic void wpas_p2p_group_formation_timeout(void *eloop_ctx, 119f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt void *timeout_ctx); 12004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidtstatic void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx); 1217f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidtstatic int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s, 1227f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt int group_added); 1236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s); 124bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidtstatic void wpas_stop_listen(void *ctx); 125684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidtstatic void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx); 12643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s); 127216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s, 128216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt enum wpa_driver_if_type type); 129a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidtstatic void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s, 130a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt int already_deleted); 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 133c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt/* 134c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * Get the number of concurrent channels that the HW can operate, but that are 135c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * currently not in use by any of the wpa_supplicant interfaces. 136c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt */ 137c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic int wpas_p2p_num_unused_channels(struct wpa_supplicant *wpa_s) 138c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{ 139c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int *freqs; 140b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt int num, unused; 141c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 142c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int)); 143c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 144c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 145c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 146c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num = get_shared_radio_freqs(wpa_s, freqs, 147c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_s->num_multichan_concurrent); 148c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 149c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 150b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt unused = wpa_s->num_multichan_concurrent - num; 151b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: num_unused_channels: %d", unused); 152b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt return unused; 153c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 154c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 155c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 156c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt/* 157c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * Get the frequencies that are currently in use by one or more of the virtual 158c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * interfaces, and that are also valid for P2P operation. 159c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt */ 16043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic unsigned int 16143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtwpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s, 16243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_used_freq_data *p2p_freqs, 16343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt unsigned int len) 164c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{ 16543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_used_freq_data *freqs; 166c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned int num, i, j; 167c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 16843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, 16943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt sizeof(struct wpa_used_freq_data)); 170c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 17143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return 0; 172c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 17343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt num = get_shared_radio_freqs_data(wpa_s, freqs, 17443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_s->num_multichan_concurrent); 175c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 17643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt os_memset(p2p_freqs, 0, sizeof(struct wpa_used_freq_data) * len); 177c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 178c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0, j = 0; i < num && j < len; i++) { 17943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p_supported_freq(wpa_s->global->p2p, freqs[i].freq)) 180c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt p2p_freqs[j++] = freqs[i]; 181c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 182c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 183c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 184c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 18543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt dump_freq_data(wpa_s, "valid for P2P", p2p_freqs, j); 186b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt 187c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return j; 188c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 189c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 190c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 191700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_p2p_set_own_freq_preference(struct wpa_supplicant *wpa_s, 192700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt int freq) 193700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 194700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 195700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; 1968bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt 1978bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt /* Use the wpa_s used to control the P2P Device operation */ 1988bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt wpa_s = wpa_s->global->p2p_init_wpa_s; 1998bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt 2008bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt if (wpa_s->conf->p2p_ignore_shared_freq && 201a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt freq > 0 && wpa_s->num_multichan_concurrent > 1 && 202a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt wpas_p2p_num_unused_channels(wpa_s) > 0) { 203a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz due to p2p_ignore_shared_freq=1 configuration", 204a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt freq); 205700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt freq = 0; 206a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt } 207700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p_set_own_freq_preference(wpa_s->global->p2p, freq); 208700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 209700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 210700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s, 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res) 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 216fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->p2p_scan_work) { 217fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_radio_work *work = wpa_s->p2p_scan_work; 218fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_scan_work = NULL; 219fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt radio_work_done(work); 220fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 221fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS)", 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) scan_res->num); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < scan_res->num; i++) { 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *bss = scan_res->res[i]; 230fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime time_tmp_age, entry_ts; 2319657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt const u8 *ies; 2329657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt size_t ies_len; 2339657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 234f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt time_tmp_age.sec = bss->age / 1000; 235f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt time_tmp_age.usec = (bss->age % 1000) * 1000; 236fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_reltime_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts); 2379657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 2389657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt ies = (const u8 *) (bss + 1); 2399657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt ies_len = bss->ie_len; 2409657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt if (bss->beacon_ie_len > 0 && 2419657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt !wpa_scan_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) && 2429657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt wpa_scan_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) { 2439657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use P2P IE(s) from Beacon frame since no P2P IE(s) in Probe Response frames received for " 2449657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt MACSTR, MAC2STR(bss->bssid)); 2459657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt ies = ies + ies_len; 2469657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt ies_len = bss->beacon_ie_len; 2479657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt } 2489657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 2499657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid, 251f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt bss->freq, &entry_ts, bss->level, 2529657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt ies, ies_len) > 0) 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_scan_res_handled(wpa_s->global->p2p); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 260fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_trigger_scan_cb(struct wpa_radio_work *work, int deinit) 261fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 262fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_supplicant *wpa_s = work->wpa_s; 263fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_driver_scan_params *params = work->ctx; 264fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int ret; 265fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 266fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (deinit) { 267bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (!work->started) { 268bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_scan_free_params(params); 269bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt return; 270bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 271bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 272bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_s->p2p_scan_work = NULL; 273fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 274fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 275fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 276fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = wpa_drv_scan(wpa_s, params); 277fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_scan_free_params(params); 278fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt work->ctx = NULL; 279fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (ret) { 280fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt radio_work_done(work); 2816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_notify_scan_trigger_status(wpa_s->global->p2p, ret); 282fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 283fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 284fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_notify_scan_trigger_status(wpa_s->global->p2p, ret); 286fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&wpa_s->scan_trigger_time); 287fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_handler; 288fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->own_scan_requested = 1; 289fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_scan_work = work; 290fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 291fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 292fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int wpas_p2p_search_social_channel(struct wpa_supplicant *wpa_s, 2946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int freq) 2956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 2966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->global->p2p_24ghz_social_channels && 2976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt (freq == 2412 || freq == 2437 || freq == 2462)) { 2986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 2996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Search all social channels regardless of whether these have 3006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * been disabled for P2P operating channel use to avoid missing 3016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * peers. 3026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 3036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 1; 3046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 3056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return p2p_supported_freq(wpa_s->global->p2p, freq); 3066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 3076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq, 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int num_req_dev_types, 31104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *req_dev_types, const u8 *dev_id, u16 pw_id) 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 314fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_driver_scan_params *params = NULL; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_ie, *ies; 316661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt unsigned int num_channels = 0; 317661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt int social_channels_freq[] = { 2412, 2437, 2462, 60480 }; 3181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t ielen; 319661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt u8 *n, i; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 324fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->p2p_scan_work) { 325fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_dbg(wpa_s, MSG_INFO, "P2P: Reject scan trigger since one is already pending"); 326fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 32761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 32861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 329fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params = os_zalloc(sizeof(*params)); 330fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (params == NULL) 331fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P Wildcard SSID */ 334fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params->num_ssids = 1; 335fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n = os_malloc(P2P_WILDCARD_SSID_LEN); 336fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (n == NULL) 337fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt goto fail; 338fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memcpy(n, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN); 339fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params->ssids[0].ssid = n; 340fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params->ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->wps->dev.p2p = 1; 34304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev, 34404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types, req_dev_types); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_ie == NULL) 347fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt goto fail; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 3501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen); 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) { 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 353fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt goto fail; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(ies, wps_ie); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_scan_ie(wpa_s->global->p2p, ies, dev_id); 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 360fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params->p2p_probe = 1; 361fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n = os_malloc(wpabuf_len(ies)); 362fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (n == NULL) { 363fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpabuf_free(ies); 364fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt goto fail; 365fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 366fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memcpy(n, wpabuf_head(ies), wpabuf_len(ies)); 367fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params->extra_ies = n; 368fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params->extra_ies_len = wpabuf_len(ies); 369fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpabuf_free(ies); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SCAN_SOCIAL: 373661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 1, 374661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt sizeof(int)); 375fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (params->freqs == NULL) 376fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt goto fail; 377661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) { 3786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpas_p2p_search_social_channel( 3796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s, social_channels_freq[i])) 380661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt params->freqs[num_channels++] = 381661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt social_channels_freq[i]; 382661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 383661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt params->freqs[num_channels++] = 0; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SCAN_FULL: 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 387203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt case P2P_SCAN_SPECIFIC: 388203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt params->freqs = os_calloc(2, sizeof(int)); 389203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (params->freqs == NULL) 390203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt goto fail; 391203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt params->freqs[0] = freq; 392203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt params->freqs[1] = 0; 393203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt break; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SCAN_SOCIAL_PLUS_ONE: 395661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 2, 396661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt sizeof(int)); 397fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (params->freqs == NULL) 398fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt goto fail; 399661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) { 4006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpas_p2p_search_social_channel( 4016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s, social_channels_freq[i])) 402661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt params->freqs[num_channels++] = 403661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt social_channels_freq[i]; 404661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 405661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (p2p_supported_freq(wpa_s->global->p2p, freq)) 406661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt params->freqs[num_channels++] = freq; 407661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt params->freqs[num_channels++] = 0; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 411bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radio_remove_works(wpa_s, "p2p-scan", 0); 412fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (radio_add_work(wpa_s, 0, "p2p-scan", 0, wpas_p2p_trigger_scan_cb, 413fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params) < 0) 414fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt goto fail; 415fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 417fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtfail: 418fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_scan_free_params(params); 419fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum wpa_driver_if_type wpas_p2p_if_type(int p2p_group_interface) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p_group_interface) { 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_INTERFACE_PENDING: 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_GROUP; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_INTERFACE_GO: 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_GO; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_INTERFACE_CLIENT: 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_CLIENT; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_GROUP; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * wpas_get_p2p_group(struct wpa_supplicant *wpa_s, 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ssid_len, int *go) 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled != 0 || !s->p2p_group || 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len != ssid_len || 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) != 0) 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO && 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s != wpa_s->current_ssid) 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *go = s->mode == WPAS_MODE_P2P_GO; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_s; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void run_wpas_p2p_disconnect(void *eloop_ctx, void *timeout_ctx) 4646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 4656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 4666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 4676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "P2P: Complete previously requested removal of %s", 4686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->ifname); 4696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpas_p2p_disconnect(wpa_s); 4706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 4716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int wpas_p2p_disconnect_safely(struct wpa_supplicant *wpa_s, 4746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_supplicant *calling_wpa_s) 4756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 4766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (calling_wpa_s == wpa_s && wpa_s && 4776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) { 4786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 4796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * The calling wpa_s instance is going to be removed. Do that 4806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * from an eloop callback to keep the instance available until 4816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * the caller has returned. This my be needed, e.g., to provide 4826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * control interface responses on the per-interface socket. 4836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 4846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (eloop_register_timeout(0, 0, run_wpas_p2p_disconnect, 4856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s, NULL) < 0) 4866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 4876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 4886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 4896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return wpas_p2p_disconnect(wpa_s); 4916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 4926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 494216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt/* Determine total number of clients in active groups where we are the GO */ 495216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic unsigned int p2p_group_go_member_count(struct wpa_supplicant *wpa_s) 496216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 497216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt unsigned int count = 0; 498216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *s; 499216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 500216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 501216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 502216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 503216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: sup:%p ssid:%p disabled:%d p2p:%d mode:%d", 504216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s, s, s->disabled, s->p2p_group, 505216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s->mode); 506216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!s->disabled && s->p2p_group && 507216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s->mode == WPAS_MODE_P2P_GO) { 508216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt count += p2p_get_group_num_members( 509216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->p2p_group); 510216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 511216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 512216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 513216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 514216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return count; 515216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 516216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 517216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 518216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt/* Find an interface for a P2P group where we are the GO */ 519216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic struct wpa_supplicant * 520216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtwpas_p2p_get_go_group(struct wpa_supplicant *wpa_s) 521216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 522216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_supplicant *save = NULL; 523216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *s; 524216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 525216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!wpa_s) 526216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return NULL; 527216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 528216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 529216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 530216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (s->disabled || !s->p2p_group || 531216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s->mode != WPAS_MODE_P2P_GO) 532216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt continue; 533216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 534216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Prefer a group with connected clients */ 535216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p_get_group_num_members(wpa_s->p2p_group)) 536216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return wpa_s; 537216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt save = wpa_s; 538216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 539216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 540216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 541216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* No group with connected clients, so pick the one without (if any) */ 542216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return save; 543216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 544216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 545216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 546216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt/* Find an active P2P group where we are the GO */ 547216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic struct wpa_ssid * wpas_p2p_group_go_ssid(struct wpa_supplicant *wpa_s, 548216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 *bssid) 549216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 550216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *s, *empty = NULL; 551216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 552216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!wpa_s) 553216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 554216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 555216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 556216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 557216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (s->disabled || !s->p2p_group || 558216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s->mode != WPAS_MODE_P2P_GO) 559216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt continue; 560216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 561216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(bssid, wpa_s->own_addr, ETH_ALEN); 562216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p_get_group_num_members(wpa_s->p2p_group)) 563216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return s; 564216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt empty = s; 565216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 566216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 567216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 568216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return empty; 569216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 570216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 571216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 572216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt/* Find a persistent group where we are the GO */ 573216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic struct wpa_ssid * 574216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtwpas_p2p_get_persistent_go(struct wpa_supplicant *wpa_s) 575216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 576216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *s; 577216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 578216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 579216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (s->disabled == 2 && s->mode == WPAS_MODE_P2P_GO) 580216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return s; 581216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 582216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 583216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return NULL; 584216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 585216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 586216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 587216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic u8 p2ps_group_capability(void *ctx, u8 incoming, u8 role) 588216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 589216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx, *tmp_wpa_s; 590216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *s; 591216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 conncap = P2PS_SETUP_NONE; 592216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt unsigned int owned_members = 0; 593216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt unsigned int owner = 0; 594216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt unsigned int client = 0; 595216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_supplicant *go_wpa_s; 596216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *persistent_go; 597216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int p2p_no_group_iface; 598216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 599216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Conncap - in:%d role:%d", incoming, role); 600216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 601216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* 602216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * For non-concurrent capable devices: 603216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * If persistent_go, then no new. 604216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * If GO, then no client. 605216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * If client, then no GO. 606216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt */ 607216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt go_wpa_s = wpas_p2p_get_go_group(wpa_s); 608216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persistent_go = wpas_p2p_get_persistent_go(wpa_s); 609216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_no_group_iface = wpa_s->conf->p2p_no_group_iface; 610216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 611216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO(iface)=%p persistent(ssid)=%p", 612216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt go_wpa_s, persistent_go); 613216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 614216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (tmp_wpa_s = wpa_s->global->ifaces; tmp_wpa_s; 615216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp_wpa_s = tmp_wpa_s->next) { 616216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (s = tmp_wpa_s->conf->ssid; s; s = s->next) { 617216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 618216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: sup:%p ssid:%p disabled:%d p2p:%d mode:%d", 619216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp_wpa_s, s, s->disabled, 620216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s->p2p_group, s->mode); 621216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!s->disabled && s->p2p_group) { 622216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO) { 623216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt owned_members += 624216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_get_group_num_members( 625216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp_wpa_s->p2p_group); 626216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt owner++; 627216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else 628216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt client++; 629216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 630216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 631216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 632216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 633216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* If not concurrent, restrict our choices */ 634216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p_no_group_iface) { 635216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: p2p_no_group_iface"); 636216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 637216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (client) 638216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_NONE; 639216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 640216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (go_wpa_s) { 641216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (role == P2PS_SETUP_CLIENT || 642216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt incoming == P2PS_SETUP_GROUP_OWNER || 643216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_client_limit_reached(go_wpa_s->p2p_group)) 644216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_NONE; 645216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 646216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_GROUP_OWNER; 647216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 648216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 649216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (persistent_go) { 650216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (role == P2PS_SETUP_NONE || role == P2PS_SETUP_NEW) { 651216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!incoming) 652216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_GROUP_OWNER | 653216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2PS_SETUP_CLIENT; 654216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (incoming == P2PS_SETUP_NEW) { 655216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 r; 656216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 657216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (os_get_random(&r, sizeof(r)) < 0 || 658216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (r & 1)) 659216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_CLIENT; 660216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_GROUP_OWNER; 661216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 662216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 663216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 664216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 665216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 666216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* If a required role has been specified, handle it here */ 667216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (role && role != P2PS_SETUP_NEW) { 668216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt switch (incoming) { 669216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_NONE: 670216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_NEW: 671216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT: 672216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW: 673216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = role; 674216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto grp_owner; 675216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 676216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_GROUP_OWNER: 677216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* 678216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * Must be a complimentary role - cannot be a client to 679216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * more than one peer. 680216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt */ 681216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (incoming == role || client) 682216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_NONE; 683216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 684216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_CLIENT; 685216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 686216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_CLIENT: 687216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Must be a complimentary role */ 688216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (incoming != role) { 689216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_GROUP_OWNER; 690216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto grp_owner; 691216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 692216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 693216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt default: 694216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_NONE; 695216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 696216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 697216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 698216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* 699216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * For now, we only will support ownership of one group, and being a 700216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * client of one group. Therefore, if we have either an existing GO 701216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * group, or an existing client group, we will not do a new GO 702216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * negotiation, but rather try to re-use the existing groups. 703216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt */ 704216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt switch (incoming) { 705216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_NONE: 706216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_NEW: 707216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (client) 708216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_GROUP_OWNER; 709216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (!owned_members) 710216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_NEW; 711216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (incoming == P2PS_SETUP_NONE) 712216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT; 713216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 714216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_CLIENT; 715216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 716216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 717216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_CLIENT: 718216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_GROUP_OWNER; 719216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 720216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 721216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_GROUP_OWNER: 722216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!client) 723216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_CLIENT; 724216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 725216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 726216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW: 727216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT: 728216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (client) 729216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_GROUP_OWNER; 730216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else { 731216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 r; 732216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 733216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (os_get_random(&r, sizeof(r)) < 0 || 734216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (r & 1)) 735216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_CLIENT; 736216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 737216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_GROUP_OWNER; 738216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 739216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 740216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 741216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt default: 742216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_NONE; 743216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 744216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 745216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtgrp_owner: 746216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if ((conncap & P2PS_SETUP_GROUP_OWNER) || 747216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (!incoming && (conncap & P2PS_SETUP_NEW))) { 748216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (go_wpa_s && p2p_client_limit_reached(go_wpa_s->p2p_group)) 749216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap &= ~P2PS_SETUP_GROUP_OWNER; 750216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GOs:%d members:%d conncap:%d", 751216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt owner, owned_members, conncap); 752216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 753216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s = wpas_p2p_get_persistent_go(wpa_s); 754216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 755216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!s && !owner && p2p_no_group_iface) { 756216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_set_intended_addr(wpa_s->global->p2p, 757216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->own_addr); 758216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (!s && !owner) { 759216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, 760216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt WPA_IF_P2P_GO) < 0) { 761216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_ERROR, 762216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: Failed to allocate a new interface for the group"); 763216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return P2PS_SETUP_NONE; 764216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 765216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->global->pending_group_iface_for_p2ps = 1; 766216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_set_intended_addr(wpa_s->global->p2p, 767216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->pending_interface_addr); 768216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 769216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 770216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 771216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return conncap; 772216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 773216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 774216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 77561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s, 77661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt enum p2p_group_removal_reason removal_reason) 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *gtype; 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *reason; 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The current SSID was not known, but there may still be a 786aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt * pending P2P group interface waiting for provisioning or a 787aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt * P2P group that is trying to reconnect. 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->conf->ssid; 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 7919d71283328fbad680cc74d9b287580e373eb4d6cJouni Malinen if (ssid->p2p_group && ssid->disabled != 2) 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7955c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen if (ssid == NULL && 7965c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE) 7975c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen { 79861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: P2P group interface " 79961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "not found"); 80061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 80161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO) 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtype = "GO"; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT || 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ssid && ssid->mode == WPAS_MODE_INFRA)) { 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->reassociate = 0; 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->disconnected = 1; 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtype = "client"; 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtype = "GO"; 812661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 813661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (removal_reason != P2P_GROUP_REMOVAL_SILENT && ssid) 814661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpas_notify_p2p_group_removed(wpa_s, ssid, gtype); 815661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 8166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_strcmp(gtype, "client") == 0) { 817661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 8186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (eloop_is_timeout_registered(wpas_p2p_psk_failure_removal, 8196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s, NULL)) { 8206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 8216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "P2P: PSK failure removal was scheduled, so use PSK failure as reason for group removal"); 8226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt removal_reason = P2P_GROUP_REMOVAL_PSK_FAILURE; 8236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eloop_cancel_timeout(wpas_p2p_psk_failure_removal, 8246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s, NULL); 8256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 8266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 827661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->cross_connect_in_use) { 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_in_use = 0; 830b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 831b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s", 832b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, wpa_s->cross_connect_uplink); 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 83461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (removal_reason) { 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_REMOVAL_REQUESTED: 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = " reason=REQUESTED"; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 83861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_GROUP_REMOVAL_FORMATION_FAILED: 83961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt reason = " reason=FORMATION_FAILED"; 84061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_REMOVAL_IDLE_TIMEOUT: 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = " reason=IDLE"; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_REMOVAL_UNAVAILABLE: 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = " reason=UNAVAILABLE"; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 84704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_GROUP_REMOVAL_GO_ENDING_SESSION: 84804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt reason = " reason=GO_ENDING_SESSION"; 84904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 850391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt case P2P_GROUP_REMOVAL_PSK_FAILURE: 851391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt reason = " reason=PSK_FAILURE"; 852391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt break; 85304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt case P2P_GROUP_REMOVAL_FREQ_CONFLICT: 85404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt reason = " reason=FREQ_CONFLICT"; 85504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt break; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = ""; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 86061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (removal_reason != P2P_GROUP_REMOVAL_SILENT) { 861b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 862b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_REMOVED "%s %s%s", 863b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, gtype, reason); 86404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 86604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL) > 0) 86704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group freq_conflict timeout"); 86804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0) 86904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout"); 870f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 8712f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_s->parent, NULL) > 0) { 872f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group formation " 873f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "timeout"); 8742f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_s->p2p_in_provisioning = 0; 8752f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt } 87604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 87715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_s->p2p_in_invitation = 0; 87815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 8799657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt /* 8809657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * Make sure wait for the first client does not remain active after the 8819657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * group has been removed. 8829657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt */ 8839657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt wpa_s->global->p2p_go_wait_client.sec = 0; 8849657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) { 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *ifname; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_driver_if_type type; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove group interface %s", 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname); 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global = wpa_s->global; 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname = os_strdup(wpa_s->ifname); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = wpas_p2p_if_type(wpa_s->p2p_group_interface); 8946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eloop_cancel_timeout(run_wpas_p2p_disconnect, wpa_s, NULL); 895e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0); 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = global->ifaces; 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s && ifname) 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_if_remove(wpa_s, type, ifname); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ifname); 9002b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 1; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9039657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt if (!wpa_s->p2p_go_group_formation_completed) { 9049657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 9059657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt wpa_s->p2p_in_provisioning = 0; 9069657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt } 9079657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 908cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_s->show_group_started = 0; 909cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(wpa_s->go_params); 910cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_s->go_params = NULL; 911cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 9126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(wpa_s->p2p_group_common_freqs); 9136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_common_freqs = NULL; 9146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_common_freqs_num = 0; 9156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 916fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->waiting_presence_resp = 0; 917fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network"); 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid && (ssid->p2p_group || 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION || 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) { 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int id = ssid->id; 92375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ssid == wpa_s->current_ssid) { 92475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_sm_set_config(wpa_s->wpa, NULL); 92575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid = NULL; 92775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 92875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 92975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Networks objects created during any P2P activities are not 93075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * exposed out as they might/will confuse certain non-P2P aware 93175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * applications since these network objects won't behave like 93275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * regular ones. 93375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 93475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Likewise, we don't send out network removed signals for such 93575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * network objects. 93675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, id); 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_clear_status(wpa_s); 939c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Temporary group network not " 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found"); 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 94404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->ap_iface) 94504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_ap_deinit(wpa_s); 94604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 94704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_drv_deinit_p2p_cli(wpa_s); 94861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 94961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s, 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *go_dev_addr, 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, size_t ssid_len) 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_bss *bss; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr; 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->go_params) 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->go_params->peer_interface_addr; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->bssid; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss = wpa_bss_get(wpa_s, bssid, ssid, ssid_len); 969cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (bss == NULL && wpa_s->go_params && 970cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt !is_zero_ether_addr(wpa_s->go_params->peer_device_addr)) 971cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt bss = wpa_bss_get_p2p_dev_addr( 972cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s, wpa_s->go_params->peer_device_addr); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 iface_addr[ETH_ALEN]; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_get_interface_addr(wpa_s->global->p2p, bssid, 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface_addr) == 0) 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss = wpa_bss_get(wpa_s, iface_addr, ssid, ssid_len); 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether " 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group is persistent - BSS " MACSTR " not found", 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid)); 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE); 9879657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt if (p2p == NULL) 9889657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt p2p = wpa_bss_get_vendor_ie_multi_beacon(bss, 9899657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt P2P_IE_VENDOR_TYPE); 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) { 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether " 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group is persistent - BSS " MACSTR 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " did not include P2P IE", MAC2STR(bssid)); 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Probe Response IEs", 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) (bss + 1), bss->ie_len); 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Beacon IEs", 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((u8 *) bss + 1) + bss->ie_len, 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->beacon_ie_len); 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = p2p_get_group_capab(p2p); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr = p2p_get_go_dev_addr(p2p); 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Checking whether group is persistent: " 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group_capab=0x%x", group_capab); 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(go_dev_addr, addr, ETH_ALEN); 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO Device Address " MACSTR, 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr)); 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p); 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: BSS " MACSTR " group_capab=0x%x " 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_dev_addr=" MACSTR, 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr)); 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 102275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s, 102375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct wpa_ssid *ssid, 102475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen const u8 *go_dev_addr) 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int changed = 0; 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Storing credentials for a persistent " 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group (GO Dev Addr " MACSTR ")", MAC2STR(go_dev_addr)); 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled == 2 && 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(go_dev_addr, s->bssid, ETH_ALEN) == 0 && 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len == ssid->ssid_len && 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid->ssid, s->ssid, ssid->ssid_len) == 0) 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s) { 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Update existing persistent group " 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "entry"); 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->passphrase && !s->passphrase) 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt changed = 1; 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (ssid->passphrase && s->passphrase && 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(ssid->passphrase, s->passphrase) != 0) 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt changed = 1; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Create a new persistent group " 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "entry"); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt changed = 1; 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = wpa_config_add_network(wpa_s->conf); 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s == NULL) 105375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 105475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 105575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 105675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Instead of network_added we emit persistent_group_added 105775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * notification. Also to keep the defense checks in 105875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * persistent_group obj registration method, we set the 105975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * relevant flags in s to designate it as a persistent group. 106075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 106175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen s->p2p_group = 1; 106275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen s->p2p_persistent_group = 1; 106375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_persistent_group_added(wpa_s, s); 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_network_defaults(s); 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->p2p_group = 1; 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->p2p_persistent_group = 1; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->disabled = 2; 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->bssid_set = 1; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(s->bssid, go_dev_addr, ETH_ALEN); 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->mode = ssid->mode; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->auth_alg = WPA_AUTH_ALG_OPEN; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->key_mgmt = WPA_KEY_MGMT_PSK; 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->proto = WPA_PROTO_RSN; 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->pairwise_cipher = WPA_CIPHER_CCMP; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->export_keys = 1; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->passphrase) { 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(s->passphrase); 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->passphrase = os_strdup(ssid->passphrase); 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->psk_set) { 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->psk_set = 1; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(s->psk, ssid->psk, 32); 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->passphrase && !s->psk_set) 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_update_psk(s); 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->ssid == NULL || s->ssid_len < ssid->ssid_len) { 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(s->ssid); 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid = os_malloc(ssid->ssid_len); 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->ssid) { 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len = ssid->ssid_len; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(s->ssid, ssid->ssid, s->ssid_len); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1096391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO && wpa_s->global->add_psk) { 1097391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_add(&s->psk_list, &wpa_s->global->add_psk->list); 1098391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 1099391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt changed = 1; 1100391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (changed && wpa_s->conf->update_config && 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_write(wpa_s->confname, wpa_s->conf)) { 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 110675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 110775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return s->id; 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s, 11121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr) 11131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 11141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *ssid, *s; 11151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *n; 11161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t i; 111761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int found = 0; 11188bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s; 11191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = wpa_s->current_ssid; 11211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 11221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !ssid->p2p_persistent_group) 11231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 11241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11258bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt for (s = p2p_wpa_s->conf->ssid; s; s = s->next) { 11261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO) 11271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 11281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->ssid_len == ssid->ssid_len && 11301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0) 11311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 11321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s == NULL) 11351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 11361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) { 1138ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN, addr, 113961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ETH_ALEN) != 0) 114061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 114161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 114261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (i == s->num_p2p_clients - 1) 114361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; /* already the most recent entry */ 114461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 114561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* move the entry to mark it most recent */ 1146ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN, 1147ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt s->p2p_client_list + (i + 1) * 2 * ETH_ALEN, 1148ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN); 114961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(s->p2p_client_list + 1150ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt (s->num_p2p_clients - 1) * 2 * ETH_ALEN, addr, 1151ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ETH_ALEN); 1152ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memset(s->p2p_client_list + 1153ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN, 1154ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 0xff, ETH_ALEN); 115561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt found = 1; 115661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 11571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 115961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) { 116061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt n = os_realloc_array(s->p2p_client_list, 1161ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt s->num_p2p_clients + 1, 2 * ETH_ALEN); 116261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (n == NULL) 116361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 1164ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memcpy(n + s->num_p2p_clients * 2 * ETH_ALEN, addr, 1165ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ETH_ALEN); 1166ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memset(n + s->num_p2p_clients * 2 * ETH_ALEN + ETH_ALEN, 1167ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 0xff, ETH_ALEN); 116861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->p2p_client_list = n; 116961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->num_p2p_clients++; 11706aa8ae4b6139bdf5593301474277dcdbc2528190Dmitry Shmidt } else if (!found && s->p2p_client_list) { 117161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Not enough room for an additional entry - drop the oldest 117261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * entry */ 117361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memmove(s->p2p_client_list, 1174ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt s->p2p_client_list + 2 * ETH_ALEN, 1175ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt (s->num_p2p_clients - 1) * 2 * ETH_ALEN); 117661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(s->p2p_client_list + 1177ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt (s->num_p2p_clients - 1) * 2 * ETH_ALEN, 117861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt addr, ETH_ALEN); 1179ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memset(s->p2p_client_list + 1180ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN, 1181ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 0xff, ETH_ALEN); 118261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 11831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11848bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt if (p2p_wpa_s->conf->update_config && 11858bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt wpa_config_write(p2p_wpa_s->confname, p2p_wpa_s->conf)) 11861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 11871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 11881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11907f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidtstatic void wpas_p2p_group_started(struct wpa_supplicant *wpa_s, 11917f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt int go, struct wpa_ssid *ssid, int freq, 11927f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt const u8 *psk, const char *passphrase, 11937f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt const u8 *go_dev_addr, int persistent, 11947f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt const char *extra) 11957f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt{ 11967f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt const char *ssid_txt; 11977f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt char psk_txt[65]; 11987f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt 11997f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt if (psk) 12007f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt wpa_snprintf_hex(psk_txt, sizeof(psk_txt), psk, 32); 12017f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt else 12027f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt psk_txt[0] = '\0'; 12037f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt 12047f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt if (ssid) 12057f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len); 12067f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt else 12077f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ssid_txt = ""; 12087f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt 12097f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt if (passphrase && passphrase[0] == '\0') 12107f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt passphrase = NULL; 12117f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt 12127f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt /* 12137f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt * Include PSK/passphrase only in the control interface message and 12147f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt * leave it out from the debug log entry. 12157f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt */ 12167f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt wpa_msg_global_ctrl(wpa_s->parent, MSG_INFO, 12177f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt P2P_EVENT_GROUP_STARTED 12187f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt "%s %s ssid=\"%s\" freq=%d%s%s%s%s%s go_dev_addr=" 12197f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt MACSTR "%s%s", 12207f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt wpa_s->ifname, go ? "GO" : "client", ssid_txt, freq, 12217f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt psk ? " psk=" : "", psk_txt, 12227f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt passphrase ? " passphrase=\"" : "", 12237f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt passphrase ? passphrase : "", 12247f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt passphrase ? "\"" : "", 12257f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt MAC2STR(go_dev_addr), 12267f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt persistent ? " [PERSISTENT]" : "", extra); 12277f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt wpa_printf(MSG_INFO, P2P_EVENT_GROUP_STARTED 12287f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt "%s %s ssid=\"%s\" freq=%d go_dev_addr=" MACSTR "%s%s", 12297f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt wpa_s->ifname, go ? "GO" : "client", ssid_txt, freq, 12307f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt MAC2STR(go_dev_addr), persistent ? " [PERSISTENT]" : "", 12317f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt extra); 12327f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt} 12337f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt 12347f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_group_formation_completed(struct wpa_supplicant *wpa_s, 1236a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt int success, int already_deleted) 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int client; 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int persistent; 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 124275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int network_id = -1; 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is likely called for the main interface. Update wpa_s 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to use the group interface if a new interface was created for the 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group. 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_group_formation) 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpa_s->global->p2p_group_formation; 12515605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (wpa_s->p2p_go_group_formation_completed) { 12525605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 12535605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_in_provisioning = 0; 12545605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 125521de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt wpa_s->p2p_in_invitation = 0; 12566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->group_formation_reported = 1; 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 1259b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 1260b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_FAILURE); 1261a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (already_deleted) 1262a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return; 126361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, 126461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_FORMATION_FAILED); 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 1269b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_SUCCESS); 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) { 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->mode = WPAS_MODE_P2P_GO; 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_notif_formation_done(wpa_s->p2p_group); 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_mac_addr_filter(wpa_s, NULL); 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = 0; 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid) { 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = ssid->mode == WPAS_MODE_INFRA; 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = ssid->p2p_persistent_group; 1283497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr, 1284497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt ETH_ALEN); 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = wpas_p2p_persistent_group(wpa_s, 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_dev_addr, 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid, 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len); 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = wpa_s->p2p_group_interface == 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_GROUP_INTERFACE_CLIENT; 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 0; 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client) { 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Indicate event only after successfully completed 4-way 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake, i.e., when the interface is ready for data 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * packets. 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 1; 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 13057f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt wpas_p2p_group_started(wpa_s, 1, ssid, 13067f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ssid ? ssid->frequency : 0, 13077f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ssid && ssid->passphrase == NULL && 13087f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ssid->psk_set ? ssid->psk : NULL, 13097f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ssid ? ssid->passphrase : NULL, 13107f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt go_dev_addr, persistent, ""); 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_cross_connect_setup(wpa_s); 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (persistent) 131675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = wpas_p2p_store_persistent_group(wpa_s->parent, 131775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ssid, go_dev_addr); 1318391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else { 1319391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(wpa_s->global->add_psk); 1320391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 1321391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 13221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (network_id < 0 && ssid) 132375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = ssid->id; 132492c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt if (!client) { 132575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0); 1326fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&wpa_s->global->p2p_go_wait_client); 132792c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt } 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1331fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstruct send_action_work { 1332fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned int freq; 1333fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt u8 dst[ETH_ALEN]; 1334fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt u8 src[ETH_ALEN]; 1335fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt u8 bssid[ETH_ALEN]; 1336fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt size_t len; 1337fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned int wait_time; 1338fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt u8 buf[0]; 1339fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}; 1340fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1341fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1342fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_send_action_work_timeout(void *eloop_ctx, 1343fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt void *timeout_ctx) 1344fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 1345fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 1346fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1347fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (!wpa_s->p2p_send_action_work) 1348fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 1349fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1350fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Send Action frame radio work timed out"); 1351fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(wpa_s->p2p_send_action_work->ctx); 1352fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt radio_work_done(wpa_s->p2p_send_action_work); 1353fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_send_action_work = NULL; 1354fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 1355fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1356fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 135703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidtstatic void wpas_p2p_action_tx_clear(struct wpa_supplicant *wpa_s) 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1359fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->p2p_send_action_work) { 1360fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct send_action_work *awork; 1361fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt awork = wpa_s->p2p_send_action_work->ctx; 1362fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (awork->wait_time == 0) { 1363fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(awork); 1364fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt radio_work_done(wpa_s->p2p_send_action_work); 1365fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_send_action_work = NULL; 1366fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else { 1367fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt /* 1368fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * In theory, this should not be needed, but number of 1369fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * places in the P2P code is still using non-zero wait 1370fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * time for the last Action frame in the sequence and 1371fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * some of these do not call send_action_done(). 1372fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt */ 1373fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_send_action_work_timeout, 1374fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s, NULL); 1375fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt eloop_register_timeout( 1376fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 0, awork->wait_time * 1000, 1377fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_send_action_work_timeout, 1378fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s, NULL); 1379fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1380fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 138103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt} 138203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 138303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 138403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidtstatic void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s, 138503658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt unsigned int freq, 138603658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt const u8 *dst, const u8 *src, 138703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt const u8 *bssid, 138803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt const u8 *data, size_t data_len, 138903658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt enum offchannel_send_action_result 139003658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt result) 139103658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt{ 139203658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt enum p2p_send_action_result res = P2P_SEND_ACTION_SUCCESS; 139303658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 139403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt wpas_p2p_action_tx_clear(wpa_s); 1395fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (result) { 14001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OFFCHANNEL_SEND_ACTION_SUCCESS: 14011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = P2P_SEND_ACTION_SUCCESS; 14021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 14031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OFFCHANNEL_SEND_ACTION_NO_ACK: 14041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = P2P_SEND_ACTION_NO_ACK; 14051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 14061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OFFCHANNEL_SEND_ACTION_FAILED: 14071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = P2P_SEND_ACTION_FAILED; 14081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res); 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1413c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (result != OFFCHANNEL_SEND_ACTION_SUCCESS && 1414c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->pending_pd_before_join && 14151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 || 1416d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0) && 1417d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->p2p_fallback_to_go_neg) { 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 1419d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req " 1420d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "during p2p_connect-auto"); 14217f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 14227f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt P2P_EVENT_FALLBACK_TO_GO_NEG 14237f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "reason=no-ACK-to-PD-Req"); 1424d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_fallback_to_go_neg(wpa_s, 0); 1425d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1430fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_send_action_cb(struct wpa_radio_work *work, int deinit) 1431fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 1432fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_supplicant *wpa_s = work->wpa_s; 1433fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct send_action_work *awork = work->ctx; 1434fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1435fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (deinit) { 1436bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (work->started) { 1437bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_send_action_work_timeout, 1438bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_s, NULL); 1439bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_s->p2p_send_action_work = NULL; 1440bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt offchannel_send_action_done(wpa_s); 1441bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1442fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(awork); 1443fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 1444fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1445fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1446fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (offchannel_send_action(wpa_s, awork->freq, awork->dst, awork->src, 1447fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt awork->bssid, awork->buf, awork->len, 1448fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt awork->wait_time, 1449fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_send_action_tx_status, 1) < 0) { 1450fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(awork); 1451fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt radio_work_done(work); 1452fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 1453fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1454fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_send_action_work = work; 1455fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 1456fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1457fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1458fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int wpas_send_action_work(struct wpa_supplicant *wpa_s, 1459fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned int freq, const u8 *dst, 1460fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 1461fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt size_t len, unsigned int wait_time) 1462fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 1463fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct send_action_work *awork; 1464fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1465fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->p2p_send_action_work) { 1466fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot schedule new p2p-send-action work since one is already pending"); 1467fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 1468fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1469fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1470fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt awork = os_zalloc(sizeof(*awork) + len); 1471fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (awork == NULL) 1472fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 1473fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1474fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt awork->freq = freq; 1475fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memcpy(awork->dst, dst, ETH_ALEN); 1476fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memcpy(awork->src, src, ETH_ALEN); 1477fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memcpy(awork->bssid, bssid, ETH_ALEN); 1478fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt awork->len = len; 1479fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt awork->wait_time = wait_time; 1480fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memcpy(awork->buf, buf, len); 1481fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1482fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (radio_add_work(wpa_s, freq, "p2p-send-action", 0, 1483fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_send_action_cb, awork) < 0) { 1484fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(awork); 1485fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 1486fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1487fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1488fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 1489fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 1490fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1491fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst, 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 1497fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int listen_freq = -1, send_freq = -1; 1498fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1499fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->p2p_listen_work) 1500fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt listen_freq = wpa_s->p2p_listen_work->freq; 1501fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->p2p_send_action_work) 1502fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt send_freq = wpa_s->p2p_send_action_work->freq; 1503fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (listen_freq != (int) freq && send_freq != (int) freq) { 1504fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d)", 1505fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt listen_freq, send_freq); 1506fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf, 1507fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt len, wait_time); 1508fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1509fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1510fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use ongoing radio work for Action frame TX"); 15111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len, 15121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wait_time, 15131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_send_action_tx_status, 1); 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_send_action_done(void *ctx) 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 1520fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1521fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->p2p_send_action_work) { 1522fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_send_action_work_timeout, 1523fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s, NULL); 1524fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(wpa_s->p2p_send_action_work->ctx); 1525fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt radio_work_done(wpa_s->p2p_send_action_work); 1526fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_send_action_work = NULL; 1527fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1528fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 15291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offchannel_send_action_done(wpa_s); 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_copy_go_neg_results(struct wpa_supplicant *wpa_s, 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *params) 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->go_params == NULL) { 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->go_params = os_malloc(sizeof(*params)); 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->go_params == NULL) 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->go_params, params, sizeof(*params)); 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s, 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *res) 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->group_formation_reported = 0; 1550cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Start WPS Enrollee for peer " MACSTR 1551cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt " dev_addr " MACSTR " wps_method %d", 1552cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MAC2STR(res->peer_interface_addr), 1553cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MAC2STR(res->peer_device_addr), res->wps_method); 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Start WPS Enrollee for SSID", 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->ssid, res->ssid_len); 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_deinit(wpa_s); 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_copy_go_neg_results(wpa_s, res); 1558cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (res->wps_method == WPS_PBC) { 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1); 1560cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC 1561cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (res->wps_method == WPS_NFC) { 1562cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpas_wps_start_nfc(wpa_s, res->peer_device_addr, 1563cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res->peer_interface_addr, 1564cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_oob_dev_pw, 1565cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_oob_dev_pw_id, 1, 1566cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_oob_dev_pw_id == 1567cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt DEV_PW_NFC_CONNECTION_HANDOVER ? 1568cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_peer_oob_pubkey_hash : 1569cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt NULL, 1570cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt NULL, 0, 0); 1571cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */ 1572cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else { 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 dev_pw_id = DEV_PW_DEFAULT; 1574216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (wpa_s->p2p_wps_method == WPS_P2PS) 1575216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev_pw_id = DEV_PW_P2PS_DEFAULT; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD) 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED; 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_wps_start_pin(wpa_s, res->peer_interface_addr, 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_pin, 1, dev_pw_id); 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1584391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_add_psk_list(struct wpa_supplicant *wpa_s, 1585391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *ssid) 1586391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 1587391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *persistent; 1588391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct psk_list_entry *psk; 1589391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_data *hapd; 1590391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1591391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!wpa_s->ap_iface) 1592391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 1593391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1594391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid, 1595391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid_len); 1596391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (persistent == NULL) 1597391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 1598391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1599391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hapd = wpa_s->ap_iface->bss[0]; 1600391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1601391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_for_each(psk, &persistent->psk_list, struct psk_list_entry, 1602391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt list) { 1603391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_wpa_psk *hpsk; 1604391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1605391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add persistent group PSK entry for " 1606391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR " psk=%d", 1607391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(psk->addr), psk->p2p); 1608391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hpsk = os_zalloc(sizeof(*hpsk)); 1609391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (hpsk == NULL) 1610391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt break; 1611391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(hpsk->psk, psk->psk, PMK_LEN); 1612391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (psk->p2p) 1613391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(hpsk->p2p_dev_addr, psk->addr, ETH_ALEN); 1614391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else 1615391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(hpsk->addr, psk->addr, ETH_ALEN); 1616391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hpsk->next = hapd->conf->ssid.wpa_psk; 1617391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hapd->conf->ssid.wpa_psk = hpsk; 1618391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 1619391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 1620391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1621391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 16226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void p2p_go_dump_common_freqs(struct wpa_supplicant *wpa_s) 16236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 16246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt unsigned int i; 16256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Common group frequencies (len=%u):", 16276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_common_freqs_num); 16286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) 16306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d", 16316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt i, wpa_s->p2p_group_common_freqs[i]); 16326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 16336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void p2p_go_save_group_common_freqs(struct wpa_supplicant *wpa_s, 16366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct p2p_go_neg_results *params) 16376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 16386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt unsigned int i, len = int_array_len(wpa_s->go_params->freq_list); 16396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_common_freqs_num = 0; 16416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(wpa_s->p2p_group_common_freqs); 16426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_common_freqs = os_calloc(len, sizeof(int)); 16436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!wpa_s->p2p_group_common_freqs) 16446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 16456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt for (i = 0; i < len; i++) { 16476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!wpa_s->go_params->freq_list[i]) 16486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 16496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_common_freqs[i] = 16506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->go_params->freq_list[i]; 16516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 16526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_common_freqs_num = i; 16536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 16546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1656216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic void p2p_config_write(struct wpa_supplicant *wpa_s) 1657216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 1658216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE 1659216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (wpa_s->parent->conf->update_config && 1660216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf)) 1661216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 1662216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */ 1663216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 1664216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1665216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_configured(void *ctx, void *data) 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *params = data; 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 167175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int network_id = -1; 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_go_save_group_common_freqs(wpa_s, params); 16746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_go_dump_common_freqs(wpa_s); 16756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_P2P_GO) { 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning"); 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_group_formation == wpa_s) 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 16817f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt wpas_p2p_group_started(wpa_s, 1, ssid, ssid->frequency, 16827f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt params->passphrase[0] == '\0' ? 16837f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt params->psk : NULL, 16847f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt params->passphrase, 16857f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt wpa_s->global->p2p_dev_addr, 16867f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt params->persistent_group, ""); 16876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->group_formation_reported = 1; 16881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1689216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (wpa_s->parent->p2ps_join_addr_valid) { 1690216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 1691216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2PS: Setting default PIN for " MACSTR, 1692216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(wpa_s->parent->p2ps_join_addr)); 1693216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_supplicant_ap_wps_pin(wpa_s, 1694216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->parent->p2ps_join_addr, 1695216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "12345670", NULL, 0, 0); 1696216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->parent->p2ps_join_addr_valid = 0; 1697216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1698216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1699fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&wpa_s->global->p2p_go_wait_client); 1700391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (params->persistent_group) { 170175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = wpas_p2p_store_persistent_group( 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent, ssid, 1703497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt wpa_s->global->p2p_dev_addr); 1704391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_p2p_add_psk_list(wpa_s, ssid); 1705391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 170675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (network_id < 0) 170775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = ssid->id; 170875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0); 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_cross_connect_setup(wpa_s); 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 17115605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 17125605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (wpa_s->p2p_first_connection_timeout) { 17135605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 17145605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "P2P: Start group formation timeout of %d seconds until first data connection on GO", 17155605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_first_connection_timeout); 17165605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_go_group_formation_completed = 0; 17175605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->global->p2p_group_formation = wpa_s; 17185605286c30e1701491bd3af974ae423727750eddDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 17195605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->parent, NULL); 17205605286c30e1701491bd3af974ae423727750eddDmitry Shmidt eloop_register_timeout( 17215605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_first_connection_timeout, 0, 17225605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpas_p2p_group_formation_timeout, 17235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->parent, NULL); 17245605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 17255605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Setting up WPS for GO provisioning"); 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_ap_mac_addr_filter(wpa_s, 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->peer_interface_addr)) { 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to setup MAC address " 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filtering"); 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1736cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (params->wps_method == WPS_PBC) { 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr, 17381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->peer_device_addr); 1739cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC 1740cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (params->wps_method == WPS_NFC) { 1741cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->parent->p2p_oob_dev_pw_id != 1742cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt DEV_PW_NFC_CONNECTION_HANDOVER && 1743cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt !wpa_s->parent->p2p_oob_dev_pw) { 1744cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known"); 1745cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return; 1746cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 1747cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpas_ap_wps_add_nfc_pw( 1748cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s, wpa_s->parent->p2p_oob_dev_pw_id, 1749cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_oob_dev_pw, 1750cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_peer_oob_pk_hash_known ? 1751cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_peer_oob_pubkey_hash : NULL); 1752cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */ 1753cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (wpa_s->p2p_pin[0]) 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr, 1755d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->p2p_pin, NULL, 0, 0); 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->go_params); 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->go_params = NULL; 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_start_wps_go(struct wpa_supplicant *wpa_s, 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *params, 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int group_formation) 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1767aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Starting GO"); 1768aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (wpas_copy_go_neg_results(wpa_s, params) < 0) { 1769aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not copy GO Negotiation " 1770aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "results"); 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1772aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_config_add_network(wpa_s->conf); 1775aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (ssid == NULL) { 1776aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not add network for GO"); 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1778aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->show_group_started = 0; 17816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_go_group_formation_completed = 0; 17826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->group_formation_reported = 0; 17831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_network_defaults(ssid); 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->temporary = 1; 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->p2p_group = 1; 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->p2p_persistent_group = params->persistent_group; 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION : 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPAS_MODE_P2P_GO; 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->frequency = params->freq; 179161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ssid->ht40 = params->ht40; 179268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt ssid->vht = params->vht; 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid = os_zalloc(params->ssid_len + 1); 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->ssid) { 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid->ssid, params->ssid, params->ssid_len); 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len = params->ssid_len; 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->auth_alg = WPA_AUTH_ALG_OPEN; 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->key_mgmt = WPA_KEY_MGMT_PSK; 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->proto = WPA_PROTO_RSN; 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->pairwise_cipher = WPA_CIPHER_CCMP; 18026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ssid->group_cipher = WPA_CIPHER_CCMP; 18036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->freq > 56160) { 18046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 18056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Enable GCMP instead of CCMP as pairwise_cipher and 18066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * group_cipher in 60 GHz. 18076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 18086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ssid->pairwise_cipher = WPA_CIPHER_GCMP; 18096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ssid->group_cipher = WPA_CIPHER_GCMP; 18106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 1811a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (os_strlen(params->passphrase) > 0) { 1812a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ssid->passphrase = os_strdup(params->passphrase); 1813a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (ssid->passphrase == NULL) { 1814b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_ERROR, 1815b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "P2P: Failed to copy passphrase for GO"); 1816a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, ssid->id); 1817a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return; 1818a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1819a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else 1820a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ssid->passphrase = NULL; 1821d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid->psk_set = params->psk_set; 1822d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (ssid->psk_set) 1823d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(ssid->psk, params->psk, sizeof(ssid->psk)); 1824a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else if (ssid->passphrase) 1825d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_config_update_psk(ssid); 182661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ssid->ap_max_inactivity = wpa_s->parent->conf->p2p_go_max_inactivity; 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ap_configured_cb = p2p_go_configured; 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ap_configured_cb_ctx = wpa_s; 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ap_configured_cb_data = wpa_s->go_params; 18316dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt wpa_s->scan_req = NORMAL_SCAN_REQ; 183275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->connect_without_scan = ssid; 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->reassociate = 1; 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->disconnected = 0; 1835aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Request scan (that will be skipped) to " 1836aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "start GO)"); 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 0, 0); 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_clone_config(struct wpa_supplicant *dst, 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_supplicant *src) 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_config *d; 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_config *s; 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d = dst->conf; 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = src->conf; 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define C(n) if (s->n) d->n = os_strdup(s->n) 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(device_name); 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(manufacturer); 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(model_name); 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(model_number); 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(serial_number); 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(config_methods); 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef C 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN); 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(d->sec_device_type, s->sec_device_type, 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(d->sec_device_type)); 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d->num_sec_device_types = s->num_sec_device_types; 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d->p2p_group_idle = s->p2p_group_idle; 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d->p2p_intra_bss = s->p2p_intra_bss; 18661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt d->persistent_reconnect = s->persistent_reconnect; 186704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt d->max_num_sta = s->max_num_sta; 186804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt d->pbc_in_m1 = s->pbc_in_m1; 1869444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt d->ignore_old_scan_res = s->ignore_old_scan_res; 187051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt d->beacon_int = s->beacon_int; 18711846323989242844f0e857458a8939fa5836429cDmitry Shmidt d->dtim_period = s->dtim_period; 18727f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt d->p2p_go_ctwindow = s->p2p_go_ctwindow; 1873b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt d->disassoc_low_ack = s->disassoc_low_ack; 18749657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt d->disable_scan_offload = s->disable_scan_offload; 1875807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt d->passive_scan = s->passive_scan; 1876cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 1877cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (s->wps_nfc_dh_privkey && s->wps_nfc_dh_pubkey) { 1878cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt d->wps_nfc_dh_privkey = wpabuf_dup(s->wps_nfc_dh_privkey); 1879cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt d->wps_nfc_dh_pubkey = wpabuf_dup(s->wps_nfc_dh_pubkey); 1880cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 1881a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt d->p2p_cli_probe = s->p2p_cli_probe; 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s, 188634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *ifname, size_t len) 188734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 188834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *ifname_ptr = wpa_s->ifname; 188934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 189034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX, 189134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) { 189234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1; 189334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 189434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 189534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx); 189634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (os_strlen(ifname) >= IFNAMSIZ && 189734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_strlen(wpa_s->ifname) < IFNAMSIZ) { 18986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int res; 18996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 190034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt /* Try to avoid going over the IFNAMSIZ length limit */ 19016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt res = os_snprintf(ifname, len, "p2p-%d", wpa_s->p2p_group_idx); 19026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(len, res) && len) 19036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ifname[len - 1] = '\0'; 190434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 190534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 190634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 190734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s, 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_driver_if_type type) 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char ifname[120], force_ifname[120]; 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->pending_interface_name[0]) { 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Pending virtual interface exists " 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "- skip creation of a new one"); 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(wpa_s->pending_interface_addr)) { 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Pending virtual address " 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unknown?! ifname='%s'", 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name); 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 192534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname)); 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_ifname[0] = '\0'; 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group", 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname); 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group_idx++; 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_type = type; 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_if_add(wpa_s, type, ifname, NULL, NULL, force_ifname, 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_addr, NULL) < 0) { 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to create new group " 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface"); 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_ifname[0]) { 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s", 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_ifname); 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->pending_interface_name, force_ifname, 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->pending_interface_name)); 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->pending_interface_name, ifname, 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->pending_interface_name)); 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Created pending virtual interface %s addr " 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, wpa_s->pending_interface_name, 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_interface_addr)); 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_remove_pending_group_interface( 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s) 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->pending_interface_name[0] || 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt is_zero_ether_addr(wpa_s->pending_interface_addr)) 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending virtual interface */ 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Removing pending group interface %s", 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name); 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_if_remove(wpa_s, wpa_s->pending_interface_type, 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name); 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN); 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 1969216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->global->pending_group_iface_for_p2ps = 0; 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go) 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_interface iface; 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group_wpa_s; 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->pending_interface_name[0]) { 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: No pending group interface"); 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpas_p2p_create_iface(wpa_s)) 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Something has forced us to remove the pending interface; try 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to create a new one and hope for the best that we will get 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the same local address. 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO : 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_IF_P2P_CLIENT) < 0) 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&iface, 0, sizeof(iface)); 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.ifname = wpa_s->pending_interface_name; 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.driver = wpa_s->driver->name; 199634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (wpa_s->conf->ctrl_interface == NULL && 199734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->parent != wpa_s && 199834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->p2p_mgmt && 199934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) 200034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface; 200134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else 200234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.ctrl_interface = wpa_s->conf->ctrl_interface; 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.driver_param = wpa_s->conf->driver_param; 2004203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s); 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s == NULL) { 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to create new " 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wpa_supplicant interface"); 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->p2p_group_interface = go ? P2P_GROUP_INTERFACE_GO : 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_GROUP_INTERFACE_CLIENT; 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = group_wpa_s; 2014216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->global->pending_group_iface_for_p2ps = 0; 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clone_config(group_wpa_s, wpa_s); 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group_wpa_s; 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_formation_timeout(void *eloop_ctx, 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *timeout_ctx) 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out"); 2027a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpas_p2p_group_formation_failed(wpa_s, 0); 202834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 202934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 203034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 2031a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidtstatic void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s, 2032a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt int already_deleted) 203334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 203434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 203534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->parent, NULL); 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_formation_failed(wpa_s->global->p2p); 2038a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpas_group_formation_completed(wpa_s, 0, already_deleted); 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2042fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_grpform_fail_after_wps(struct wpa_supplicant *wpa_s) 2043fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 2044fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Reject group formation due to WPS provisioning failure"); 2045fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 2046fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->parent, NULL); 2047fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout, 2048fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->parent, NULL); 2049fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->global->p2p_fail_on_wps_complete = 0; 2050fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2051fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2052fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2053391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s) 2054391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 2055391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->global->p2p_group_formation != wpa_s) 2056391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 2057391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Speed up group formation timeout since this cannot succeed */ 2058391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 2059391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->parent, NULL); 2060391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout, 2061391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->parent, NULL); 2062391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 2063391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 2064391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 2065fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res) 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_cancel_remain_on_channel(wpa_s); 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->off_channel_freq = 0; 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->roc_waiting_drv_freq = 0; 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->status) { 2076b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 2077b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GO_NEG_FAILURE "status=%d", 2078b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt res->status); 20791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_notify_p2p_go_neg_completed(wpa_s, res); 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->p2p_go_ht40) 208561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res->ht40 = 1; 208668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (wpa_s->p2p_go_vht) 208768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res->vht = 1; 208861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2089b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS "role=%s " 2090b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt "freq=%d ht40=%d peer_dev=" MACSTR " peer_iface=" MACSTR 2091b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt " wps_method=%s", 2092b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt res->role_go ? "GO" : "client", res->freq, res->ht40, 2093b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt MAC2STR(res->peer_device_addr), 2094b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt MAC2STR(res->peer_interface_addr), 2095b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_wps_method_text(res->wps_method)); 20961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_notify_p2p_go_neg_completed(wpa_s, res); 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 209804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (res->role_go && wpa_s->p2p_persistent_id >= 0) { 209904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid; 210004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, 210104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id); 210204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid && ssid->disabled == 2 && 210304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->mode == WPAS_MODE_P2P_GO && ssid->passphrase) { 210404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t len = os_strlen(ssid->passphrase); 210504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Override passphrase based " 210604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "on requested persistent group"); 210704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(res->passphrase, ssid->passphrase, len); 210804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res->passphrase[len] = '\0'; 210904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 211004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 211104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->create_p2p_iface) { 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group_wpa_s = 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_init_group_interface(wpa_s, res->role_go); 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s == NULL) { 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 2117d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, 2118d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt wpa_s, NULL); 2119a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpas_p2p_group_formation_failed(wpa_s, 1); 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s != wpa_s) { 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_wpa_s->p2p_pin, wpa_s->p2p_pin, 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(group_wpa_s->p2p_pin)); 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->p2p_wps_method = wpa_s->p2p_wps_method; 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN); 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->p2p_in_provisioning = 1; 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->role_go) 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(group_wpa_s, res, 1); 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_enrollee(group_wpa_s, res); 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_in_provisioning = 1; 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = wpa_s; 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->role_go) 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(wpa_s, res, 1); 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_enrollee(ctx, res); 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(15 + res->peer_config_timeout / 100, 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (res->peer_config_timeout % 100) * 10000, 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_formation_timeout, wpa_s, NULL); 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21557a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidtstatic void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id, 21567a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt u8 go_intent) 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 2159b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_REQUEST MACSTR 21607a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt " dev_passwd_id=%u go_intent=%u", MAC2STR(src), 21617a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt dev_passwd_id, go_intent); 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21637a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent); 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2167fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_dev_found(void *ctx, const u8 *addr, 2168fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const struct p2p_peer_info *info, 2169fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int new_device) 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 217404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt char *wfd_dev_info_hex = NULL; 217504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 21768367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#ifdef CONFIG_WIFI_DISPLAY 217704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt wfd_dev_info_hex = wifi_display_subelem_hex(info->wfd_subelems, 217804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt WFD_SUBELEM_DEVICE_INFO); 21798367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#endif /* CONFIG_WIFI_DISPLAY */ 218004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 2181216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (info->p2ps_instance) { 2182216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt char str[256]; 2183216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *buf = wpabuf_head(info->p2ps_instance); 2184216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t len = wpabuf_len(info->p2ps_instance); 2185216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2186216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt while (len) { 2187216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u32 id; 2188216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u16 methods; 2189216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 str_len; 2190216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2191216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (len < 4 + 2 + 1) 2192216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 2193216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt id = WPA_GET_LE32(buf); 2194216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf += sizeof(u32); 2195216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt methods = WPA_GET_BE16(buf); 2196216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf += sizeof(u16); 2197216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt str_len = *buf++; 2198216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (str_len > len - 4 - 2 - 1) 2199216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 2200216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(str, buf, str_len); 2201216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt str[str_len] = '\0'; 2202216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf += str_len; 2203216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt len -= str_len + sizeof(u32) + sizeof(u16) + sizeof(u8); 2204216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2205216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 2206216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_EVENT_DEVICE_FOUND MACSTR 2207216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " p2p_dev_addr=" MACSTR 2208216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " pri_dev_type=%s name='%s'" 2209216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " config_methods=0x%x" 2210216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " dev_capab=0x%x" 2211216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " group_capab=0x%x" 2212216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_id=%x asp_svc=%s%s", 2213216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(addr), 2214216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(info->p2p_device_addr), 2215216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wps_dev_type_bin2str( 2216216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt info->pri_dev_type, 2217216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt devtype, sizeof(devtype)), 2218216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt info->device_name, methods, 2219216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt info->dev_capab, info->group_capab, 2220216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt id, str, 2221216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt info->vendor_elems ? 2222216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " vendor_elems=1" : ""); 2223216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2224216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto done; 2225216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 2226216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 2227b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR 2228b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " p2p_dev_addr=" MACSTR 2229b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " pri_dev_type=%s name='%s' config_methods=0x%x " 22306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "dev_capab=0x%x group_capab=0x%x%s%s%s new=%d", 2231b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(addr), MAC2STR(info->p2p_device_addr), 2232b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wps_dev_type_bin2str(info->pri_dev_type, devtype, 2233b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt sizeof(devtype)), 2234b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt info->device_name, info->config_methods, 2235b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt info->dev_capab, info->group_capab, 223604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt wfd_dev_info_hex ? " wfd_dev_info=0x" : "", 22372e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wfd_dev_info_hex ? wfd_dev_info_hex : "", 22386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt info->vendor_elems ? " vendor_elems=1" : "", 22396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt new_device); 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2241216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtdone: 224204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_free(wfd_dev_info_hex); 22439767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 224404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device); 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_dev_lost(void *ctx, const u8 *dev_addr) 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 22521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2253b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST 2254b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "p2p_dev_addr=" MACSTR, MAC2STR(dev_addr)); 22551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_device_lost(wpa_s, dev_addr); 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2260b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void wpas_find_stopped(void *ctx) 2261b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 2262b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 2263b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_FIND_STOPPED); 22648bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt wpas_notify_p2p_find_stopped(wpa_s); 2265b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 2266b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 2267b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 2268fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstruct wpas_p2p_listen_work { 2269fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned int freq; 2270fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned int duration; 2271fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpabuf *probe_resp_ie; 2272fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}; 2273fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2274fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2275fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_listen_work_free(struct wpas_p2p_listen_work *lwork) 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2277fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (lwork == NULL) 2278fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 2279fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpabuf_free(lwork->probe_resp_ie); 2280fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(lwork); 2281fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2282fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2283fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2284fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_p2p_listen_work_done(struct wpa_supplicant *wpa_s) 2285fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 2286fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpas_p2p_listen_work *lwork; 2287fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2288fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (!wpa_s->p2p_listen_work) 2289fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 2290fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2291fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt lwork = wpa_s->p2p_listen_work->ctx; 2292fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_listen_work_free(lwork); 2293fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt radio_work_done(wpa_s->p2p_listen_work); 2294fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_listen_work = NULL; 2295fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2296fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_start_listen_cb(struct wpa_radio_work *work, int deinit) 2299fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 2300fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_supplicant *wpa_s = work->wpa_s; 2301fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpas_p2p_listen_work *lwork = work->ctx; 23026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt unsigned int duration; 2303fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2304fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (deinit) { 2305bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (work->started) { 2306bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_s->p2p_listen_work = NULL; 2307bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpas_stop_listen(wpa_s); 2308bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 2309fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_listen_work_free(lwork); 2310fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 2311fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2312fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2313fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_listen_work = work; 2314fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2315fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_drv_set_ap_wps_ie(wpa_s, NULL, lwork->probe_resp_ie, NULL); 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_probe_req_report(wpa_s, 1) < 0) { 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to " 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "report received Probe Request frames"); 2320fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_listen_work_done(wpa_s); 2321fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2324fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->pending_listen_freq = lwork->freq; 2325fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->pending_listen_duration = lwork->duration; 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt duration = lwork->duration; 23286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 23296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->extra_roc_dur) { 23306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "TESTING: Increase ROC duration %u -> %u", 23316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt duration, duration + wpa_s->extra_roc_dur); 23326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt duration += wpa_s->extra_roc_dur; 23336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 23346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 23356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 23366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, duration) < 0) { 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver " 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to remain on channel (%u MHz) for Listen " 2339fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt "state", lwork->freq); 2340fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_listen_work_done(wpa_s); 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_freq = 0; 2342fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->off_channel_freq = 0; 2345fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->roc_waiting_drv_freq = lwork->freq; 2346fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2347fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2348fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2349fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int wpas_start_listen(void *ctx, unsigned int freq, 2350fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned int duration, 2351fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const struct wpabuf *probe_resp_ie) 2352fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 2353fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 2354fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpas_p2p_listen_work *lwork; 2355fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2356fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->p2p_listen_work) { 2357fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Reject start_listen since p2p_listen_work already exists"); 2358fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 2359fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2360fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2361fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt lwork = os_zalloc(sizeof(*lwork)); 2362fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (lwork == NULL) 2363fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 2364fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt lwork->freq = freq; 2365fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt lwork->duration = duration; 2366fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (probe_resp_ie) { 2367fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt lwork->probe_resp_ie = wpabuf_dup(probe_resp_ie); 2368fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (lwork->probe_resp_ie == NULL) { 2369fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_listen_work_free(lwork); 2370fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 2371fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2372fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2373fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2374fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (radio_add_work(wpa_s, freq, "p2p-listen", 0, wpas_start_listen_cb, 2375fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt lwork) < 0) { 2376fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_listen_work_free(lwork); 2377fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 2378fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_stop_listen(void *ctx) 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_cancel_remain_on_channel(wpa_s); 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->off_channel_freq = 0; 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->roc_waiting_drv_freq = 0; 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_set_ap_wps_ie(wpa_s, NULL, NULL, NULL); 2393a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt 2394a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt /* 2395a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * Don't cancel Probe Request RX reporting for a connected P2P Client 2396a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt * handling Probe Request frames. 2397a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt */ 2398a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (!wpa_s->p2p_cli_probe) 2399a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpa_drv_probe_req_report(wpa_s, 0); 2400a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt 2401fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_listen_work_done(wpa_s); 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2405a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidtstatic int wpas_send_probe_resp(void *ctx, const struct wpabuf *buf, 2406a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt unsigned int freq) 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 2409a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 2410a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt freq); 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_prov_disc_local_display(struct wpa_supplicant *wpa_s, 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer, const char *params, 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int generated_pin) 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2418b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_SHOW_PIN MACSTR 2419b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " %08d%s", MAC2STR(peer), generated_pin, params); 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_prov_disc_local_keypad(struct wpa_supplicant *wpa_s, 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer, const char *params) 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2426b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_ENTER_PIN MACSTR 2427b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "%s", MAC2STR(peer), params); 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2431fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods, 2432fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const u8 *dev_addr, const u8 *pri_dev_type, 2433fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const char *dev_name, u16 supp_config_methods, 2434fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt u8 dev_capab, u8 group_capab, const u8 *group_id, 2435fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt size_t group_id_len) 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 24391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char params[300]; 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 empty_dev_type[8]; 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int generated_pin = 0; 24421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *group = NULL; 24436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int res; 24441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 24451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (group_id) { 24461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (group = wpa_s->global->ifaces; group; group = group->next) 24471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt { 24481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *s = group->current_ssid; 24491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s != NULL && 24501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt s->mode == WPAS_MODE_P2P_GO && 24511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group_id_len - ETH_ALEN == s->ssid_len && 24521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(group_id + ETH_ALEN, s->ssid, 24531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt s->ssid_len) == 0) 24541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 24551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 24561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pri_dev_type == NULL) { 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(empty_dev_type, 0, sizeof(empty_dev_type)); 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pri_dev_type = empty_dev_type; 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt res = os_snprintf(params, sizeof(params), " p2p_dev_addr=" MACSTR 24636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt " pri_dev_type=%s name='%s' config_methods=0x%x " 24646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "dev_capab=0x%x group_capab=0x%x%s%s", 24656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt MAC2STR(dev_addr), 24666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wps_dev_type_bin2str(pri_dev_type, devtype, 24676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sizeof(devtype)), 24686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dev_name, supp_config_methods, dev_capab, group_capab, 24696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt group ? " group=" : "", 24706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt group ? group->ifname : ""); 24716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(sizeof(params), res)) 24726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: PD Request event truncated"); 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params[sizeof(params) - 1] = '\0'; 2474c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config_methods & WPS_CONFIG_DISPLAY) { 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generated_pin = wps_generate_pin(); 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_prov_disc_local_display(wpa_s, peer, params, 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generated_pin); 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (config_methods & WPS_CONFIG_KEYPAD) 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_prov_disc_local_keypad(wpa_s, peer, params); 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (config_methods & WPS_CONFIG_PUSHBUTTON) 2482b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_REQ 2483b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR "%s", MAC2STR(peer), params); 248475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 248575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_provision_discovery(wpa_s, peer, 1 /* request */, 248675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_SUCCESS, 248775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen config_methods, generated_pin); 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2491fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods) 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int generated_pin = 0; 249504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char params[20]; 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2497c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (wpa_s->pending_pd_before_join && 2498c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 || 2499c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) { 2500c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 2501c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Starting pending " 2502c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "join-existing-group operation"); 2503cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpas_p2p_join_start(wpa_s, 0, NULL, 0); 2504c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return; 2505c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 2506c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 250704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->pending_pd_use == AUTO_PD_JOIN || 25086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->pending_pd_use == AUTO_PD_GO_NEG) { 25096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int res; 25106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 25116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt res = os_snprintf(params, sizeof(params), " peer_go=%d", 25126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->pending_pd_use == AUTO_PD_JOIN); 25136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(sizeof(params), res)) 25146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params[sizeof(params) - 1] = '\0'; 25156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } else 251604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params[0] = '\0'; 251704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config_methods & WPS_CONFIG_DISPLAY) 251904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_prov_disc_local_keypad(wpa_s, peer, params); 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (config_methods & WPS_CONFIG_KEYPAD) { 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generated_pin = wps_generate_pin(); 252204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_prov_disc_local_display(wpa_s, peer, params, 252304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt generated_pin); 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (config_methods & WPS_CONFIG_PUSHBUTTON) 2525b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP 2526b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR "%s", MAC2STR(peer), params); 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 252875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */, 252975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_SUCCESS, 253075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen config_methods, generated_pin); 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_prov_disc_fail(void *ctx, const u8 *peer, 2535216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt enum p2p_prov_disc_status status, 2536216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u32 adv_id, const u8 *adv_mac, 2537216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const char *deferred_session_resp) 253875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 253975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct wpa_supplicant *wpa_s = ctx; 254075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 254104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_fallback_to_go_neg) { 254204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: PD for p2p_connect-auto " 254304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "failed - fall back to GO Negotiation"); 25447f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 25457f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt P2P_EVENT_FALLBACK_TO_GO_NEG 25467f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "reason=PD-failed"); 254704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_fallback_to_go_neg(wpa_s, 0); 254804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 254904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 255004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2551d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (status == P2P_PROV_DISC_TIMEOUT_JOIN) { 25522b380488c6b5d21e54e98397c7a8d6a9f16dd8b5Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 2553d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Starting pending " 2554d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "join-existing-group operation (no ACK for PD " 2555d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "Req attempts)"); 2556cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpas_p2p_join_start(wpa_s, 0, NULL, 0); 2557d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 25582b380488c6b5d21e54e98397c7a8d6a9f16dd8b5Dmitry Shmidt } 2559d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2560216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (adv_id && adv_mac && deferred_session_resp) { 2561216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE 2562216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " p2p_dev_addr=" MACSTR " status=%d adv_id=%x" 2563216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " deferred_session_resp='%s'", 2564216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(peer), status, adv_id, 2565216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt deferred_session_resp); 2566216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (adv_id && adv_mac) { 2567216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE 2568216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " p2p_dev_addr=" MACSTR " status=%d adv_id=%x", 2569216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(peer), status, adv_id); 2570216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 2571216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE 2572216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " p2p_dev_addr=" MACSTR " status=%d", 2573216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(peer), status); 2574216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 257504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 257675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */, 257775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen status, 0, 0); 257875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 257975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 258075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 2581f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidtstatic int freq_included(const struct p2p_channels *channels, unsigned int freq) 2582f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt{ 2583f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (channels == NULL) 2584f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return 1; /* Assume no restrictions */ 2585f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return p2p_channels_includes_freq(channels, freq); 2586f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 2587f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt} 2588f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 2589f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 259043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt/** 259143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * Pick the best frequency to use from all the currently used frequencies. 259243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt */ 259343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic int wpas_p2p_pick_best_used_freq(struct wpa_supplicant *wpa_s, 259443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_used_freq_data *freqs, 259543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt unsigned int num) 259643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{ 259743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt unsigned int i, c; 259843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 259943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* find a candidate freq that is supported by P2P */ 260043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt for (c = 0; c < num; c++) 260143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p_supported_freq(wpa_s->global->p2p, freqs[c].freq)) 260243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt break; 260343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 260443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (c == num) 260543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return 0; 260643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 260743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* once we have a candidate, try to find a 'better' one */ 260843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt for (i = c + 1; i < num; i++) { 260943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (!p2p_supported_freq(wpa_s->global->p2p, freqs[i].freq)) 261043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt continue; 261143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 261243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* 261343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * 1. Infrastructure station interfaces have higher preference. 261443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * 2. P2P Clients have higher preference. 261543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * 3. All others. 261643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt */ 261743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (freqs[i].flags & WPA_FREQ_USED_BY_INFRA_STATION) { 261843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt c = i; 261943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt break; 262043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 262143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 262243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if ((freqs[i].flags & WPA_FREQ_USED_BY_P2P_CLIENT)) 262343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt c = i; 262443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 262543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return freqs[c].freq; 262643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt} 262743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 262843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid, 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_dev_addr, const u8 *ssid, 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ssid_len, int *go, u8 *group_bssid, 2632f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt int *force_freq, int persistent_group, 2633cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const struct p2p_channels *channels, 2634cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int dev_pw_id) 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 263843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_used_freq_data *freqs; 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *grp; 264043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt int best_freq; 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!persistent_group) { 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR 2644344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt " to join an active group (SSID: %s)", 2645344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt MAC2STR(sa), wpa_ssid_txt(ssid, ssid_len)); 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) && 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN) 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0 || 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0)) { 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept previously " 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authorized invitation"); 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto accept_inv; 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2654cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2655cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC 26562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (dev_pw_id >= 0 && wpa_s->p2p_nfc_tag_enabled && 26572f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt dev_pw_id == wpa_s->p2p_oob_dev_pw_id) { 2658cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept invitation based on local enabled NFC Tag"); 26592f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_s->p2p_wps_method = WPS_NFC; 26602f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_s->pending_join_wps_method = WPS_NFC; 26612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(wpa_s->pending_join_dev_addr, 2662cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt go_dev_addr, ETH_ALEN); 26632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(wpa_s->pending_join_iface_addr, 2664cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt bssid, ETH_ALEN); 2665cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt goto accept_inv; 2666cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 2667cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */ 2668cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Do not accept the invitation automatically; notify user and 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request approval. 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt grp = wpas_get_p2p_group(wpa_s, ssid, ssid_len, go); 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (grp) { 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept invitation to already " 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "running persistent group"); 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*go) 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_bssid, grp->own_addr, ETH_ALEN); 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto accept_inv; 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26857a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) && 26867a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0) { 26877a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept previously initiated " 26887a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "invitation to re-invoke a persistent group"); 268976cd2cc44b62e858f1897ce58f4ce7d0174e8839Dmitry Shmidt os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 26907a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else if (!wpa_s->conf->persistent_reconnect) 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled == 2 && 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(s->bssid, go_dev_addr, ETH_ALEN) == 0 && 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len == ssid_len && 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) == 0) 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!s) { 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested reinvocation of an unknown group", 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_UNKNOWN_GROUP; 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO && !wpas_p2p_create_iface(wpa_s)) { 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *go = 1; 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state >= WPA_AUTHENTICATING) { 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The only available " 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface is already in use - reject " 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation"); 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_bssid, wpa_s->own_addr, ETH_ALEN); 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (s->mode == WPAS_MODE_P2P_GO) { 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *go = 1; 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO) < 0) 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new " 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface address for the group"); 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_bssid, wpa_s->pending_interface_addr, 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtaccept_inv: 2730700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, 0); 2731700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 273243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt best_freq = 0; 273343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, 273443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt sizeof(struct wpa_used_freq_data)); 273543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (freqs) { 273643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt int num_channels = wpa_s->num_multichan_concurrent; 273743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt int num = wpas_p2p_valid_oper_freqs(wpa_s, freqs, num_channels); 273843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num); 273943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt os_free(freqs); 274043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 274143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 2742c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt /* Get one of the frequencies currently in use */ 274343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (best_freq > 0) { 2744a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to prefer a channel already used by one of the interfaces"); 274543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, best_freq); 2746a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt 2747a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt if (wpa_s->num_multichan_concurrent < 2 || 2748a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt wpas_p2p_num_unused_channels(wpa_s) < 1) { 2749a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No extra channels available - trying to force channel to match a channel already used by one of the interfaces"); 275043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt *force_freq = best_freq; 2751a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt } 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2754c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (*force_freq > 0 && wpa_s->num_multichan_concurrent > 1 && 2755c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpas_p2p_num_unused_channels(wpa_s) > 0) { 2756f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (*go == 0) { 2757f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt /* We are the client */ 2758f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer was found to be " 2759f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt "running a GO but we are capable of MCC, " 2760f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt "figure out the best channel to use"); 2761f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt *force_freq = 0; 2762f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt } else if (!freq_included(channels, *force_freq)) { 2763f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt /* We are the GO, and *force_freq is not in the 2764f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt * intersection */ 2765f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not " 2766f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt "in intersection but we are capable of MCC, " 2767f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt "figure out the best channel to use", 2768f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt *force_freq); 2769f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt *force_freq = 0; 2770f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt } 2771f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt } 2772f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_SUCCESS; 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, 27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, size_t ssid_len, 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_dev_addr, u8 status, 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int op_freq) 27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled == 2 && 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len == ssid_len && 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) == 0) 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status == P2P_SC_SUCCESS) { 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR 2794344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt " was accepted; op_freq=%d MHz, SSID=%s", 2795344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt MAC2STR(sa), op_freq, wpa_ssid_txt(ssid, ssid_len)); 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s) { 279791c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt int go = s->mode == WPAS_MODE_P2P_GO; 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_add_persistent( 279915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_s, s, go, 0, op_freq, 0, 0, NULL, 28005605286c30e1701491bd3af974ae423727750eddDmitry Shmidt go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0); 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (bssid) { 2802d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->user_initiated_pd = 0; 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_join(wpa_s, bssid, go_dev_addr, 2804cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_wps_method, 0, op_freq, 2805344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt ssid, ssid_len); 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " was rejected (status %u)", MAC2STR(sa), status); 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!s) { 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid) { 2818b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 2819b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_INVITATION_RECEIVED 2820b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "sa=" MACSTR " go_dev_addr=" MACSTR 2821b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " bssid=" MACSTR " unknown-network", 2822b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(sa), MAC2STR(go_dev_addr), 2823b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(bssid)); 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2825b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 2826b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_INVITATION_RECEIVED 2827b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "sa=" MACSTR " go_dev_addr=" MACSTR 2828b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " unknown-network", 2829b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(sa), MAC2STR(go_dev_addr)); 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28347a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO && op_freq) { 2835b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED 2836b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "sa=" MACSTR " persistent=%d freq=%d", 2837b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(sa), s->id, op_freq); 28387a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else { 2839b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED 2840b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "sa=" MACSTR " persistent=%d", 2841b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(sa), s->id); 28427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2846700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s, 2847700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt struct wpa_ssid *ssid, 2848391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *peer, int inv) 2849700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 2850700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt size_t i; 28518bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s; 2852700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2853700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (ssid == NULL) 2854700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; 2855700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2856700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) { 2857ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (os_memcmp(ssid->p2p_client_list + i * 2 * ETH_ALEN, peer, 2858700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ETH_ALEN) == 0) 2859700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt break; 2860700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 28616aa8ae4b6139bdf5593301474277dcdbc2528190Dmitry Shmidt if (i >= ssid->num_p2p_clients || !ssid->p2p_client_list) { 2862700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GO && 2863700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) { 2864700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d " 2865700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "due to invitation result", ssid->id); 2866700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_notify_network_removed(wpa_s, ssid); 2867700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, ssid->id); 2868700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; 2869700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 2870700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; /* Peer not found in client list */ 2871700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 2872700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2873700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent " 2874391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt "group %d client list%s", 2875391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(peer), ssid->id, 2876391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt inv ? " due to invitation result" : ""); 2877ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memmove(ssid->p2p_client_list + i * 2 * ETH_ALEN, 2878ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ssid->p2p_client_list + (i + 1) * 2 * ETH_ALEN, 2879ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt (ssid->num_p2p_clients - i - 1) * 2 * ETH_ALEN); 2880700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid->num_p2p_clients--; 28818bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt if (p2p_wpa_s->conf->update_config && 28828bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt wpa_config_write(p2p_wpa_s->confname, p2p_wpa_s->conf)) 2883700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 2884700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 2885700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2886700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2887700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s, 2888700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt const u8 *peer) 2889700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 2890700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt struct wpa_ssid *ssid; 2891700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2892700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s = wpa_s->global->p2p_invite_group; 2893700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s == NULL) 2894700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; /* No known invitation group */ 2895700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid = wpa_s->current_ssid; 2896700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 2897700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt !ssid->p2p_persistent_group) 2898700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; /* Not operating as a GO in persistent group */ 2899700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid = wpas_p2p_get_persistent(wpa_s->parent, peer, 2900700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid->ssid, ssid->ssid_len); 2901391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_remove_persistent_peer(wpa_s, ssid, peer, 1); 2902700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 2903700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2904700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 29057a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtstatic void wpas_invitation_result(void *ctx, int status, const u8 *bssid, 2906700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt const struct p2p_channels *channels, 290715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt const u8 *peer, int neg_freq, 290815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt int peer_oper_freq) 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 291215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt int freq; 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid) { 2915b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT 2916b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "status=%d " MACSTR, 2917b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt status, MAC2STR(bssid)); 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2919b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT 2920b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "status=%d ", status); 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_invitation_result(wpa_s, status, bssid); 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2924700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR, 2925700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt status, MAC2STR(peer)); 2926700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->pending_invite_ssid_id == -1) { 2927700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (status == P2P_SC_FAIL_UNKNOWN_GROUP) 2928700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_remove_persistent_client(wpa_s, peer); 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Invitation to active group */ 2930700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29327a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { 29337a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another " 29347a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "invitation exchange to indicate readiness for " 29357a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "re-invocation"); 29367a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 29377a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != P2P_SC_SUCCESS) { 2939700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (status == P2P_SC_FAIL_UNKNOWN_GROUP) { 2940700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid = wpa_config_get_network( 2941700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->conf, wpa_s->pending_invite_ssid_id); 2942391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_remove_persistent_peer(wpa_s, ssid, peer, 1); 2943700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_invite_ssid_id); 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Could not find persistent group " 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data matching with invitation"); 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29562c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen /* 29572c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * The peer could have missed our ctrl::ack frame for Invitation 29582c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * Response and continue retransmitting the frame. To reduce the 29592c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * likelihood of the peer not getting successful TX status for the 29602c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * Invitation Response frame, wait a short time here before starting 29612c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * the persistent group so that we will remain on the current channel to 29622c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * acknowledge any possible retransmission from the peer. 29632c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen */ 29642c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 50 ms wait on current channel before " 29652c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen "starting persistent group"); 29662c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen os_sleep(0, 50000); 29672c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen 296815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt if (neg_freq > 0 && ssid->mode == WPAS_MODE_P2P_GO && 296915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt freq_included(channels, neg_freq)) 297015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt freq = neg_freq; 297115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt else if (peer_oper_freq > 0 && ssid->mode != WPAS_MODE_P2P_GO && 297215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt freq_included(channels, peer_oper_freq)) 297315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt freq = peer_oper_freq; 297415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt else 297515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt freq = 0; 297615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 297715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Persistent group invitation success - op_freq=%d MHz SSID=%s", 297815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt freq, wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_add_persistent(wpa_s, ssid, 298031be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen ssid->mode == WPAS_MODE_P2P_GO, 298196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt wpa_s->p2p_persistent_go_freq, 298215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt freq, 298368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht, 298468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt channels, 29855605286c30e1701491bd3af974ae423727750eddDmitry Shmidt ssid->mode == WPAS_MODE_P2P_GO ? 29865605286c30e1701491bd3af974ae423727750eddDmitry Shmidt P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 29875605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 0); 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 299104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_p2p_disallowed_freq(struct wpa_global *global, 299204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int freq) 299304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 2994cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (freq_range_list_includes(&global->p2p_go_avoid_freq, freq)) 2995cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 1; 29964ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return freq_range_list_includes(&global->p2p_disallow_freq, freq); 299704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 299804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 299904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 300004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_add_chan(struct p2p_reg_class *reg, u8 chan) 300104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 300204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt reg->channel[reg->channels] = chan; 300304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt reg->channels++; 300404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 300504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 300604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s, 300868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_channels *chan, 300968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_channels *cli_chan) 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, cla = 0; 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->global->p2p_24ghz_social_channels = 1; 30146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 301568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memset(cli_chan, 0, sizeof(*cli_chan)); 301668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz " 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Operating class 81 - 2.4 GHz band channels 1..13 */ 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_class[cla].reg_class = 81; 302204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan->reg_class[cla].channels = 0; 302304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < 11; i++) { 302404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 2412 + i * 5)) 302504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], i + 1); 302604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 302704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan->reg_class[cla].channels) 302804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cla++; 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz " 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Operating class 115 - 5 GHz, channels 36-48 */ 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_class[cla].reg_class = 115; 303504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan->reg_class[cla].channels = 0; 303604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 36 * 5)) 303704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 36); 303804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 40 * 5)) 303904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 40); 304004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 44 * 5)) 304104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 44); 304204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 48 * 5)) 304304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 48); 304404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan->reg_class[cla].channels) 304504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cla++; 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz " 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Operating class 124 - 5 GHz, channels 149,153,157,161 */ 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_class[cla].reg_class = 124; 305204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan->reg_class[cla].channels = 0; 305304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 149 * 5)) 305404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 149); 305504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 153 * 5)) 305604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 153); 305704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 156 * 5)) 305804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 157); 305904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 161 * 5)) 306004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 161); 306104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan->reg_class[cla].channels) 306204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cla++; 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_classes = cla; 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 num_modes, 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum hostapd_hw_mode mode) 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 i; 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_modes; i++) { 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (modes[i].mode == mode) 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &modes[i]; 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtenum chan_allowed { 30856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt NOT_ALLOWED, NO_IR, ALLOWED 308668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt}; 308768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 308804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int has_channel(struct wpa_global *global, 308904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_hw_modes *mode, u8 chan, int *flags) 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 309204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int freq; 309304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 309404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq = (mode->mode == HOSTAPD_MODE_IEEE80211A ? 5000 : 2407) + 309504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan * 5; 309604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_p2p_disallowed_freq(global, freq)) 309768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < mode->num_channels; i++) { 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mode->channels[i].chan == chan) { 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags) 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *flags = mode->channels[i].flag; 310368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (mode->channels[i].flag & 310468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt (HOSTAPD_CHAN_DISABLED | 310568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt HOSTAPD_CHAN_RADAR)) 310668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 31076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (mode->channels[i].flag & HOSTAPD_CHAN_NO_IR) 31086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NO_IR; 310968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return ALLOWED; 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 311368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_oper_class_map { 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum hostapd_hw_mode mode; 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_class; 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 min_chan; 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 max_chan; 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 inc; 3123661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt enum { BW20, BW40PLUS, BW40MINUS, BW80, BW2160 } bw; 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31261d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic const struct p2p_oper_class_map op_class[] = { 312761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 }, 312861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#if 0 /* Do not enable HT40 on 2 GHz for now */ 312961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS }, 313061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS }, 313161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif 313261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20 }, 313361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20 }, 3134a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20 }, 313561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS }, 313661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS }, 313761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS }, 313861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS }, 313968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 314068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt /* 314168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center 314268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of 314368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * 80 MHz, but currently use the following definition for simplicity 314468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * (these center frequencies are not actual channels, which makes 314568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * has_channel() fail). wpas_p2p_verify_80mhz() should take care of 314668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * removing invalid channels. 314768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt */ 314868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80 }, 3149661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160 }, 315061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { -1, 0, 0, 0, 0, BW20 } 315161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}; 315261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 315361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 315468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic int wpas_p2p_get_center_80mhz(struct wpa_supplicant *wpa_s, 315568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct hostapd_hw_modes *mode, 315668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 channel) 315761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 315868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 center_channels[] = { 42, 58, 106, 122, 138, 155 }; 315968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt unsigned int i; 316061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 316168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (mode->mode != HOSTAPD_MODE_IEEE80211A) 316261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 316368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 316468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < ARRAY_SIZE(center_channels); i++) 316568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt /* 316668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48), 316768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * so the center channel is 6 channels away from the start/end. 316868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt */ 316968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (channel >= center_channels[i] - 6 && 317068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt channel <= center_channels[i] + 6) 317168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return center_channels[i]; 317268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 317368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 317468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 317568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 317668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 317768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic enum chan_allowed wpas_p2p_verify_80mhz(struct wpa_supplicant *wpa_s, 317868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct hostapd_hw_modes *mode, 317968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 channel, u8 bw) 318068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 318168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 center_chan; 318268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int i, flags; 318368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt enum chan_allowed res, ret = ALLOWED; 318468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 318568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel); 318668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (!center_chan) 318768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 318868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (center_chan >= 58 && center_chan <= 138) 318968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; /* Do not allow DFS channels for P2P */ 319068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 319168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt /* check all the channels are available */ 319268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < 4; i++) { 319368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int adj_chan = center_chan - 6 + i * 4; 319468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 319568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res = has_channel(wpa_s->global, mode, adj_chan, &flags); 319668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (res == NOT_ALLOWED) 319768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 31986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (res == NO_IR) 31996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ret = NO_IR; 320068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 320168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70)) 320268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 320368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50)) 320468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 320568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30)) 320668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 320768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10)) 320868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 320968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 321068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 321168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return ret; 321268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 321368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 321468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 321568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic enum chan_allowed wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s, 321668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct hostapd_hw_modes *mode, 321768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 channel, u8 bw) 321868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 321996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt int flag = 0; 322068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt enum chan_allowed res, res2; 322168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 322268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res2 = res = has_channel(wpa_s->global, mode, channel, &flag); 322368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (bw == BW40MINUS) { 322468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (!(flag & HOSTAPD_CHAN_HT40MINUS)) 322568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 322668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res2 = has_channel(wpa_s->global, mode, channel - 4, NULL); 322768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else if (bw == BW40PLUS) { 322868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (!(flag & HOSTAPD_CHAN_HT40PLUS)) 322968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 323068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res2 = has_channel(wpa_s->global, mode, channel + 4, NULL); 323168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else if (bw == BW80) { 323268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res2 = wpas_p2p_verify_80mhz(wpa_s, mode, channel, bw); 323368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 323468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 323568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (res == NOT_ALLOWED || res2 == NOT_ALLOWED) 323668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return NOT_ALLOWED; 32376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (res == NO_IR || res2 == NO_IR) 32386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NO_IR; 323968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return res; 324061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 324161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 324261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s, 324468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_channels *chan, 324568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_channels *cli_chan) 32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct hostapd_hw_modes *mode; 324868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int cla, op, cli_cla; 32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->hw.modes == NULL) { 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching " 32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "of all supported channels; assume dualband " 32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "support"); 325468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return wpas_p2p_default_channels(wpa_s, chan, cli_chan); 32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 325768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cla = cli_cla = 0; 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (op = 0; op_class[op].op_class; op++) { 32601d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt const struct p2p_oper_class_map *o = &op_class[op]; 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ch; 326268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *reg = NULL, *cli_reg = NULL; 32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode); 32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mode == NULL) 32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 32676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (mode->mode == HOSTAPD_MODE_IEEE80211G) 32686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->global->p2p_24ghz_social_channels = 1; 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { 327068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt enum chan_allowed res; 327168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw); 327268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (res == ALLOWED) { 327368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (reg == NULL) { 327468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Add operating class %u", 327568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o->op_class); 327668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt reg = &chan->reg_class[cla]; 327768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cla++; 327868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt reg->reg_class = o->op_class; 327968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 328068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt reg->channel[reg->channels] = ch; 328168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt reg->channels++; 32826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } else if (res == NO_IR && 328368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->conf->p2p_add_cli_chan) { 328468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cli_reg == NULL) { 328568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Add operating class %u (client only)", 328668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o->op_class); 328768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cli_reg = &cli_chan->reg_class[cli_cla]; 328868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cli_cla++; 328968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cli_reg->reg_class = o->op_class; 329068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 329168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cli_reg->channel[cli_reg->channels] = ch; 329268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cli_reg->channels++; 32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg) { 32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Channels", 32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg->channel, reg->channels); 32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 329968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cli_reg) { 330068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Channels (client only)", 330168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cli_reg->channel, cli_reg->channels); 330268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_classes = cla; 330668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cli_chan->reg_classes = cli_cla; 33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 331261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s, 331361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_hw_modes *mode, u8 channel) 331461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 331568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int op; 331668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt enum chan_allowed ret; 331761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 331861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (op = 0; op_class[op].op_class; op++) { 33191d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt const struct p2p_oper_class_map *o = &op_class[op]; 332061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 ch; 332161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 332261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { 332361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (o->mode != HOSTAPD_MODE_IEEE80211A || 3324a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt (o->bw != BW40PLUS && o->bw != BW40MINUS) || 3325a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt ch != channel) 332661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 332761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ret = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw); 332868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (ret == ALLOWED) 332961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return (o->bw == BW40MINUS) ? -1 : 1; 333061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 333161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 333261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 333361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 333461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 333561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 333668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s, 333768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct hostapd_hw_modes *mode, u8 channel) 333868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 333968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (!wpas_p2p_verify_channel(wpa_s, mode, channel, BW80)) 334068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 334168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 334268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return wpas_p2p_get_center_80mhz(wpa_s, mode, channel); 334368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 334468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 334568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf, 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buf_len) 33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(wpa_s->own_addr, interface_addr, ETH_ALEN) == 0) 33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_get_noa(wpa_s, buf, buf_len); 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3362d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstruct wpa_supplicant * wpas_get_p2p_go_iface(struct wpa_supplicant *wpa_s, 3363d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt const u8 *ssid, size_t ssid_len) 3364c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 3365d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 3366d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt struct wpa_ssid *s = wpa_s->current_ssid; 3367d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (s == NULL) 3368d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt continue; 3369d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (s->mode != WPAS_MODE_P2P_GO && 3370d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt s->mode != WPAS_MODE_AP && 3371d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt s->mode != WPAS_MODE_P2P_GROUP_FORMATION) 3372d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt continue; 3373d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (s->ssid_len != ssid_len || 337403658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) != 0) 3375d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt continue; 3376d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt return wpa_s; 3377d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt } 3378d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3379d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt return NULL; 3380d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3381d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt} 3382d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3383c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 3384d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstruct wpa_supplicant * wpas_get_p2p_client_iface(struct wpa_supplicant *wpa_s, 3385d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt const u8 *peer_dev_addr) 3386d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{ 3387c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 3388c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 3389c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid == NULL) 3390c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 3391c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid->mode != WPAS_MODE_INFRA) 3392c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 3393c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (wpa_s->wpa_state != WPA_COMPLETED && 3394c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->wpa_state != WPA_GROUP_HANDSHAKE) 3395c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 3396d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (os_memcmp(wpa_s->go_dev_addr, peer_dev_addr, ETH_ALEN) == 0) 3397d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt return wpa_s; 3398c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 3399c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 3400d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt return NULL; 3401d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt} 3402d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3403d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3404d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstatic int wpas_go_connected(void *ctx, const u8 *dev_addr) 3405d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{ 3406d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3407d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3408d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt return wpas_get_p2p_client_iface(wpa_s, dev_addr) != NULL; 3409c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 3410c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 3411c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 34121846323989242844f0e857458a8939fa5836429cDmitry Shmidtstatic int wpas_is_concurrent_session_active(void *ctx) 34131846323989242844f0e857458a8939fa5836429cDmitry Shmidt{ 34141846323989242844f0e857458a8939fa5836429cDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 34151846323989242844f0e857458a8939fa5836429cDmitry Shmidt struct wpa_supplicant *ifs; 34161846323989242844f0e857458a8939fa5836429cDmitry Shmidt 34171846323989242844f0e857458a8939fa5836429cDmitry Shmidt for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { 34181846323989242844f0e857458a8939fa5836429cDmitry Shmidt if (ifs == wpa_s) 34191846323989242844f0e857458a8939fa5836429cDmitry Shmidt continue; 34201846323989242844f0e857458a8939fa5836429cDmitry Shmidt if (ifs->wpa_state > WPA_ASSOCIATED) 34211846323989242844f0e857458a8939fa5836429cDmitry Shmidt return 1; 34221846323989242844f0e857458a8939fa5836429cDmitry Shmidt } 34231846323989242844f0e857458a8939fa5836429cDmitry Shmidt return 0; 34241846323989242844f0e857458a8939fa5836429cDmitry Shmidt} 34251846323989242844f0e857458a8939fa5836429cDmitry Shmidt 34261846323989242844f0e857458a8939fa5836429cDmitry Shmidt 3427b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void wpas_p2p_debug_print(void *ctx, int level, const char *msg) 3428b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 3429b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3430b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, level, "P2P: %s", msg); 3431b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 3432b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 3433b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 34349ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidtint wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s, 34359ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt const char *conf_p2p_dev) 343634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 343734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt struct wpa_interface iface; 343834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt struct wpa_supplicant *p2pdev_wpa_s; 343934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char ifname[100]; 344034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char force_name[100]; 344134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt int ret; 344234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 34436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ret = os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s", 34446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->ifname); 34456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(sizeof(ifname), ret)) 34466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 344734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt force_name[0] = '\0'; 344834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE; 344934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL, 345034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt force_name, wpa_s->pending_interface_addr, NULL); 345134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (ret < 0) { 345234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface"); 345334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return ret; 345434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 345534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_strlcpy(wpa_s->pending_interface_name, ifname, 345634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt sizeof(wpa_s->pending_interface_name)); 345734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 345834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_memset(&iface, 0, sizeof(iface)); 345934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.p2p_mgmt = 1; 346034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.ifname = wpa_s->pending_interface_name; 346134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.driver = wpa_s->driver->name; 346234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.driver_param = wpa_s->conf->driver_param; 34632ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt 34642ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt /* 34652ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt * If a P2P Device configuration file was given, use it as the interface 34662ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt * configuration file (instead of using parent's configuration file. 34672ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt */ 34689ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt if (conf_p2p_dev) { 34699ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt iface.confname = conf_p2p_dev; 34702ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt iface.ctrl_interface = NULL; 34712ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt } else { 34722ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt iface.confname = wpa_s->confname; 34732ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt iface.ctrl_interface = wpa_s->conf->ctrl_interface; 34742ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt } 34752ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt 3476203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s); 347734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!p2pdev_wpa_s) { 347834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface"); 347934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return -1; 348034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 348134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 348234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 348334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 348434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 348534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 348634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 3487fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_presence_resp(void *ctx, const u8 *src, u8 status, 3488fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const u8 *noa, size_t noa_len) 3489fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 3490fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_supplicant *wpa_s, *intf = ctx; 3491fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt char hex[100]; 3492fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3493fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (wpa_s = intf->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 3494fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->waiting_presence_resp) 3495fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt break; 3496fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3497fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (!wpa_s) { 3498fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No group interface was waiting for presence response"); 3499fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 3500fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3501fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->waiting_presence_resp = 0; 3502fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3503fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_snprintf_hex(hex, sizeof(hex), noa, noa_len); 3504fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PRESENCE_RESPONSE "src=" MACSTR 3505fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt " status=%u noa=%s", MAC2STR(src), status, hex); 3506fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 3507fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3508fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3509216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_get_persistent_group(void *ctx, const u8 *addr, const u8 *ssid, 3510216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t ssid_len, u8 *go_dev_addr, 3511216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 *ret_ssid, size_t *ret_ssid_len) 3512216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 3513216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3514216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *s; 3515216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3516216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s = wpas_p2p_get_persistent(wpa_s, addr, ssid, ssid_len); 3517216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (s) { 3518216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(ret_ssid, s->ssid, s->ssid_len); 3519216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *ret_ssid_len = s->ssid_len; 3520216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(go_dev_addr, s->bssid, ETH_ALEN); 3521216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 1; 3522216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3523216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3524216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 3525216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 3526216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3527216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3528216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_get_go_info(void *ctx, u8 *intended_addr, 3529216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 *ssid, size_t *ssid_len, int *group_iface) 3530216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 3531216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3532216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *s; 3533216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 bssid[ETH_ALEN]; 3534216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3535216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s = wpas_p2p_group_go_ssid(wpa_s, bssid); 3536216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!s) { 3537216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s = wpas_p2p_get_persistent_go(wpa_s); 3538216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (s) 3539216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(bssid, s->bssid, ETH_ALEN); 3540216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3541216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3542216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *group_iface = wpas_p2p_create_iface(wpa_s); 3543216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!s) 3544216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 3545216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3546216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(intended_addr, bssid, ETH_ALEN); 3547216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(ssid, s->ssid, s->ssid_len); 3548216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *ssid_len = s->ssid_len; 3549216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3550216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 1; 3551216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 3552216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3553216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3554216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_remove_stale_groups(void *ctx, const u8 *peer, const u8 *go, 3555216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *ssid, size_t ssid_len) 3556216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 3557216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3558216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *s; 3559216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int save_config = 0; 3560216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t i; 3561216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3562216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Start with our first choice of Persistent Groups */ 3563216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt while ((s = wpas_p2p_get_persistent(wpa_s, peer, NULL, 0))) { 3564216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (go && ssid && ssid_len && 3565216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s->ssid_len == ssid_len && 3566216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcmp(go, s->bssid, ETH_ALEN) == 0 && 3567216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) == 0) 3568216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 3569216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3570216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Remove stale persistent group */ 3571216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (s->mode != WPAS_MODE_P2P_GO || s->num_p2p_clients <= 1) { 3572216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, s->id); 3573216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt save_config = 1; 3574216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt continue; 3575216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3576216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3577216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (i = 0; i < s->num_p2p_clients; i++) { 3578216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN, 3579216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt peer, ETH_ALEN) != 0) 3580216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt continue; 3581216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3582216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN, 3583216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s->p2p_client_list + (i + 1) * 2 * ETH_ALEN, 3584216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN); 3585216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 3586216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3587216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s->num_p2p_clients--; 3588216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt save_config = 1; 3589216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3590216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3591216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (save_config) 3592216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_config_write(wpa_s); 3593216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3594216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Return TRUE if valid SSID remains */ 3595216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return s != NULL; 3596216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 3597216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3598216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3599216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, 3600216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *adv_mac, const u8 *ses_mac, 3601216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *grp_mac, u32 adv_id, u32 ses_id, 3602216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 conncap, int passwd_id, 3603216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *persist_ssid, 3604216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t persist_ssid_size, int response_done, 3605216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int prov_start, const char *session_info) 3606216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 3607216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3608216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 mac[ETH_ALEN]; 3609216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *persistent_go, *stale, *s; 3610216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int save_config = 0; 3611216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_supplicant *go_wpa_s; 3612216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3613216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!dev) 3614216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return; 3615216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3616216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memset(mac, 0, ETH_ALEN); 3617216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!adv_mac) 3618216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_mac = mac; 3619216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!ses_mac) 3620216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ses_mac = mac; 3621216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!grp_mac) 3622216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt grp_mac = mac; 3623216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3624216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (prov_start) { 3625216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (session_info == NULL) { 3626216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 3627216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_EVENT_P2PS_PROVISION_START MACSTR 3628216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_id=%x conncap=%x" 3629216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_mac=" MACSTR 3630216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " session=%x mac=" MACSTR 3631216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " dev_passwd_id=%d", 3632216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(dev), adv_id, conncap, 3633216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(adv_mac), 3634216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ses_id, MAC2STR(ses_mac), 3635216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id); 3636216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 3637216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 3638216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_EVENT_P2PS_PROVISION_START MACSTR 3639216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_id=%x conncap=%x" 3640216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_mac=" MACSTR 3641216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " session=%x mac=" MACSTR 3642216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " dev_passwd_id=%d info='%s'", 3643216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(dev), adv_id, conncap, 3644216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(adv_mac), 3645216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ses_id, MAC2STR(ses_mac), 3646216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id, session_info); 3647216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3648216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return; 3649216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3650216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3651216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt go_wpa_s = wpas_p2p_get_go_group(wpa_s); 3652216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persistent_go = wpas_p2p_get_persistent_go(wpa_s); 3653216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3654216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (status && status != P2P_SC_SUCCESS_DEFERRED) { 3655216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (go_wpa_s && !p2p_group_go_member_count(wpa_s)) 3656216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname); 3657216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3658216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (persistent_go && !persistent_go->num_p2p_clients) { 3659216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* remove empty persistent GO */ 3660216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, 3661216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persistent_go->id); 3662216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3663216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3664216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 3665216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_EVENT_P2PS_PROVISION_DONE MACSTR 3666216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " status=%d" 3667216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_id=%x adv_mac=" MACSTR 3668216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " session=%x mac=" MACSTR, 3669216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(dev), status, 3670216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, MAC2STR(adv_mac), 3671216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ses_id, MAC2STR(ses_mac)); 3672216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return; 3673216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3674216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3675216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Clean up stale persistent groups with this device */ 3676216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt s = wpas_p2p_get_persistent(wpa_s, dev, persist_ssid, 3677216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persist_ssid_size); 3678216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (;;) { 3679216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt stale = wpas_p2p_get_persistent(wpa_s, dev, NULL, 0); 3680216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!stale) 3681216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 3682216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3683216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (s && s->ssid_len == stale->ssid_len && 3684216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcmp(stale->bssid, s->bssid, ETH_ALEN) == 0 && 3685216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcmp(stale->ssid, s->ssid, s->ssid_len) == 0) 3686216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 3687216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3688216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Remove stale persistent group */ 3689216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (stale->mode != WPAS_MODE_P2P_GO || 3690216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt stale->num_p2p_clients <= 1) { 3691216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, stale->id); 3692216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 3693216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t i; 3694216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3695216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt for (i = 0; i < stale->num_p2p_clients; i++) { 3696216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (os_memcmp(stale->p2p_client_list + 3697216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt i * ETH_ALEN, 3698216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev, ETH_ALEN) == 0) { 3699216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memmove(stale->p2p_client_list + 3700216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt i * ETH_ALEN, 3701216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt stale->p2p_client_list + 3702216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (i + 1) * ETH_ALEN, 3703216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (stale->num_p2p_clients - 3704216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt i - 1) * ETH_ALEN); 3705216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 3706216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3707216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3708216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt stale->num_p2p_clients--; 3709216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3710216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt save_config = 1; 3711216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3712216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3713216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (save_config) 3714216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_config_write(wpa_s); 3715216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3716216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (s) { 3717216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (go_wpa_s && !p2p_group_go_member_count(wpa_s)) 3718216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname); 3719216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3720216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (persistent_go && s != persistent_go && 3721216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt !persistent_go->num_p2p_clients) { 3722216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* remove empty persistent GO */ 3723216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, 3724216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persistent_go->id); 3725216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Save config */ 3726216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3727216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3728216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 3729216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_EVENT_P2PS_PROVISION_DONE MACSTR 3730216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " status=%d" 3731216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_id=%x adv_mac=" MACSTR 3732216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " session=%x mac=" MACSTR 3733216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " persist=%d", 3734216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(dev), status, 3735216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, MAC2STR(adv_mac), 3736216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ses_id, MAC2STR(ses_mac), s->id); 3737216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return; 3738216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3739216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3740216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (conncap == P2PS_SETUP_GROUP_OWNER) { 3741216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const char *go_ifname = NULL; 3742216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!go_wpa_s) { 3743216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->global->pending_p2ps_group = 1; 3744216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3745216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (wpa_s->conf->p2p_no_group_iface) 3746216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt go_ifname = wpa_s->ifname; 3747216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (wpa_s->pending_interface_name[0]) 3748216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt go_ifname = wpa_s->pending_interface_name; 3749216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3750216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!go_ifname) { 3751216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpas_p2ps_prov_complete( 3752216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s, P2P_SC_FAIL_UNKNOWN_GROUP, 3753216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev, adv_mac, ses_mac, 3754216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt NULL, adv_id, ses_id, 0, 0, 3755216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt NULL, 0, 0, 0, NULL); 3756216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return; 3757216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3758216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3759216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* If PD Resp complete, start up the GO */ 3760216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (response_done && persistent_go) { 3761216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpas_p2p_group_add_persistent( 3762216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s, persistent_go, 3763216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, 0, 0, 0, 0, NULL, 3764216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persistent_go->mode == 3765216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt WPAS_MODE_P2P_GO ? 3766216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 3767216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0); 3768216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (response_done) { 3769216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpas_p2p_group_add(wpa_s, 1, 0, 0, 0); 3770216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3771216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3772216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (passwd_id == DEV_PW_P2PS_DEFAULT) { 3773216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(wpa_s->p2ps_join_addr, dev, ETH_ALEN); 3774216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->p2ps_join_addr_valid = 1; 3775216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 3776216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2PS: Saving PIN for " MACSTR, 3777216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(dev)); 3778216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3779216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (passwd_id == DEV_PW_P2PS_DEFAULT) { 3780216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt go_ifname = go_wpa_s->ifname; 3781216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3782216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_dbg(go_wpa_s, MSG_DEBUG, 3783216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: Setting PIN-1 For " MACSTR, MAC2STR(dev)); 3784216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_supplicant_ap_wps_pin(go_wpa_s, dev, "12345670", 3785216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt NULL, 0, 0); 3786216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3787216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(wpa_s->p2ps_join_addr, dev, ETH_ALEN); 3788216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->p2ps_join_addr_valid = 1; 3789216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 3790216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2PS: Saving PIN for " MACSTR, MAC2STR(dev)); 3791216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3792216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3793216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 3794216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_EVENT_P2PS_PROVISION_DONE MACSTR 3795216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " status=%d conncap=%x" 3796216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_id=%x adv_mac=" MACSTR 3797216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " session=%x mac=" MACSTR 3798216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " dev_passwd_id=%d go=%s", 3799216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(dev), status, conncap, 3800216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, MAC2STR(adv_mac), 3801216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ses_id, MAC2STR(ses_mac), 3802216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id, go_ifname); 3803216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return; 3804216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3805216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3806216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (go_wpa_s && !p2p_group_go_member_count(wpa_s)) 3807216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpas_p2p_group_remove(wpa_s, go_wpa_s->ifname); 3808216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3809216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (persistent_go && !persistent_go->num_p2p_clients) { 3810216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* remove empty persistent GO */ 3811216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, persistent_go->id); 3812216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3813216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3814216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (conncap == P2PS_SETUP_CLIENT) { 3815216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 3816216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_EVENT_P2PS_PROVISION_DONE MACSTR 3817216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " status=%d conncap=%x" 3818216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_id=%x adv_mac=" MACSTR 3819216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " session=%x mac=" MACSTR 3820216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " dev_passwd_id=%d join=" MACSTR, 3821216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(dev), status, conncap, 3822216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, MAC2STR(adv_mac), 3823216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ses_id, MAC2STR(ses_mac), 3824216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id, MAC2STR(grp_mac)); 3825216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 3826216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 3827216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_EVENT_P2PS_PROVISION_DONE MACSTR 3828216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " status=%d conncap=%x" 3829216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " adv_id=%x adv_mac=" MACSTR 3830216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " session=%x mac=" MACSTR 3831216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt " dev_passwd_id=%d", 3832216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(dev), status, conncap, 3833216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, MAC2STR(adv_mac), 3834216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ses_id, MAC2STR(ses_mac), 3835216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id); 3836216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3837216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 3838216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3839216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 38405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int _wpas_p2p_in_progress(void *ctx) 38415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 38425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 38435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return wpas_p2p_in_progress(wpa_s); 38445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 38455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 38465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3847216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int wpas_prov_disc_resp_cb(void *ctx) 3848216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 3849216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3850216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpa_ssid *persistent_go; 3851216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3852216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!wpa_s->global->pending_p2ps_group) 3853216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 3854216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3855216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->global->pending_p2ps_group = 0; 3856216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3857216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (wpas_p2p_get_go_group(wpa_s)) 3858216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 3859216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persistent_go = wpas_p2p_get_persistent_go(wpa_s); 3860216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3861216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (persistent_go) { 3862216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpas_p2p_group_add_persistent( 3863216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s, persistent_go, 0, 0, 0, 0, 0, NULL, 3864216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persistent_go->mode == WPAS_MODE_P2P_GO ? 3865216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0); 3866216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 3867216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpas_p2p_group_add(wpa_s, 1, 0, 0, 0); 3868216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 3869216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3870216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 1; 3871216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 3872216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3873216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 38758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_init - Initialize P2P module for %wpa_supplicant 38768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init() 38778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 38788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 38798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 38808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) 38818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_config p2p; 38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3885391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->conf->p2p_disabled) 3886391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 3887391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)) 38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 38908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p) 38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 38938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&p2p, 0, sizeof(p2p)); 38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.cb_ctx = wpa_s; 3896b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p.debug_print = wpas_p2p_debug_print; 38978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.p2p_scan = wpas_p2p_scan; 38988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.send_action = wpas_send_action; 38998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.send_action_done = wpas_send_action_done; 39008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.go_neg_completed = wpas_go_neg_completed; 39018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.go_neg_req_rx = wpas_go_neg_req_rx; 39028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.dev_found = wpas_dev_found; 39038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.dev_lost = wpas_dev_lost; 3904b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p.find_stopped = wpas_find_stopped; 39058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.start_listen = wpas_start_listen; 39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.stop_listen = wpas_stop_listen; 39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.send_probe_resp = wpas_send_probe_resp; 39088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.sd_request = wpas_sd_request; 39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.sd_response = wpas_sd_response; 39108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.prov_disc_req = wpas_prov_disc_req; 39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.prov_disc_resp = wpas_prov_disc_resp; 391275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p.prov_disc_fail = wpas_prov_disc_fail; 39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.invitation_process = wpas_invitation_process; 39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.invitation_received = wpas_invitation_received; 39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.invitation_result = wpas_invitation_result; 39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.get_noa = wpas_get_noa; 3917c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p.go_connected = wpas_go_connected; 3918fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt p2p.presence_resp = wpas_presence_resp; 39191846323989242844f0e857458a8939fa5836429cDmitry Shmidt p2p.is_concurrent_session_active = wpas_is_concurrent_session_active; 39205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt p2p.is_p2p_in_progress = _wpas_p2p_in_progress; 3921216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p.get_persistent_group = wpas_get_persistent_group; 3922216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p.get_go_info = wpas_get_go_info; 3923216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p.remove_stale_groups = wpas_remove_stale_groups; 3924216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p.p2ps_prov_complete = wpas_p2ps_prov_complete; 3925216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p.prov_disc_resp_cb = wpas_prov_disc_resp_cb; 3926216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p.p2ps_group_capability = p2ps_group_capability; 39278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN); 39291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN); 39308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.dev_name = wpa_s->conf->device_name; 39318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.manufacturer = wpa_s->conf->manufacturer; 39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.model_name = wpa_s->conf->model_name; 39338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.model_number = wpa_s->conf->model_number; 39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.serial_number = wpa_s->conf->serial_number; 39358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wps) { 39368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16); 39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.config_methods = wpa_s->wps->config_methods; 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3940661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels)) { 3941661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_printf(MSG_ERROR, 3942661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt "P2P: Failed to configure supported channel list"); 3943661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 3944661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 3945661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->p2p_listen_reg_class && 39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_listen_channel) { 39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.reg_class = wpa_s->conf->p2p_listen_reg_class; 39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.channel = wpa_s->conf->p2p_listen_channel; 395043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p.channel_forced = 1; 39518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 39528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Pick one of the social channels randomly as the listen 39548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 39558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3956661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (p2p_config_get_random_social(&p2p, &p2p.reg_class, 3957661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt &p2p.channel) != 0) { 39581d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt wpa_printf(MSG_INFO, 39591d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt "P2P: No social channels supported by the driver - do not enable P2P"); 39601d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt return 0; 3961661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 396243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p.channel_forced = 0; 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3964661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d:%d", 3965661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p.reg_class, p2p.channel); 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->p2p_oper_reg_class && 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_oper_channel) { 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_reg_class = wpa_s->conf->p2p_oper_reg_class; 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_channel = wpa_s->conf->p2p_oper_channel; 39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.cfg_op_channel = 1; 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Configured operating channel: " 39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d:%d", p2p.op_reg_class, p2p.op_channel); 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3977661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * Use random operation channel from 2.4 GHz band social 3978661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * channels (1, 6, 11) or band 60 GHz social channel (2) if no 3979661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt * other preference is indicated. 39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3981661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (p2p_config_get_random_social(&p2p, &p2p.op_reg_class, 3982661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt &p2p.op_channel) != 0) { 3983661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_printf(MSG_ERROR, 3984661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt "P2P: Failed to select random social channel as operation channel"); 3985661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 3986661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 39878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.cfg_op_channel = 0; 39888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Random operating channel: " 39898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d:%d", p2p.op_reg_class, p2p.op_channel); 39908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 399144c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 399244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt if (wpa_s->conf->p2p_pref_chan && wpa_s->conf->num_p2p_pref_chan) { 399344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p.pref_chan = wpa_s->conf->p2p_pref_chan; 399444c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p.num_pref_chan = wpa_s->conf->num_p2p_pref_chan; 399544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } 399644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 39978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) { 39988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.country, wpa_s->conf->country, 2); 39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.country[2] = 0x04; 40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.country, "XX\x04", 3); 40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type, 40048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types; 40078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type, 40088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN); 40098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.concurrent_operations = !!(wpa_s->drv_flags & 40118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_FLAGS_P2P_CONCURRENT); 40128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.max_peers = 100; 40148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->p2p_ssid_postfix) { 40168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.ssid_postfix_len = 40178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(wpa_s->conf->p2p_ssid_postfix); 40188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p.ssid_postfix_len > sizeof(p2p.ssid_postfix)) 40198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.ssid_postfix_len = sizeof(p2p.ssid_postfix); 40208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.ssid_postfix, wpa_s->conf->p2p_ssid_postfix, 40218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.ssid_postfix_len); 40228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss; 40258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4026d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p.max_listen = wpa_s->max_remain_on_chan; 4027d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 40282271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (wpa_s->conf->p2p_passphrase_len >= 8 && 40292271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt wpa_s->conf->p2p_passphrase_len <= 63) 40302271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p.passphrase_len = wpa_s->conf->p2p_passphrase_len; 40312271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt else 40322271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p.passphrase_len = 8; 40332271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 40348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->p2p = p2p_init(&p2p); 40358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p == NULL) 40368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 403704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt global->p2p_init_wpa_s = wpa_s; 40388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) { 40408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->wps_vendor_ext[i] == NULL) 40418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 40428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_wps_vendor_extension( 40438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->p2p, wpa_s->conf->wps_vendor_ext[i]); 40448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 404668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_set_no_go_freq(global->p2p, &wpa_s->conf->p2p_no_go_freq); 404768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 40488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 40538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_deinit - Deinitialize per-interface P2P data 40548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 40558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 40568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitialize per-interface P2P data. 40578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 40588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_deinit(struct wpa_supplicant *wpa_s) 40598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->driver && wpa_s->drv_priv) 40618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_probe_req_report(wpa_s, 0); 40621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 40631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->go_params) { 40641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Clear any stored provisioning info */ 40651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_clear_provisioning_info( 40661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->global->p2p, 406704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->go_params->peer_device_addr); 40681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 40691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 40708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->go_params); 40718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->go_params = NULL; 4072684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt eloop_cancel_timeout(wpas_p2p_psk_failure_removal, wpa_s, NULL); 40738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); 40748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 40758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 40768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 40778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL); 40788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 407904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL); 4080fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_listen_work_done(wpa_s); 4081fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->p2p_send_action_work) { 4082fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(wpa_s->p2p_send_action_work->ctx); 4083fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt radio_work_done(wpa_s->p2p_send_action_work); 4084fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_send_action_work = NULL; 4085fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 4086fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_send_action_work_timeout, wpa_s, NULL); 40878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(wpa_s->p2p_oob_dev_pw); 4089cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_oob_dev_pw = NULL; 4090cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 40916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(wpa_s->p2p_group_common_freqs); 40926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_common_freqs = NULL; 40936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_group_common_freqs_num = 0; 40946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 40958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: remove group interface from the driver if this wpa_s instance 40968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is on top of a P2P group interface */ 40978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 41018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_deinit_global - Deinitialize global P2P module 41028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init() 41038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 41048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitializes the global (per device) P2P module. 41058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 410643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic void wpas_p2p_deinit_global(struct wpa_global *global) 41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s, *tmp; 41098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 411061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s = global->ifaces; 411161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 4112661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpas_p2p_service_flush(global->p2p_init_wpa_s); 41138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Remove remaining P2P group interfaces */ 41158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_s && wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) 41168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpa_s->next; 41178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_s) { 41188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = global->ifaces; 41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (tmp && 41208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (tmp == wpa_s || 41218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)) { 41228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = tmp->next; 41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 412604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Disconnect from the P2P group and deinit the interface */ 412704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_disconnect(tmp); 41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 41318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Deinit GO data on any possibly remaining interface (if main 41328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface is used as GO). 41338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 41348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 41358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface) 41368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_deinit(wpa_s); 41378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_deinit(global->p2p); 41408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->p2p = NULL; 414104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt global->p2p_init_wpa_s = NULL; 41428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s) 41468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 414734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) && 414834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->conf->p2p_no_group_iface) 4149d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* separate interface disabled per configuration */ 41508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & 41518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE | 41528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P)) 41538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* P2P group requires a new interface in every case 41548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 41558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CONCURRENT)) 41568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* driver does not support concurrent operations */ 41578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->ifaces->next) 41588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* more that one interface already in use */ 41598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state >= WPA_AUTHENTICATING) 41608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* this interface is already in use */ 41618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s, 41668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer_addr, 41678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 41688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 416904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 4170d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ssid *ssid, unsigned int pref_freq) 41718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (persistent_group && wpa_s->conf->persistent_reconnect) 41731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt persistent_group = 2; 41741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 417561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 417661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Increase GO config timeout if HT40 is used since it takes some time 417761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * to scan channels for coex purposes before the BSS can be started. 417861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 417961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_config_timeout(wpa_s->global->p2p, 418061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40 ? 255 : 100, 20); 418161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 41828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect(wpa_s->global->p2p, peer_addr, wps_method, 41838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent, own_interface_addr, force_freq, 418404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt persistent_group, ssid ? ssid->ssid : NULL, 418504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid ? ssid->ssid_len : 0, 4186cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_pd_before_go_neg, pref_freq, 4187cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id : 4188cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 0); 41898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s, 41938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer_addr, 41948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 41958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 419604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 4197d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ssid *ssid, unsigned int pref_freq) 41988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (persistent_group && wpa_s->conf->persistent_reconnect) 42001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt persistent_group = 2; 42011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_authorize(wpa_s->global->p2p, peer_addr, wps_method, 42038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent, own_interface_addr, force_freq, 420404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt persistent_group, ssid ? ssid->ssid : NULL, 4205cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid ? ssid->ssid_len : 0, pref_freq, 4206cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id : 4207cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 0); 42088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s) 42128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_join_scan_count++; 42148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d", 42158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_join_scan_count); 42168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_join_scan_count > P2P_MAX_JOIN_SCAN_ATTEMPTS) { 42178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to find GO " MACSTR 42188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for join operationg - stop join attempt", 42198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_join_iface_addr)); 42208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 422104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_auto_pd) { 422204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 4223b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 4224b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_PROV_DISC_FAILURE 4225b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " p2p_dev_addr=" MACSTR " status=N/A", 4226b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 422704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 422804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 4229b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 4230b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_FAILURE); 42318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 423504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq) 423604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 423743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt int res; 423843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt unsigned int num, i; 423943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_used_freq_data *freqs; 424004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4241c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (wpas_p2p_num_unused_channels(wpa_s) > 0) { 4242c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt /* Multiple channels are supported and not all are in use */ 424304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 4244c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 424504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 424643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, 424743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt sizeof(struct wpa_used_freq_data)); 4248c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 4249c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return 1; 425004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4251c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num = wpas_p2p_valid_oper_freqs(wpa_s, freqs, 4252c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_s->num_multichan_concurrent); 425304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4254c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0; i < num; i++) { 425543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (freqs[i].freq == freq) { 4256c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Frequency %d MHz in use by another virtual interface and can be used", 4257c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freq); 4258c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = 0; 4259c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt goto exit_free; 4260c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 426104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 426204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 426343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No valid operating frequencies"); 4264c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = 1; 4265c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 4266c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtexit_free: 4267c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 4268c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return res; 426904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 427004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 427104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 427204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s, 427304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *peer_dev_addr) 427404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 427504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 427604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int updated; 427704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 427804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bss = wpa_bss_get_p2p_dev_addr(wpa_s, peer_dev_addr); 427904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss == NULL) 428004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 428104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss->last_update_idx < wpa_s->bss_update_idx) { 428204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer BSS entry not updated in the " 428304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "last scan"); 428404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 428504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 428604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4287fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt updated = os_reltime_before(&wpa_s->p2p_auto_started, 4288fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt &bss->last_update); 428904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Current BSS entry for peer updated at " 429004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "%ld.%06ld (%supdated in last scan)", 429104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bss->last_update.sec, bss->last_update.usec, 429204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt updated ? "": "not "); 429304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 429404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return updated; 429504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 429604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 429704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 42988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, 42998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res) 43008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4301344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt struct wpa_bss *bss = NULL; 43028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 43038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 iface_addr[ETH_ALEN]; 430404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 43058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 43068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 43088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 43098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 431004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS) for %sjoin", 431104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt scan_res ? (int) scan_res->num : -1, 431204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_join ? "auto_" : ""); 43138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scan_res) 43158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_scan_res_handler(wpa_s, scan_res); 43168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 431704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_auto_pd) { 431804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int join = wpas_p2p_peer_go(wpa_s, 431904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_join_dev_addr); 432004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join == 0 && 432104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry < P2P_AUTO_PD_SCAN_ATTEMPTS) { 432204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry++; 4323444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt bss = wpa_bss_get_bssid_latest( 4324444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt wpa_s, wpa_s->pending_join_dev_addr); 432504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss) { 432604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq = bss->freq; 432704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Scan retry %d for " 432804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "the peer " MACSTR " at %d MHz", 432904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry, 433004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(wpa_s-> 433104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pending_join_dev_addr), 433204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq); 4333344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpas_p2p_join_scan_req(wpa_s, freq, NULL, 0); 433404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 433504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 433604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 433704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 433804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join < 0) 433904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt join = 0; 434004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 434104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 434204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use = join ? AUTO_PD_JOIN : AUTO_PD_GO_NEG; 434304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Auto PD with " MACSTR " join=%d", 434404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr), join); 434504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_prov_disc_req(wpa_s->global->p2p, 4346216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->pending_join_dev_addr, NULL, 434704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_config_methods, join, 4348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 0, wpa_s->user_initiated_pd) < 0) { 434904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 4350b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 4351b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_PROV_DISC_FAILURE 4352b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " p2p_dev_addr=" MACSTR " status=N/A", 4353b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 435404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 435504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 435604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 435704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 435804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_auto_join) { 435904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int join = wpas_p2p_peer_go(wpa_s, 436004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_join_dev_addr); 436104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join < 0) { 436204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be " 436304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "running a GO -> use GO Negotiation"); 43647f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 43657f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt P2P_EVENT_FALLBACK_TO_GO_NEG 43667f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "reason=peer-not-running-GO"); 436704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, 436804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_pin, wpa_s->p2p_wps_method, 436904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_group, 0, 0, 0, 437004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_go_intent, 437104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_connect_freq, 437204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id, 437361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_pd_before_go_neg, 437468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->p2p_go_ht40, 437568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->p2p_go_vht); 437604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 437704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 437804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 437904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer was found running GO%s -> " 438004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "try to join the group", join ? "" : 438104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " in older scan"); 43827f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt if (!join) { 43837f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 43847f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt P2P_EVENT_FALLBACK_TO_GO_NEG_ENABLED); 438504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 1; 43867f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt } 438704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 438804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 43898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_get_oper_freq(wpa_s->global->p2p, 43908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_iface_addr); 43918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0 && 43928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_get_interface_addr(wpa_s->global->p2p, 43938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_dev_addr, 43948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface_addr) == 0 && 4395661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt os_memcmp(iface_addr, wpa_s->pending_join_dev_addr, ETH_ALEN) != 0 4396661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt && !wpa_bss_get_bssid(wpa_s, wpa_s->pending_join_iface_addr)) { 43978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Overwrite pending interface " 43988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "address for join from " MACSTR " to " MACSTR 43998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " based on newly discovered P2P peer entry", 44008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_join_iface_addr), 44018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(iface_addr)); 44028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, 44038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 44048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_get_oper_freq(wpa_s->global->p2p, 44068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_iface_addr); 44078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 0) { 44098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " 44108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from P2P peer table: %d MHz", freq); 44118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4412344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (wpa_s->p2p_join_ssid_len) { 4413344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID " 4414344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt MACSTR " and SSID %s", 4415344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt MAC2STR(wpa_s->pending_join_iface_addr), 4416344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_ssid_txt(wpa_s->p2p_join_ssid, 4417344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_s->p2p_join_ssid_len)); 4418344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr, 4419344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_s->p2p_join_ssid, 4420344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_s->p2p_join_ssid_len); 4421344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } 4422344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (!bss) { 4423344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID " 4424344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt MACSTR, MAC2STR(wpa_s->pending_join_iface_addr)); 4425344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt bss = wpa_bss_get_bssid_latest(wpa_s, 4426344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_s->pending_join_iface_addr); 4427344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } 44288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss) { 4429a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt u8 dev_addr[ETH_ALEN]; 4430a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt 44318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = bss->freq; 44328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " 4433051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt "from BSS table: %d MHz (SSID %s)", freq, 4434051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_ssid_txt(bss->ssid, bss->ssid_len)); 4435a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (p2p_parse_dev_addr((const u8 *) (bss + 1), bss->ie_len, 4436a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt dev_addr) == 0 && 4437a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_memcmp(wpa_s->pending_join_dev_addr, 4438a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpa_s->pending_join_iface_addr, ETH_ALEN) == 0 && 4439a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_memcmp(dev_addr, wpa_s->pending_join_dev_addr, 4440a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt ETH_ALEN) != 0) { 4441a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpa_printf(MSG_DEBUG, 4442a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt "P2P: Update target GO device address based on BSS entry: " MACSTR " (was " MACSTR ")", 4443a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt MAC2STR(dev_addr), 4444a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 4445a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, 4446a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt ETH_ALEN); 4447a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt } 44488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0) { 44508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 method; 44518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 445204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_check_freq_conflict(wpa_s, freq) > 0) { 4453b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 4454b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_FAILURE 4455b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "reason=FREQ_CONFLICT"); 445604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 445704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 445804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 44598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Send Provision Discovery Request " 44608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "prior to joining an existing group (GO " MACSTR 44618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " freq=%u MHz)", 44628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr), freq); 44638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_pd_before_join = 1; 44648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (wpa_s->pending_join_wps_method) { 44668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 44678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = WPS_CONFIG_KEYPAD; 44688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 44698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 44708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = WPS_CONFIG_DISPLAY; 44718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 44728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 44738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = WPS_CONFIG_PUSHBUTTON; 44748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 44758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 44768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = 0; 44778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 44788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((p2p_get_provisioning_info(wpa_s->global->p2p, 44811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->pending_join_dev_addr) == 44821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt method)) { 44831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 44841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * We have already performed provision discovery for 44851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * joining the group. Proceed directly to join 44861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * operation without duplicated provision discovery. */ 44871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Provision discovery " 44881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "with " MACSTR " already done - proceed to " 44891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "join", 44901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 44911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->pending_pd_before_join = 0; 44921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto start; 44931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 44941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 44958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_prov_disc_req(wpa_s->global->p2p, 4496216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->pending_join_dev_addr, 4497216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt NULL, method, 1, 4498d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt freq, wpa_s->user_initiated_pd) < 0) { 44998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to send Provision " 45008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Discovery Request before joining an " 45018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "existing group"); 45028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 45038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto start; 45048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to find BSS/GO - try again later"); 45098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 45108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL); 45118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_check_join_scan_limit(wpa_s); 45128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstart: 45158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start join operation immediately */ 4516cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpas_p2p_join_start(wpa_s, 0, NULL, 0); 45178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4520344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidtstatic void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq, 4521344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt const u8 *ssid, size_t ssid_len) 45228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 45248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params params; 45258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_ie, *ies; 45261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t ielen; 452704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int freqs[2] = { 0, 0 }; 45288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 45308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P Wildcard SSID */ 45328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_ssids = 1; 4533344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (ssid && ssid_len) { 4534344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt params.ssids[0].ssid = ssid; 4535344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt params.ssids[0].ssid_len = ssid_len; 4536344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt os_memcpy(wpa_s->p2p_join_ssid, ssid, ssid_len); 4537344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_s->p2p_join_ssid_len = ssid_len; 4538344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } else { 4539344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID; 4540344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN; 4541344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_s->p2p_join_ssid_len = 0; 4542344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } 45438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->wps->dev.p2p = 1; 454504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev, 454604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0, 454704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt NULL); 45488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_ie == NULL) { 45498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_scan_res_join(wpa_s, NULL); 45508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 45541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen); 45558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) { 45568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 45578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_scan_res_join(wpa_s, NULL); 45588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(ies, wps_ie); 45618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 45628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4563c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_scan_ie(wpa_s->global->p2p, ies, NULL); 45648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p_probe = 1; 45668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies = wpabuf_head(ies); 45678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies_len = wpabuf_len(ies); 45689e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt 45699e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt if (!freq) { 45709e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt int oper_freq; 45719e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt /* 45729e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * If freq is not provided, check the operating freq of the GO 45739e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt * and use a single channel scan on if possible. 45749e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt */ 45759e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt oper_freq = p2p_get_oper_freq(wpa_s->global->p2p, 45769e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt wpa_s->pending_join_iface_addr); 45779e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt if (oper_freq > 0) 45789e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt freq = oper_freq; 45799e3f8ee32a0c11c56b11985805b5492d04886a99Dmitry Shmidt } 458004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (freq > 0) { 458104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freqs[0] = freq; 458204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.freqs = freqs; 458304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 45848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 45868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Run a scan to update BSS table and start Provision Discovery once 45878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the new scan results become available. 45888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 45891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_scan(wpa_s, ¶ms); 4590444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (!ret) { 4591fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&wpa_s->scan_trigger_time); 459204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_join; 4593fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->own_scan_requested = 1; 4594444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } 45958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 45978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 45998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to start scan for join - " 46008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "try again later"); 46018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 46028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL); 46038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_check_join_scan_limit(wpa_s); 46048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 460804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx) 460904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 461004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 4611344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpas_p2p_join_scan_req(wpa_s, 0, NULL, 0); 461204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 461304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 461404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 46158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr, 461604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *dev_addr, enum p2p_wps_method wps_method, 4617cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int auto_join, int op_freq, 4618cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 46198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface " 4621cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MACSTR " dev " MACSTR " op_freq=%d)%s", 4622cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MAC2STR(iface_addr), MAC2STR(dev_addr), op_freq, 462304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt auto_join ? " (auto_join)" : ""); 4624344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (ssid && ssid_len) { 4625344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group SSID specified: %s", 4626344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_ssid_txt(ssid, ssid_len)); 4627344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } 46288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 462904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 463004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_join = !!auto_join; 46318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN); 46328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN); 46338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_wps_method = wps_method; 46348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we are not running find during connection establishment */ 46368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_stop_find(wpa_s); 46378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_join_scan_count = 0; 4639cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpas_p2p_join_scan_req(wpa_s, op_freq, ssid, ssid_len); 46408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 46418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4644cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq, 4645cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *ssid, size_t ssid_len) 46468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group; 46488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 464904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 46508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = wpas_p2p_get_group_iface(wpa_s, 0, 0); 46528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) 46538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 46548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group != wpa_s) { 46558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group->p2p_pin, wpa_s->p2p_pin, 46568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(group->p2p_pin)); 46578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->p2p_wps_method = wpa_s->p2p_wps_method; 46584b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt } else { 46594b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt /* 46604b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * Need to mark the current interface for p2p_group_formation 46614b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * when a separate group interface is not used. This is needed 46624b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * to allow p2p_cancel stop a pending p2p_connect-join. 46634b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * wpas_p2p_init_group_interface() addresses this for the case 46644b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * where a separate group interface is used. 46654b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt */ 46664b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt wpa_s->global->p2p_group_formation = wpa_s; 46678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->p2p_in_provisioning = 1; 467004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt group->p2p_fallback_to_go_neg = wpa_s->p2p_fallback_to_go_neg; 46718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 4673cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(res.peer_device_addr, wpa_s->pending_join_dev_addr, ETH_ALEN); 46748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr, 46758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 46768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = wpa_s->pending_join_wps_method; 4677cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (freq && ssid && ssid_len) { 4678cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res.freq = freq; 4679cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res.ssid_len = ssid_len; 4680cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(res.ssid, ssid, ssid_len); 4681cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else { 4682cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt bss = wpa_bss_get_bssid_latest(wpa_s, 4683cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->pending_join_iface_addr); 4684cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (bss) { 4685cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res.freq = bss->freq; 4686cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res.ssid_len = bss->ssid_len; 4687cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(res.ssid, bss->ssid, bss->ssid_len); 4688cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Join target GO operating frequency from BSS table: %d MHz (SSID %s)", 4689cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt bss->freq, 4690cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_ssid_txt(bss->ssid, bss->ssid_len)); 4691cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 469204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 469304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4694c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { 4695c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel prior to " 4696c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "starting client"); 4697c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_drv_cancel_remain_on_channel(wpa_s); 4698c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->off_channel_freq = 0; 4699c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->roc_waiting_drv_freq = 0; 4700c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 47018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_enrollee(group, &res); 47028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 47048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Allow a longer timeout for join-a-running-group than normal 15 47058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * second group formation timeout since the GO may not have authorized 47068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * our connection yet. 47078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 47088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); 47098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(60, 0, wpas_p2p_group_formation_timeout, 47108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s, NULL); 47118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 47138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47167a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtstatic int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq, 471768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int *force_freq, int *pref_freq, int go) 47187a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt{ 471943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_used_freq_data *freqs; 472043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt int res, best_freq, num_unused; 4721c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned int freq_in_use = 0, num, i; 4722c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 472343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, 472443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt sizeof(struct wpa_used_freq_data)); 4725c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 4726c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 4727c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 472843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt num = wpas_p2p_valid_oper_freqs(wpa_s, freqs, 472943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_s->num_multichan_concurrent); 473043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 473143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* 473243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * It is possible that the total number of used frequencies is bigger 473343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * than the number of frequencies used for P2P, so get the system wide 473443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * number of unused frequencies. 473543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt */ 473643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt num_unused = wpas_p2p_num_unused_channels(wpa_s); 473743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 4738b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt wpa_printf(MSG_DEBUG, 473943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt "P2P: Setup freqs: freq=%d num_MCC=%d shared_freqs=%u num_unused=%d", 474043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt freq, wpa_s->num_multichan_concurrent, num, num_unused); 4741c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 47427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (freq > 0) { 474368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int ret; 474468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (go) 474568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt ret = p2p_supported_freq(wpa_s->global->p2p, freq); 474668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt else 474768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt ret = p2p_supported_freq_cli(wpa_s->global->p2p, freq); 474868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (!ret) { 4749203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && 4750203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt ieee80211_is_dfs(freq)) { 4751203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* 4752203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * If freq is a DFS channel and DFS is offloaded 4753203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * to the driver, allow P2P GO to use it. 4754203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt */ 4755203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, 4756203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt "P2P: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded to the driver", 4757203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt freq); 4758203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } else { 4759203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, 4760203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt "P2P: The forced channel (%u MHz) is not supported for P2P uses", 4761203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt freq); 4762203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt res = -3; 4763203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt goto exit_free; 4764203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 47657a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 47667a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 4767c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0; i < num; i++) { 476843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (freqs[i].freq == freq) 4769c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freq_in_use = 1; 4770c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4771c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 477243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (num_unused <= 0 && !freq_in_use) { 4773c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz as there are no available channels", 4774c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freq); 4775c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = -2; 4776c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt goto exit_free; 47777a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 47787a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the " 47797a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "requested channel (%u MHz)", freq); 47807a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt *force_freq = freq; 4781c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt goto exit_ok; 4782c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4783c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 478443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num); 4785c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 478643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* We have a candidate frequency to use */ 478743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (best_freq > 0) { 478843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (*pref_freq == 0 && num_unused > 0) { 4789e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Try to prefer a frequency (%u MHz) we are already using", 479043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt best_freq); 479143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt *pref_freq = best_freq; 479251a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt } else { 479351a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Try to force us to use frequency (%u MHz) which is already in use", 479443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt best_freq); 479543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt *force_freq = best_freq; 4796c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 479743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } else if (num_unused > 0) { 479843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, 479943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt "P2P: Current operating channels are not available for P2P. Try to use another channel"); 480043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt *force_freq = 0; 480143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } else { 480243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, 480343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt "P2P: All channels are in use and none of them are P2P enabled. Cannot start P2P group"); 480443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt res = -2; 480543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt goto exit_free; 4806c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4807c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 4808c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtexit_ok: 4809c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = 0; 4810c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtexit_free: 4811c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 4812c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return res; 48137a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt} 48147a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 48157a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 48168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 48178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_connect - Request P2P Group Formation to be started 48188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 48198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @peer_addr: Address of the peer P2P Device 48208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pin: PIN to use during provisioning or %NULL to indicate PBC mode 48218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @persistent_group: Whether to create a persistent group 482204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @auto_join: Whether to select join vs. GO Negotiation automatically 48238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @join: Whether to join an existing group (as a client) instead of starting 48248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Group Owner negotiation; @peer_addr is BSSID in that case 48258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @auth: Whether to only authorize the connection instead of doing that and 48268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initiating Group Owner negotiation 48278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @go_intent: GO Intent or -1 to use default 48288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency for the group or 0 for auto-selection 482904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @persistent_id: Persistent group credentials to use for forcing GO 483004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * parameters or -1 to generate new values (SSID/passphrase) 483104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @pd: Whether to send Provision Discovery prior to GO Negotiation as an 483204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * interoperability workaround when initiating group formation 483361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @ht40: Start GO with 40 MHz channel width 483468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @vht: Start GO with VHT support 48358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified 48368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure, -2 on failure due to channel not currently available, 48378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * -3 if forced channel is not supported 48388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 48398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 48408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pin, enum p2p_wps_method wps_method, 484104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int persistent_group, int auto_join, int join, int auth, 484261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int go_intent, int freq, int persistent_id, int pd, 484368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int ht40, int vht) 48448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4845c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int force_freq = 0, pref_freq = 0; 48467a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int ret = 0, res; 48478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_driver_if_type iftype; 48481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *if_addr; 484904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = NULL; 48508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 48528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 485404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (persistent_id >= 0) { 485504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, persistent_id); 485604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid == NULL || ssid->disabled != 2 || 485704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->mode != WPAS_MODE_P2P_GO) 485804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 485904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 486004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4861391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(wpa_s->global->add_psk); 4862391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 4863391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 4864fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->global->p2p_fail_on_wps_complete = 0; 4865216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->global->pending_p2ps_group = 0; 4866fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 48678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go_intent < 0) 48688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent = wpa_s->conf->p2p_go_intent; 48698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auth) 48718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 48728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_wps_method = wps_method; 487404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_group = !!persistent_group; 487504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id = persistent_id; 487604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_go_intent = go_intent; 487704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_connect_freq = freq; 487804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 0; 487904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_pd_before_go_neg = !!pd; 488061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40 = !!ht40; 488168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->p2p_go_vht = !!vht; 48828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pin) 48848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin)); 48858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wps_method == WPS_PIN_DISPLAY) { 48868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = wps_generate_pin(); 48876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt res = os_snprintf(wpa_s->p2p_pin, sizeof(wpa_s->p2p_pin), 48886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "%08d", ret); 48896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(sizeof(wpa_s->p2p_pin), res)) 48906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_pin[sizeof(wpa_s->p2p_pin) - 1] = '\0'; 48918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Randomly generated PIN: %s", 48928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_pin); 48938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 48948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_pin[0] = '\0'; 48958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 489604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join || auto_join) { 48978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN]; 48988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth) { 48998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to " 49008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connect a running group from " MACSTR, 49018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 49028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); 49038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 49048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, peer_addr, ETH_ALEN); 49068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr, 49078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface_addr) < 0) { 49088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, peer_addr, ETH_ALEN); 49098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_get_dev_addr(wpa_s->global->p2p, peer_addr, 49108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr); 49118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 491204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (auto_join) { 4913fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&wpa_s->p2p_auto_started); 491404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Auto join started at " 491504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "%ld.%06ld", 491604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.sec, 491704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.usec); 491804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 4919d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->user_initiated_pd = 1; 492004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method, 4921cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt auto_join, freq, NULL, 0) < 0) 49228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 49248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 492668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq, 492768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt go_intent == 15); 49287a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (res) 49297a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return res; 4930a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, 4931a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt force_freq ? force_freq : pref_freq); 49328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s); 49348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->create_p2p_iface) { 49361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Prepare to add a new interface for the group */ 49371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt iftype = WPA_IF_P2P_GROUP; 49381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (go_intent == 15) 49391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt iftype = WPA_IF_P2P_GO; 49401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) { 49411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new " 49421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "interface for the group"); 49438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 49458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if_addr = wpa_s->pending_interface_addr; 49471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else 49481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if_addr = wpa_s->own_addr; 49498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth) { 49518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method, 49521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt go_intent, if_addr, 4953d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt force_freq, persistent_group, ssid, 4954d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pref_freq) < 0) 49558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 49578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 49591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method, 49601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt go_intent, if_addr, force_freq, 4961d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt persistent_group, ssid, pref_freq) < 0) { 49621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->create_p2p_iface) 49631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 49648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 49678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 49718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_remain_on_channel_cb - Indication of remain-on-channel start 49728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 49738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency of the channel in MHz 49748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @duration: Duration of the stay on the channel in milliseconds 49758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 49768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is called when the driver indicates that it has started the 49778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requested remain-on-channel duration. 49788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 49798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 49808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int freq, unsigned int duration) 49818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 49838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4984216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: remain-on-channel callback (off_channel_freq=%u pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u duration=%u)", 4985216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->off_channel_freq, wpa_s->pending_listen_freq, 4986216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->roc_waiting_drv_freq, freq, duration); 4987216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (wpa_s->off_channel_freq && 4988216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->off_channel_freq == wpa_s->pending_listen_freq) { 49898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_cb(wpa_s->global->p2p, wpa_s->pending_listen_freq, 49908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_duration); 49918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_freq = 0; 49927f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt } else { 49937f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore remain-on-channel callback (off_channel_freq=%u pending_listen_freq=%d freq=%u duration=%u)", 49947f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt wpa_s->off_channel_freq, wpa_s->pending_listen_freq, 49957f93d6fa14a343127754c33a03cf2f641b6ff6e4Dmitry Shmidt freq, duration); 49968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 500057cea1a480975338d84f7bbc229b4dc76e030600Jithu Janceint wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout) 50018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Limit maximum Listen state time based on driver limitation. */ 50038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout > wpa_s->max_remain_on_chan) 50048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = wpa_s->max_remain_on_chan; 50058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_listen(wpa_s->global->p2p, timeout); 50078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 50118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_cancel_remain_on_channel_cb - Remain-on-channel timeout 50128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 50138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency of the channel in MHz 50148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 50158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is called when the driver indicates that a remain-on-channel 50168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * operation has been completed, i.e., the duration on the requested channel 50178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has timed out. 50188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 50198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 50208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int freq) 50218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback " 50238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(p2p_long_listen=%d ms pending_action_tx=%p)", 5024a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->p2p_long_listen, offchannel_pending_action_tx(wpa_s)); 5025fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_listen_work_done(wpa_s); 50268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 50278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 502857cea1a480975338d84f7bbc229b4dc76e030600Jithu Jance if (wpa_s->p2p_long_listen > 0) 502957cea1a480975338d84f7bbc229b4dc76e030600Jithu Jance wpa_s->p2p_long_listen -= wpa_s->max_remain_on_chan; 50308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen_end(wpa_s->global->p2p, freq) > 0) 50318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* P2P module started a new operation */ 5032a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (offchannel_pending_action_tx(wpa_s)) 50338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 50348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_long_listen > 0) { 50358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state"); 50368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_listen_start(wpa_s, wpa_s->p2p_long_listen); 5037391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 5038391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* 5039391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * When listen duration is over, stop listen & update p2p_state 5040391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * to IDLE. 5041391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt */ 5042391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_stop_listen(wpa_s->global->p2p); 50438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 50448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 50488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_group_remove - Remove a P2P group 50498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 50508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ifname: Network interface name of the group interface or "*" to remove all 50518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * groups 50528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 50538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 50548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to remove a P2P group. This can be used to disconnect 50558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from a group in which the local end is a P2P Client or to end a P2P Group in 50568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case the local end is the Group Owner. If a virtual network interface was 50578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * created for this group, that interface will be removed. Otherwise, only the 50588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured P2P group network will be removed from the interface. 50598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 50608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname) 50618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global = wpa_s->global; 50636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_supplicant *calling_wpa_s = wpa_s; 50648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(ifname, "*") == 0) { 50668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *prev; 50678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = global->ifaces; 50688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_s) { 50698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = wpa_s; 50708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpa_s->next; 5071b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if (prev->p2p_group_interface != 5072b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt NOT_P2P_GROUP_INTERFACE || 5073b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt (prev->current_ssid && 5074b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt prev->current_ssid->p2p_group)) 50756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpas_p2p_disconnect_safely(prev, calling_wpa_s); 50768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 50778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 50788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 50798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 50818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(wpa_s->ifname, ifname) == 0) 50828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 50838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 50848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return wpas_p2p_disconnect_safely(wpa_s, calling_wpa_s); 50868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50898bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq) 50908bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 50918bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt unsigned int r; 50928bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 50938bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (freq == 2) { 50948bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 2.4 GHz " 50958bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "band"); 50968bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (wpa_s->best_24_freq > 0 && 509768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_supported_freq_go(wpa_s->global->p2p, 509868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->best_24_freq)) { 50998bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = wpa_s->best_24_freq; 51008bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use best 2.4 GHz band " 51018bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "channel: %d MHz", freq); 51028bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } else { 5103661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random((u8 *) &r, sizeof(r)) < 0) 5104661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 51058bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = 2412 + (r % 3) * 25; 51068bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use random 2.4 GHz band " 51078bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "channel: %d MHz", freq); 51088bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 51098bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 51108bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 51118bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (freq == 5) { 51128bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 5 GHz " 51138bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "band"); 51148bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (wpa_s->best_5_freq > 0 && 511568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_supported_freq_go(wpa_s->global->p2p, 51168bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_s->best_5_freq)) { 51178bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = wpa_s->best_5_freq; 51188bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use best 5 GHz band " 51198bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "channel: %d MHz", freq); 51208bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } else { 5121661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random((u8 *) &r, sizeof(r)) < 0) 5122661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 51238bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = 5180 + (r % 4) * 20; 512468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (!p2p_supported_freq_go(wpa_s->global->p2p, freq)) { 51258bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not select " 51268bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "5 GHz channel for P2P group"); 51278bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return -1; 51288bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 51298bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use random 5 GHz band " 51308bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "channel: %d MHz", freq); 51318bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 51328bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 51338bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 513468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (freq > 0 && !p2p_supported_freq_go(wpa_s->global->p2p, freq)) { 5135203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && 5136203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt ieee80211_is_dfs(freq)) { 5137203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* 5138203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * If freq is a DFS channel and DFS is offloaded to the 5139203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * driver, allow P2P GO to use it. 5140203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt */ 5141203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: " 5142203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt "%s: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded", 5143203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt __func__, freq); 5144203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt return freq; 5145203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 51468bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The forced channel for GO " 51478bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "(%u MHz) is not supported for P2P uses", 51488bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq); 51498bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return -1; 51508bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 51518bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 51528bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return freq; 51538bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 51548bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 51558bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 515643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s, 515743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct p2p_go_neg_results *params, 515843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt const struct p2p_channels *channels) 515943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{ 516043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt unsigned int i, r; 516143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 516243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* first try some random selection of the social channels */ 5163661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random((u8 *) &r, sizeof(r)) < 0) 5164661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 516543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 516643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt for (i = 0; i < 3; i++) { 516743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt params->freq = 2412 + ((r + i) % 3) * 25; 516843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) && 5169661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt freq_included(channels, params->freq) && 5170661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, params->freq)) 517143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt goto out; 517243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 517343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 517443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* try all channels in reg. class 81 */ 517543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt for (i = 0; i < 11; i++) { 517643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt params->freq = 2412 + i * 5; 517743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) && 5178661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt freq_included(channels, params->freq) && 5179661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, params->freq)) 518043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt goto out; 518143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 518243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 5183203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* try all channels in operating class 115 */ 5184203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt for (i = 0; i < 4; i++) { 5185203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt params->freq = 5180 + i * 20; 5186203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) && 5187203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt freq_included(channels, params->freq) && 5188203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, params->freq)) 5189203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt goto out; 5190203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 5191203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 5192203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* try all channels in operating class 124 */ 5193203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt for (i = 0; i < 4; i++) { 5194203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt params->freq = 5745 + i * 20; 5195203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) && 5196203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt freq_included(channels, params->freq) && 5197203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, params->freq)) 5198203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt goto out; 5199203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 5200203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 5201661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* try social channel class 180 channel 2 */ 5202661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt params->freq = 58320 + 1 * 2160; 5203661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) && 5204661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt freq_included(channels, params->freq) && 5205661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, params->freq)) 5206661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt goto out; 5207661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 5208661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* try all channels in reg. class 180 */ 5209661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt for (i = 0; i < 4; i++) { 5210661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt params->freq = 58320 + i * 2160; 5211661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) && 5212661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt freq_included(channels, params->freq) && 5213661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, params->freq)) 5214661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt goto out; 5215661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 5216661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 5217203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No 2.4, 5, or 60 GHz channel allowed"); 521843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return -1; 521943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtout: 522043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference known)", 522143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt params->freq); 522243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return 0; 522343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt} 522443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 522543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 52261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, 52271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_go_neg_results *params, 522868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int freq, int ht40, int vht, 52297a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt const struct p2p_channels *channels) 52308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 523143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_used_freq_data *freqs; 523243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt unsigned int pref_freq, cand_freq; 5233c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned int num, i; 52348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(params, 0, sizeof(*params)); 52368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->role_go = 1; 523761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params->ht40 = ht40; 523868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt params->vht = vht; 52398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq) { 52407a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!freq_included(channels, freq)) { 52417a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not " 52427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "accepted", freq); 52437a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return -1; 52447a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 52458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced " 52468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frequency %d MHz", freq); 52478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = freq; 52488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_reg_class == 81 && 52498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_oper_channel >= 1 && 52507a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_channel <= 11 && 52517a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, 52527a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 2407 + 5 * wpa_s->conf->p2p_oper_channel)) { 52538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = 2407 + 5 * wpa_s->conf->p2p_oper_channel; 52548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured " 52558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frequency %d MHz", params->freq); 52567a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else if ((wpa_s->conf->p2p_oper_reg_class == 115 || 52577a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 116 || 52587a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 117 || 52597a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 124 || 5260a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 125 || 52617a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 126 || 52627a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 127) && 52637a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, 52647a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 5000 + 5 * wpa_s->conf->p2p_oper_channel)) { 52658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel; 52668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured " 52678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frequency %d MHz", params->freq); 52688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_channel == 0 && 52698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_overall_freq > 0 && 527068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_supported_freq_go(wpa_s->global->p2p, 527168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->best_overall_freq) && 52727a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, wpa_s->best_overall_freq)) { 52738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = wpa_s->best_overall_freq; 52748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best overall " 52758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %d MHz", params->freq); 52768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_channel == 0 && 52778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_24_freq > 0 && 527868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_supported_freq_go(wpa_s->global->p2p, 527968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->best_24_freq) && 52807a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, wpa_s->best_24_freq)) { 52818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = wpa_s->best_24_freq; 52828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 2.4 GHz " 52838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %d MHz", params->freq); 52848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_channel == 0 && 52858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_5_freq > 0 && 528668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_supported_freq_go(wpa_s->global->p2p, 528768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->best_5_freq) && 52887a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, wpa_s->best_5_freq)) { 52898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = wpa_s->best_5_freq; 52908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz " 52918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %d MHz", params->freq); 529244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } else if ((pref_freq = p2p_get_pref_freq(wpa_s->global->p2p, 529344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt channels))) { 529444c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt params->freq = pref_freq; 529544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz from preferred " 529644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt "channels", params->freq); 52978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 529843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* no preference, select some channel */ 529943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (wpas_p2p_select_freq_no_pref(wpa_s, params, channels) < 0) 530004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 53018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 53028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 530343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, 530443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt sizeof(struct wpa_used_freq_data)); 5305c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 5306c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 5307c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 530843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt num = wpas_p2p_valid_oper_freqs(wpa_s, freqs, 5309c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_s->num_multichan_concurrent); 5310c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 531143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt cand_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num); 531243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 531343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* First try the best used frequency if possible */ 531443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (!freq && cand_freq > 0 && freq_included(channels, cand_freq)) { 531543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt params->freq = cand_freq; 531643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } else if (!freq) { 531743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* Try any of the used frequencies */ 531843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt for (i = 0; i < num; i++) { 531943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (freq_included(channels, freqs[i].freq)) { 532043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Force GO on a channel we are already using (%u MHz)", 532143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt freqs[i].freq); 532243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt params->freq = freqs[i].freq; 532343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt break; 532443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 53257a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 53261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 532743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (i == num) { 532843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (wpas_p2p_num_unused_channels(wpa_s) <= 0) { 5329e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using"); 533043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt os_free(freqs); 533143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return -1; 533243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } else { 533343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels"); 533443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 533543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 533643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } else { 533743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt for (i = 0; i < num; i++) { 533843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (freqs[i].freq == freq) 533943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt break; 534043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 534143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 534243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (i == num) { 534343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (wpas_p2p_num_unused_channels(wpa_s) <= 0) { 534443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (freq) 534543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on freq (%u MHz) as all the channels are in use", freq); 534643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt os_free(freqs); 534743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return -1; 534843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } else { 534943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use one of the free channels"); 535043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 5351c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 5352c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 5353e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 5354c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 53551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 53568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 53578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * 53608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, 53618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go) 53628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 53638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group_wpa_s; 53648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5365aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (!wpas_p2p_create_iface(wpa_s)) { 5366aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use same interface for group " 5367aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "operations"); 53685605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_first_connection_timeout = 0; 53698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_s; 5370aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 53718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO : 5373aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt WPA_IF_P2P_CLIENT) < 0) { 5374b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_ERROR, 5375b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "P2P: Failed to add group interface"); 53768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5377aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 53788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s = wpas_p2p_init_group_interface(wpa_s, go); 53798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s == NULL) { 5380b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_ERROR, 5381b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "P2P: Failed to initialize group interface"); 53828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 53838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 53848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 53858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5386aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s", 5387aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt group_wpa_s->ifname); 53885605286c30e1701491bd3af974ae423727750eddDmitry Shmidt group_wpa_s->p2p_first_connection_timeout = 0; 53898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group_wpa_s; 53908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 53918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 53948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_group_add - Add a new P2P group with local end as Group Owner 53958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 53968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @persistent_group: Whether to create a persistent group 53978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency for the group or 0 to indicate no hardcoding 539868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @ht40: Start GO with 40 MHz channel width 539968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @vht: Start GO with VHT support 54008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 54018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 54028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function creates a new P2P group with the local end as the Group Owner, 54038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * i.e., without using Group Owner Negotiation. 54048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 54058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, 540668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int freq, int ht40, int vht) 54078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 54088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results params; 54098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 54118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 54128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5413391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(wpa_s->global->add_psk); 5414391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 5415391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 5416dca3979ccdf869f140f096b83df322a0efc84f22Dmitry Shmidt /* Make sure we are not running find during connection establishment */ 54171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND"); 5418d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_stop_find_oper(wpa_s); 5419dca3979ccdf869f140f096b83df322a0efc84f22Dmitry Shmidt 54208bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = wpas_p2p_select_go_freq(wpa_s, freq); 54218bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (freq < 0) 54228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 54238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 542468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, vht, NULL)) 54251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 542604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (params.freq && 542768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt !p2p_supported_freq_go(wpa_s->global->p2p, params.freq)) { 5428203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && 5429203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt ieee80211_is_dfs(params.freq)) { 5430203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* 5431203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * If freq is a DFS channel and DFS is offloaded to the 5432203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * driver, allow P2P GO to use it. 5433203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt */ 5434203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, 5435203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt "P2P: %s: The forced channel for GO (%u MHz) is DFS, and DFS is offloaded to driver", 5436203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt __func__, params.freq); 5437203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } else { 5438203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, 5439203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt "P2P: The selected channel for GO (%u MHz) is not supported for P2P uses", 5440203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt params.freq); 5441203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt return -1; 5442203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 544304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 54448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_params(wpa_s->global->p2p, ¶ms); 54458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.persistent_group = persistent_group; 54468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpas_p2p_get_group_iface(wpa_s, 0, 1); 54488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 54498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 54508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(wpa_s, ¶ms, 0); 54518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 54538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 54548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_start_p2p_client(struct wpa_supplicant *wpa_s, 545715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt struct wpa_ssid *params, int addr_allocated, 545815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt int freq) 54598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 54608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 54618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0); 54638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 54648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5465391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->p2p_last_4way_hs_fail = NULL; 54668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_deinit(wpa_s); 54688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_config_add_network(wpa_s->conf); 54708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) 54718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 54728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_network_defaults(ssid); 54738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->temporary = 1; 54748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->proto = WPA_PROTO_RSN; 54758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->pairwise_cipher = WPA_CIPHER_CCMP; 54768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->group_cipher = WPA_CIPHER_CCMP; 54778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->key_mgmt = WPA_KEY_MGMT_PSK; 54788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid = os_malloc(params->ssid_len); 54798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->ssid == NULL) { 54808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, ssid->id); 54818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 54828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 54838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid->ssid, params->ssid, params->ssid_len); 54848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len = params->ssid_len; 54858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->p2p_group = 1; 54868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->export_keys = 1; 54878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->psk_set) { 54888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid->psk, params->psk, 32); 54898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->psk_set = 1; 54908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 54918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->passphrase) 54928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->passphrase = os_strdup(params->passphrase); 54938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 1; 549515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_s->p2p_in_invitation = 1; 549615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_s->p2p_invite_go_freq = freq; 54978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 549815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent, 549915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt NULL); 550015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0, 550115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpas_p2p_group_formation_timeout, 550215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_s->parent, NULL); 5503fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt wpa_supplicant_select_network(wpa_s, ssid); 5504fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt 55058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 55068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 55078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, 55108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid, int addr_allocated, 551196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt int force_freq, int neg_freq, int ht40, 551296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt int vht, const struct p2p_channels *channels, 55135605286c30e1701491bd3af974ae423727750eddDmitry Shmidt int connection_timeout) 55148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 55158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results params; 551696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt int go = 0, freq; 55178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->disabled != 2 || ssid->ssid == NULL) 55198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 55208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go) && 55228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go == (ssid->mode == WPAS_MODE_P2P_GO)) { 55238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Requested persistent group is " 55248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "already running"); 5525b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt if (go == 0 && 5526b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 5527b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt wpa_s->parent, NULL)) { 5528b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt /* 5529b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt * This can happen if Invitation Response frame was lost 5530b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt * and the peer (GO of a persistent group) tries to 5531b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt * invite us again. Reschedule the timeout to avoid 5532b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt * terminating the wait for the connection too early 5533b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt * since we now know that the peer is still trying to 5534b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt * invite us instead of having already started the GO. 5535b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt */ 5536b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt wpa_printf(MSG_DEBUG, 5537b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt "P2P: Reschedule group formation timeout since peer is still trying to invite us"); 5538b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0, 5539b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt wpas_p2p_group_formation_timeout, 5540b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt wpa_s->parent, NULL); 5541b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt } 55428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 55438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 55448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5545391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(wpa_s->global->add_psk); 5546391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 5547391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 55488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we are not running find during connection establishment */ 5549d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_stop_find_oper(wpa_s); 55508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 555104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 0; 555204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 55536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 55546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (force_freq > 0) { 55556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt freq = wpas_p2p_select_go_freq(wpa_s, force_freq); 55566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (freq < 0) 55576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 55586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } else { 55596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt freq = wpas_p2p_select_go_freq(wpa_s, neg_freq); 55606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (freq < 0 || 55616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt (freq > 0 && !freq_included(channels, freq))) 55626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt freq = 0; 55636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 5564912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt } else if (ssid->mode == WPAS_MODE_INFRA) { 55656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt freq = neg_freq; 5566912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt if (freq <= 0 || !freq_included(channels, freq)) { 5567912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt struct os_reltime now; 5568912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt struct wpa_bss *bss = 5569912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt wpa_bss_get_p2p_dev_addr(wpa_s, ssid->bssid); 5570912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt 5571912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt os_get_reltime(&now); 5572912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt if (bss && 5573912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt !os_reltime_expired(&now, &bss->last_update, 5) && 5574912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt freq_included(channels, bss->freq)) 5575912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt freq = bss->freq; 5576912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt else 5577912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt freq = 0; 5578912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt } 55798bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 558015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq); 5581912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt } else { 558215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt return -1; 5583912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt } 558415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 558568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, vht, channels)) 55861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 55878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.role_go = 1; 5589d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.psk_set = ssid->psk_set; 5590d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (params.psk_set) 5591d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(params.psk, ssid->psk, sizeof(params.psk)); 5592a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (ssid->passphrase) { 5593a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) { 5594a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Invalid passphrase in " 5595a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "persistent group"); 5596a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 5597a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 5598a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_strlcpy(params.passphrase, ssid->passphrase, 5599a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(params.passphrase)); 56008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(params.ssid, ssid->ssid, ssid->ssid_len); 56028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = ssid->ssid_len; 56038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.persistent_group = 1; 56048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 1); 56068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 56078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 56088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_channels_to_freqs(channels, params.freq_list, P2P_MAX_CHANNELS); 56106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 56115605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_first_connection_timeout = connection_timeout; 56128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(wpa_s, ¶ms, 0); 56138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 56158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_ie_update(void *ctx, struct wpabuf *beacon_ies, 56198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *proberesp_ies) 56208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 56228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface) { 56238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = wpa_s->ap_iface->bss[0]; 56241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!(hapd->conf->p2p & P2P_GROUP_OWNER)) { 56251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(beacon_ies); 56261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(proberesp_ies); 56271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 56281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 56298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (beacon_ies) { 56308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_beacon_ie); 56318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_beacon_ie = beacon_ies; 56328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_probe_resp_ie); 56348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_probe_resp_ie = proberesp_ies; 56358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 56368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(beacon_ies); 56378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(proberesp_ies); 56388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_update_beacon(wpa_s); 56408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_idle_update(void *ctx, int idle) 56448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 56468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->ap_iface) 56478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 56488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO - group %sidle", idle ? "" : "not "); 5649fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (idle) { 5650fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->global->p2p_fail_on_wps_complete && 5651fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->p2p_in_provisioning) { 5652fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_grpform_fail_after_wps(wpa_s); 5653fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 5654fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 56558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 5656fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else 56578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL); 56588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s, 566204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid) 56638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group; 56658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_config *cfg; 56668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 56688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 56698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg = os_zalloc(sizeof(*cfg)); 56718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg == NULL) 56728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 56738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 567404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid->p2p_persistent_group && wpa_s->conf->persistent_reconnect) 56751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cfg->persistent_group = 2; 567604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else if (ssid->p2p_persistent_group) 56771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cfg->persistent_group = 1; 56788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN); 56798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->max_stations && 56808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->max_stations < wpa_s->conf->max_num_sta) 56818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->max_clients = wpa_s->max_stations; 56828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 56838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->max_clients = wpa_s->conf->max_num_sta; 568404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(cfg->ssid, ssid->ssid, ssid->ssid_len); 568504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cfg->ssid_len = ssid->ssid_len; 5686cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt cfg->freq = ssid->frequency; 56878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->cb_ctx = wpa_s; 56888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->ie_update = wpas_p2p_ie_update; 56898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->idle_update = wpas_p2p_idle_update; 56908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p_group_init(wpa_s->global->p2p, cfg); 56928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) 56938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(cfg); 569404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) 56958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_notif_formation_done(group); 56968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group = group; 56978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group; 56988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 57028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int registrar) 57038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 570404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 570504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 57068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->p2p_in_provisioning) { 57078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore WPS success event - P2P " 57088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "provisioning not in progress"); 57098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 57108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 57118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 571204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_INFRA) { 571304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 571404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(go_dev_addr, wpa_s->bssid, ETH_ALEN); 571504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid, 571604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->ssid_len); 571704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Clear any stored provisioning info */ 571804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_clear_provisioning_info(wpa_s->global->p2p, go_dev_addr); 571904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 57201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent, 57228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 57235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_go_group_formation_completed = 1; 572404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_INFRA) { 572504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 572604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Use a separate timeout for initial data connection to 572704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * complete to allow the group to be removed automatically if 572804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * something goes wrong in this step before the P2P group idle 572904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * timeout mechanism is taken into use. 573004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 57315605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 57325605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "P2P: Re-start group formation timeout (%d seconds) as client for initial connection", 57335605286c30e1701491bd3af974ae423727750eddDmitry Shmidt P2P_MAX_INITIAL_CONN_WAIT); 573404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0, 573504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_group_formation_timeout, 573604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->parent, NULL); 57375605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } else if (ssid) { 57385605286c30e1701491bd3af974ae423727750eddDmitry Shmidt /* 57395605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * Use a separate timeout for initial data connection to 57405605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * complete to allow the group to be removed automatically if 57415605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * the client does not complete data connection successfully. 57425605286c30e1701491bd3af974ae423727750eddDmitry Shmidt */ 57435605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 57445605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "P2P: Re-start group formation timeout (%d seconds) as GO for initial connection", 57455605286c30e1701491bd3af974ae423727750eddDmitry Shmidt P2P_MAX_INITIAL_CONN_WAIT_GO); 57465605286c30e1701491bd3af974ae423727750eddDmitry Shmidt eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT_GO, 0, 57475605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpas_p2p_group_formation_timeout, 57485605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->parent, NULL); 57495605286c30e1701491bd3af974ae423727750eddDmitry Shmidt /* 57505605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * Complete group formation on first successful data connection 57515605286c30e1701491bd3af974ae423727750eddDmitry Shmidt */ 57525605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_go_group_formation_completed = 0; 575304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 57548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 57558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_success_cb(wpa_s->global->p2p, peer_addr); 5756a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpas_group_formation_completed(wpa_s, 1, 0); 57578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 57588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 576075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s, 576175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct wps_event_fail *fail) 576275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 576375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!wpa_s->p2p_in_provisioning) { 576475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_DEBUG, "P2P: Ignore WPS fail event - P2P " 576575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "provisioning not in progress"); 576675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 576775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 57681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->go_params) { 57701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_clear_provisioning_info( 57711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->global->p2p, 577204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->go_params->peer_device_addr); 57731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 57741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 577575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_wps_failed(wpa_s, fail); 5776fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 5777fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s == wpa_s->global->p2p_group_formation) { 5778fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt /* 5779fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * Allow some time for the failed WPS negotiation exchange to 5780fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * complete, but remove the group since group formation cannot 5781fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * succeed after provisioning failure. 5782fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt */ 5783fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: WPS step failed during group formation - reject connection from timeout"); 5784fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->global->p2p_fail_on_wps_complete = 1; 5785fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt eloop_deplete_timeout(0, 50000, 5786fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_group_formation_timeout, 5787fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->parent, NULL); 5788fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 5789fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 5790fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 5791fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 5792fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtint wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s) 5793fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 5794fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (!wpa_s->global->p2p_fail_on_wps_complete || 5795fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt !wpa_s->p2p_in_provisioning) 5796fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 5797fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 5798fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_p2p_grpform_fail_after_wps(wpa_s); 5799fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 5800fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 580175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 580275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 580375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 58048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 580504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *config_method, 5806216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt enum wpas_p2p_prov_disc_use use, 5807216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_provision *p2ps_prov) 58088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 58098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 config_methods; 58108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5811216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s->global->pending_p2ps_group = 0; 581204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 0; 581304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use = NORMAL_PD; 5814216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2ps_prov && use == WPAS_P2P_PD_FOR_ASP) { 5815216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_prov->conncap = p2ps_group_capability( 5816216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_s, P2PS_SETUP_NONE, p2ps_prov->role); 5817216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 5818216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: %s conncap: %d - ASP parsed: %x %x %d %s", 5819216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt __func__, p2ps_prov->conncap, 5820216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_prov->adv_id, p2ps_prov->conncap, 5821216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_prov->status, p2ps_prov->info); 5822216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 5823216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt config_methods = 0; 5824216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (os_strncmp(config_method, "display", 7) == 0) 58258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config_methods = WPS_CONFIG_DISPLAY; 58261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strncmp(config_method, "keypad", 6) == 0) 58278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config_methods = WPS_CONFIG_KEYPAD; 58281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strncmp(config_method, "pbc", 3) == 0 || 58291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_strncmp(config_method, "pushbutton", 10) == 0) 58308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config_methods = WPS_CONFIG_PUSHBUTTON; 58311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else { 58321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unknown config method"); 5833216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_free(p2ps_prov); 58348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 58351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 58368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 583704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (use == WPAS_P2P_PD_AUTO) { 583804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(wpa_s->pending_join_dev_addr, peer_addr, ETH_ALEN); 583904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_config_methods = config_methods; 584004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 1; 584104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_join = 0; 584204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_before_join = 0; 584304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry = 0; 584404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_stop_find(wpa_s); 584504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_join_scan_count = 0; 5846fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&wpa_s->p2p_auto_started); 584704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Auto PD started at %ld.%06ld", 584804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.sec, 584904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.usec); 585004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_join_scan(wpa_s, NULL); 585104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 585204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 585304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 5854216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) { 5855216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_free(p2ps_prov); 58568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5857216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 58588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5859216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr, p2ps_prov, 586004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt config_methods, use == WPAS_P2P_PD_FOR_JOIN, 5861d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 0, 1); 58628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 58638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, 58668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end) 58678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 58688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_scan_result_text(ies, ies_len, buf, end); 58698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 58708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s) 58738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5874a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!offchannel_pending_action_tx(wpa_s)) 58758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 58768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 587703658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt wpas_p2p_action_tx_clear(wpa_s); 587803658834c33748b9ad86f3d4cdf0c7be9c6887d1Dmitry Shmidt 58798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new " 58808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operation request"); 5881a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt offchannel_clear_pending_action_tx(wpa_s); 58828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 58838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout, 58868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 5887c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types, 5888216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *dev_id, unsigned int search_delay, 5889203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt u8 seek_cnt, const char **seek_string, int freq) 58908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 58918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clear_pending_action_tx(wpa_s); 58928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 58938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 589404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL || 589504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_in_provisioning) 58968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 58978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 5899c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 59008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_find(wpa_s->global->p2p, timeout, type, 590161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt num_req_dev_types, req_dev_types, dev_id, 5902203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt search_delay, seek_cnt, seek_string, freq); 59038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 59048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpas_p2p_scan_res_ignore_search(struct wpa_supplicant *wpa_s, 59076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_scan_results *scan_res) 59086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 59096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore scan results"); 59106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 59116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->p2p_scan_work) { 59126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_radio_work *work = wpa_s->p2p_scan_work; 59136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->p2p_scan_work = NULL; 59146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt radio_work_done(work); 59156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 59166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 59176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 59186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 59196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 59206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 59216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Indicate that results have been processed so that the P2P module can 59226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * continue pending tasks. 59236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 59246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_scan_res_handled(wpa_s->global->p2p); 59256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 59266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 59276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 59286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s) 59298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 59308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clear_pending_action_tx(wpa_s); 59318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 59328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 59338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 59348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 59368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(wpa_s->global->p2p); 59378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->scan_res_handler == wpas_p2p_scan_res_handler) { 59396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 59406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "P2P: Do not consider the scan results after stop_find"); 59416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore_search; 59426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 5943d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 5944d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5945d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5946d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid wpas_p2p_stop_find(struct wpa_supplicant *wpa_s) 5947d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 59486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpas_p2p_stop_find_oper(wpa_s); 5949216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!wpa_s->global->pending_group_iface_for_p2ps) 5950216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 59518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 59528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx) 59558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 59568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 59578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 59588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 59598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout) 59628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 59638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 59648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 59668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 59678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5968c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 59698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clear_pending_action_tx(wpa_s); 59708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout == 0) { 59728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 59738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is a request for unlimited Listen state. However, at 59748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * least for now, this is mapped to a Listen state for one 59758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hour. 59768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 59778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = 3600; 59788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 59798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 59808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 59818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 59831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Stop previous find/listen operation to avoid trying to request a new 59841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * remain-on-channel operation while the driver is still running the 59851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * previous one. 59861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 59871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->global->p2p) 59881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_stop_find(wpa_s->global->p2p); 59891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 59908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpas_p2p_listen_start(wpa_s, timeout * 1000); 59918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) { 59928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = timeout * 1000; 59938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, 59948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_long_listen_timeout, 59958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s, NULL); 59968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 59978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 59998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 60008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, 60038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, int p2p_group) 60048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 60058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 60068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 60078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 60098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 60108bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt /* 60118bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt * Advertize mandatory cross connection capability even on 60128bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt * p2p_disabled=1 interface when associating with a P2P Manager WLAN AP. 60138bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt */ 60148bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt if (wpa_s->conf->p2p_disabled && p2p_group) 6015661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 60168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 60178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 60188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) 60198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 60208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE); 60228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len, 60238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group, p2p_ie); 60248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 60258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 60278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 60288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, 60311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *dst, const u8 *bssid, 6032a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt const u8 *ie, size_t ie_len, 6033a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt unsigned int rx_freq, int ssi_signal) 60348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 60358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 60368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 60378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 60388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 60398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 604004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid, 6041a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt ie, ie_len, rx_freq)) { 604204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_NOT_P2P: 604304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len, 604404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssi_signal); 604504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* fall through */ 604604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_MALFORMED: 604704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_NOT_LISTEN: 604804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_NOT_PROCESSED: 604904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt default: /* make gcc happy */ 605004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 605104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_PROCESSED: 605204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 605304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 60548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 60558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da, 60588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *bssid, 60598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 category, const u8 *data, size_t len, int freq) 60608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 60618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 60628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 60638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 60648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 60658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len, 60678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq); 60688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 60698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies) 60728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 60738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 60748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 60758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 60768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 60778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_scan_ie(wpa_s->global->p2p, ies, NULL); 60798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 60808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 608243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s) 60838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 60848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_deinit(wpa_s->p2p_group); 60858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group = NULL; 60861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 60871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ap_configured_cb = NULL; 60881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ap_configured_cb_ctx = NULL; 60891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ap_configured_cb_data = NULL; 60901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->connect_without_scan = NULL; 60918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 60928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr) 60958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 60968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 60978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 60988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 60998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 61008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 61018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_reject(wpa_s->global->p2p, addr); 61028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 61038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 61048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 61058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Invite to reinvoke a persistent group */ 61068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 610731be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, 610868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int ht40, int vht, int pref_freq) 61098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 61108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_invite_role role; 6111c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt u8 *bssid = NULL; 6112c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int force_freq = 0; 61137a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int res; 6114a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt int no_pref_freq_given = pref_freq == 0; 61157a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 6116700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->global->p2p_invite_group = NULL; 61177a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (peer_addr) 61187a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); 61197a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt else 61207a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 61218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 612231be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_persistent_go_freq = freq; 612331be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_go_ht40 = !!ht40; 61248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 61258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_GO; 61268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer_addr == NULL) { 61278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Missing peer " 61288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "address in invitation command"); 61298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 61308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 61318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_create_iface(wpa_s)) { 61328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, 61338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_IF_P2P_GO) < 0) { 61348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to " 61358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "allocate a new interface for the " 61368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group"); 61378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 61388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 61398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->pending_interface_addr; 61408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 61418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->own_addr; 61428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 61438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_CLIENT; 61448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer_addr = ssid->bssid; 61458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 61468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_invite_ssid_id = ssid->id; 61478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 614868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq, 614968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt role == P2P_INVITE_ROLE_GO); 61507a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (res) 61517a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return res; 6152af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff 61538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 61548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 61558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6156a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt if (wpa_s->parent->conf->p2p_ignore_shared_freq && 6157a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt no_pref_freq_given && pref_freq > 0 && 6158a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt wpa_s->num_multichan_concurrent > 1 && 6159a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt wpas_p2p_num_unused_channels(wpa_s) > 0) { 6160a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz for invitation due to p2p_ignore_shared_freq=1 configuration", 6161a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt pref_freq); 6162a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt pref_freq = 0; 6163a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt } 6164a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt 61652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt /* 61662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt * Stop any find/listen operations before invitation and possibly 61672f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt * connection establishment. 61682f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt */ 61692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpas_p2p_stop_find_oper(wpa_s); 61702f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 61718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, 61727a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr, 6173cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 1, pref_freq, -1); 61748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 61758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 61768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 61778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Invite to join an active group */ 61788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, 61798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer_addr, const u8 *go_dev_addr) 61808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 61818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global = wpa_s->global; 61828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_invite_role role; 6183c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt u8 *bssid = NULL; 61848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 6185c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt int persistent; 6186051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int freq = 0, force_freq = 0, pref_freq = 0; 61877a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int res; 61888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618931be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_persistent_go_freq = 0; 619031be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_go_ht40 = 0; 619168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->p2p_go_vht = 0; 619231be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen 61938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 61948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(wpa_s->ifname, ifname) == 0) 61958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 61968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 61978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) { 61988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Interface '%s' not found", ifname); 61998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 62008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 62018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 62038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 62048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No current SSID to use for " 62058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation"); 62068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 62078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 62088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6209700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->global->p2p_invite_group = wpa_s; 6210c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt persistent = ssid->p2p_persistent_group && 6211c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpas_p2p_get_persistent(wpa_s->parent, peer_addr, 6212c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt ssid->ssid, ssid->ssid_len); 6213c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 62148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 62158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_ACTIVE_GO; 62168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->own_addr; 62178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go_dev_addr == NULL) 62181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt go_dev_addr = wpa_s->global->p2p_dev_addr; 6219051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt freq = ssid->frequency; 62208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 62218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_CLIENT; 62228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state < WPA_ASSOCIATED) { 62238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Not associated - cannot " 62248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invite to current group"); 62258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 62268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 62278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->bssid; 62288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go_dev_addr == NULL && 62298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(wpa_s->go_dev_addr)) 62308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_dev_addr = wpa_s->go_dev_addr; 6231051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt freq = wpa_s->current_bss ? wpa_s->current_bss->freq : 6232051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt (int) wpa_s->assoc_freq; 62338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 62348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent->pending_invite_ssid_id = -1; 62358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 62378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 62388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 623968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq, 624068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt role == P2P_INVITE_ROLE_ACTIVE_GO); 62417a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (res) 62427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return res; 6243c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, force_freq); 62447a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 62458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, 62467a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt ssid->ssid, ssid->ssid_len, force_freq, 6247cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt go_dev_addr, persistent, pref_freq, -1); 62488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 62498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_completed(struct wpa_supplicant *wpa_s) 62528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 62538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 62548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 625575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int network_id = -1; 62568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int persistent; 62571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int freq; 6258cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 ip[3 * 4]; 6259cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt char ip_addr[100]; 62608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 626104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) { 626204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 626304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->parent, NULL); 626404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 626504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 62668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->show_group_started || !ssid) 6267fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 62688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 0; 62708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 62728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->bssid_set) 62738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(go_dev_addr, ssid->bssid, ETH_ALEN); 62748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid, 62758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len); 62768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->go_dev_addr, go_dev_addr, ETH_ALEN); 62778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_group_formation == wpa_s) 62798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 62808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = wpa_s->current_bss ? wpa_s->current_bss->freq : 62821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (int) wpa_s->assoc_freq; 6283cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 6284cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ip_addr[0] = '\0'; 6285cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_sm_get_p2p_ip_addr(wpa_s->wpa, ip) == 0) { 62866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int res; 62876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 62886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt res = os_snprintf(ip_addr, sizeof(ip_addr), 62896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt " ip_addr=%u.%u.%u.%u " 62906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "ip_mask=%u.%u.%u.%u go_ip_addr=%u.%u.%u.%u", 62916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ip[0], ip[1], ip[2], ip[3], 62926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ip[4], ip[5], ip[6], ip[7], 62936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ip[8], ip[9], ip[10], ip[11]); 62946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(sizeof(ip_addr), res)) 62956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ip_addr[0] = '\0'; 6296cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 6297cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 62987f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt wpas_p2p_group_started(wpa_s, 0, ssid, freq, 62997f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ssid->passphrase == NULL && ssid->psk_set ? 63007f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ssid->psk : NULL, 63017f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ssid->passphrase, go_dev_addr, persistent, 63027f0b69e88015ca077ef7a417fde0a76c10df23a5Dmitry Shmidt ip_addr); 63038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (persistent) 630575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = wpas_p2p_store_persistent_group(wpa_s->parent, 630675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ssid, go_dev_addr); 630775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (network_id < 0) 630875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = ssid->id; 630975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 1); 63108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 63118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1, 63148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval1, u32 duration2, u32 interval2) 63158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6316fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int ret; 6317fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 63188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 63198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 63208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state < WPA_ASSOCIATED || 63228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid == NULL || 63238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->mode != WPAS_MODE_INFRA) 63248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 63258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6326fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid, 6327fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->own_addr, wpa_s->assoc_freq, 6328fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt duration1, interval1, duration2, interval2); 6329fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (ret == 0) 6330fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->waiting_presence_resp = 1; 6331fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 6332fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return ret; 63338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 63348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period, 63378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 63388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 63398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 63408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 63418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_ext_listen(wpa_s->global->p2p, period, interval); 63438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 63448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_p2p_is_client(struct wpa_supplicant *wpa_s) 63471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 6348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->current_ssid == NULL) { 6349d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 6350d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * current_ssid can be cleared when P2P client interface gets 6351d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * disconnected, so assume this interface was used as P2P 6352d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * client. 6353d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 6354d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 6355d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 6356d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return wpa_s->current_ssid->p2p_group && 63571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->current_ssid->mode == WPAS_MODE_INFRA; 63581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 63591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 63601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 63618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx) 63628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 63638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 63648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) { 63668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - " 63678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "disabled"); 63688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 63698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 63708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 637104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group idle timeout reached - terminate " 637204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "group"); 637361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_IDLE_TIMEOUT); 63748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 63758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s) 63788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 637904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int timeout; 638004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 638104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0) 638204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout"); 63831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 63841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group) 63858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 63868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout = wpa_s->conf->p2p_group_idle; 63881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA && 63891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE)) 63901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout = P2P_MAX_CLIENT_IDLE; 63911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 63921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (timeout == 0) 63938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 63948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 639504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (timeout < 0) { 639604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA) 639704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt timeout = 0; /* special client mode no-timeout */ 639804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 639904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 640004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 640104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 640204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_in_provisioning) { 640304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 640404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Use the normal group formation timeout during the 640504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * provisioning phase to avoid terminating this process too 640604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * early due to group idle timeout. 640704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 640804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout " 640904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "during provisioning"); 641004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 641104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 64129e4e8acef07b7053e93024a621489286900b9ec7Deepthi Gowri 641304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->show_group_started) { 641404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 641504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Use the normal group formation timeout between the end of 641604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * the provisioning phase and completion of 4-way handshake to 641704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * avoid terminating this process too early due to group idle 641804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * timeout. 641904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 642004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout " 642104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "while waiting for initial 4-way handshake to " 642204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "complete"); 642304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 642404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 642504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 64268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds", 64271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout); 64281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout, 64291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL); 64308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 64318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64332b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen/* Returns 1 if the interface was removed */ 64342b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenint wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, 64352b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen u16 reason_code, const u8 *ie, size_t ie_len, 64362b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen int locally_generated) 64378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 64388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 64392b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 0; 64408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 644104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!locally_generated) 644204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie, 644304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie_len); 644404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 644504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (reason_code == WLAN_REASON_DEAUTH_LEAVING && !locally_generated && 644604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid && 644704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid->p2p_group && 644804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid->mode == WPAS_MODE_INFRA) { 644904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group " 645004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "session is ending"); 64512b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen if (wpas_p2p_group_delete(wpa_s, 64522b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen P2P_GROUP_REMOVAL_GO_ENDING_SESSION) 64532b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen > 0) 64542b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 1; 645504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 64562b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen 64572b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 0; 64588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 64598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, 646204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 reason_code, const u8 *ie, size_t ie_len, 646304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int locally_generated) 64648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 64658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 64668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 64678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 646804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!locally_generated) 646904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie, 647004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie_len); 64718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 64728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_config(struct wpa_supplicant *wpa_s) 64758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 64768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 64778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 64798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 64808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)) 64828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 64838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME) 64858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_dev_name(p2p, wpa_s->conf->device_name); 64868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) 64888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type); 64898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wps && 64918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS)) 64928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_config_methods(p2p, wpa_s->wps->config_methods); 64938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wps && (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID)) 64958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_uuid(p2p, wpa_s->wps->uuid); 64968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_WPS_STRING) { 64988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_manufacturer(p2p, wpa_s->conf->manufacturer); 64998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_model_name(p2p, wpa_s->conf->model_name); 65008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_model_number(p2p, wpa_s->conf->model_number); 65018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_serial_number(p2p, wpa_s->conf->serial_number); 65028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 65038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 65048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) 65058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_sec_dev_types(p2p, 65068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (void *) wpa_s->conf->sec_device_type, 65078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->num_sec_device_types); 65088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 65098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION) { 65108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 65118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 65128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) { 65138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->wps_vendor_ext[i] == NULL) 65148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 65158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_wps_vendor_extension( 65168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, wpa_s->conf->wps_vendor_ext[i]); 65178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 65188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 65198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 65208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) && 65218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->country[0] && wpa_s->conf->country[1]) { 65228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char country[3]; 65238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[0] = wpa_s->conf->country[0]; 65248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[1] = wpa_s->conf->country[1]; 65258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[2] = 0x04; 65268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_country(p2p, country); 65278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 65288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 65298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_SSID_POSTFIX) { 65308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_ssid_postfix(p2p, (u8 *) wpa_s->conf->p2p_ssid_postfix, 65318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_ssid_postfix ? 65328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(wpa_s->conf->p2p_ssid_postfix) : 65338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0); 65348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 65358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 65368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_INTRA_BSS) 65378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_intra_bss_dist(p2p, wpa_s->conf->p2p_intra_bss); 653875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 653975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_LISTEN_CHANNEL) { 654075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen u8 reg_class, channel; 654175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int ret; 654275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen unsigned int r; 654343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u8 channel_forced; 654443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 654575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->p2p_listen_reg_class && 654675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->conf->p2p_listen_channel) { 654775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen reg_class = wpa_s->conf->p2p_listen_reg_class; 654875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen channel = wpa_s->conf->p2p_listen_channel; 654943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt channel_forced = 1; 655075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 655175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen reg_class = 81; 655275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 655375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Pick one of the social channels randomly as the 655475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * listen channel. 655575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 6556661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random((u8 *) &r, sizeof(r)) < 0) 6557661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt channel = 1; 6558661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt else 6559661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt channel = 1 + (r % 3) * 5; 656043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt channel_forced = 0; 656175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 656243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt ret = p2p_set_listen_channel(p2p, reg_class, channel, 656343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt channel_forced); 656475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ret) 656575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_ERROR, "P2P: Own listen channel update " 656675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "failed: %d", ret); 656775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 656875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_OPER_CHANNEL) { 656975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen u8 op_reg_class, op_channel, cfg_op_channel; 657075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int ret = 0; 657175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen unsigned int r; 657275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->p2p_oper_reg_class && 657375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->conf->p2p_oper_channel) { 657475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_reg_class = wpa_s->conf->p2p_oper_reg_class; 657575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_channel = wpa_s->conf->p2p_oper_channel; 657675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen cfg_op_channel = 1; 657775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 657875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_reg_class = 81; 657975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 658075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Use random operation channel from (1, 6, 11) 658175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *if no other preference is indicated. 658275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 6583661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random((u8 *) &r, sizeof(r)) < 0) 6584661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt op_channel = 1; 6585661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt else 6586661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt op_channel = 1 + (r % 3) * 5; 658775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen cfg_op_channel = 0; 658875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 658975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ret = p2p_set_oper_channel(p2p, op_reg_class, op_channel, 659075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen cfg_op_channel); 659175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ret) 659275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_ERROR, "P2P: Own oper channel update " 659375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "failed: %d", ret); 659475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 659504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 659604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PREF_CHAN) { 659704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_set_pref_chan(p2p, wpa_s->conf->num_p2p_pref_chan, 659804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->conf->p2p_pref_chan) < 0) { 659904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Preferred channel list " 660004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "update failed"); 660104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 660268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 660368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_set_no_go_freq(p2p, &wpa_s->conf->p2p_no_go_freq) < 0) { 660468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: No GO channel list " 660568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt "update failed"); 660668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 660704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 66082271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 66092271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PASSPHRASE_LEN) 66102271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt p2p_set_passphrase_len(p2p, wpa_s->conf->p2p_passphrase_len); 66118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 66128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start, 66158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int duration) 66168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 66178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->ap_iface) 66188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 66198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start, 66208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt duration); 66218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 66228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled) 66258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 66268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 66278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 66288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->cross_connection = enabled; 66308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_cross_connect(wpa_s->global->p2p, enabled); 66318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!enabled) { 66338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 66348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) 66368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 66378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->cross_connect_enabled == 0) 66388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 66398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_enabled = 0; 66418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_in_use = 0; 6642b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(iface->parent, MSG_INFO, 6643b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s", 6644b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt iface->ifname, 6645b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt iface->cross_connect_uplink); 66468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 66478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 66488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 66508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 66518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink) 66548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 66558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 66568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!uplink->global->cross_connection) 66588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 66598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = uplink->global->ifaces; iface; iface = iface->next) { 66618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface->cross_connect_enabled) 66628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 66638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) != 66648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 66658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 66668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->ap_iface == NULL) 66678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 66688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->cross_connect_in_use) 66698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 66708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_in_use = 1; 6672b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(iface->parent, MSG_INFO, 6673b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s", 6674b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt iface->ifname, iface->cross_connect_uplink); 66758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 66768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 66778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink) 66808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 66818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 66828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = uplink->global->ifaces; iface; iface = iface->next) { 66848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface->cross_connect_enabled) 66858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 66868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) != 66878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 66888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 66898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface->cross_connect_in_use) 66908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 66918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6692b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(iface->parent, MSG_INFO, 6693b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s", 6694b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt iface->ifname, iface->cross_connect_uplink); 66958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_in_use = 0; 66968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 66978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 66988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 66998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s) 67018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 67028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface || wpa_s->current_ssid == NULL || 67038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->mode != WPAS_MODE_INFRA || 67048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_disallowed) 67058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_disable_cross_connect(wpa_s); 67068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 67078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_enable_cross_connect(wpa_s); 670804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->ap_iface && 670904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0) 671004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout"); 67118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 67128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s) 67158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 67168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_disable_cross_connect(wpa_s); 67171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->ap_iface && 67181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !eloop_is_timeout_registered(wpas_p2p_group_idle_timeout, 67191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL)) 67208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 67218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 67228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s) 67258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 67268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 67278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->global->cross_connection) 67298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 67308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { 67328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface == wpa_s) 67338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 67348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->drv_flags & 67358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE) 67368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 67376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if ((iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) && 67386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt iface != wpa_s->parent) 67398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 67408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_enabled = 1; 67428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname, 67438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->cross_connect_uplink)); 67448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from " 67458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s to %s whenever uplink is available", 67468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname, wpa_s->cross_connect_uplink); 67478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->ap_iface || iface->current_ssid == NULL || 67498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->current_ssid->mode != WPAS_MODE_INFRA || 67508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_disallowed || 67518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->wpa_state != WPA_COMPLETED) 67528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 67538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_in_use = 1; 6755b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 6756b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s", 6757b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, wpa_s->cross_connect_uplink); 67588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 67598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 67608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 67618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s) 67648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 67658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT && 67668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !wpa_s->p2p_in_provisioning) 67678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* not P2P client operation */ 67688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Terminate connection due to WPS PBC " 67708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "session overlap"); 67718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s != wpa_s->parent) 67728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_ctrl(wpa_s->parent, MSG_INFO, WPS_EVENT_OVERLAP); 6773a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpas_p2p_group_formation_failed(wpa_s, 0); 67748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 67758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 67768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6778df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidtvoid wpas_p2p_pbc_overlap_cb(void *eloop_ctx, void *timeout_ctx) 6779df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt{ 6780df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 6781df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt wpas_p2p_notif_pbc_overlap(wpa_s); 6782df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt} 6783df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 6784df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 67858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s) 67868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 678768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_channels chan, cli_chan; 6788684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt struct wpa_supplicant *ifs; 67898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global == NULL || wpa_s->global->p2p == NULL) 67918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 67928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&chan, 0, sizeof(chan)); 679468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memset(&cli_chan, 0, sizeof(cli_chan)); 679568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (wpas_p2p_setup_channels(wpa_s, &chan, &cli_chan)) { 67968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to update supported " 67978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel list"); 67988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 67998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 68008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 680168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_update_channel_list(wpa_s->global->p2p, &chan, &cli_chan); 6802684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt 6803684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { 6804684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt int freq; 6805684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt if (!ifs->current_ssid || 6806684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt !ifs->current_ssid->p2p_group || 6807684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt (ifs->current_ssid->mode != WPAS_MODE_P2P_GO && 6808684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt ifs->current_ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)) 6809684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt continue; 6810684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt freq = ifs->current_ssid->frequency; 6811684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt if (freq_included(&chan, freq)) { 6812684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt wpa_dbg(ifs, MSG_DEBUG, 6813684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt "P2P GO operating frequency %d MHz in valid range", 6814684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt freq); 6815684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt continue; 6816684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt } 6817684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt 6818684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt wpa_dbg(ifs, MSG_DEBUG, 6819684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt "P2P GO operating in invalid frequency %d MHz", freq); 6820684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt /* TODO: Consider using CSA or removing the group within 6821684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt * wpa_supplicant */ 6822684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt wpa_msg(ifs, MSG_INFO, P2P_EVENT_REMOVE_AND_REFORM_GROUP); 6823684785c7f4e58498603a9a5ce26f933cc2557ebdDmitry Shmidt } 68248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 68258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6827a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void wpas_p2p_scan_res_ignore(struct wpa_supplicant *wpa_s, 6828a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt struct wpa_scan_results *scan_res) 6829a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 6830a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore scan results"); 6831a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 6832a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 6833a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 68348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_cancel(struct wpa_supplicant *wpa_s) 68358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 68368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global = wpa_s->global; 68378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 68388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer; 68398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p == NULL) 68418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 68428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to cancel group formation"); 68448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->pending_interface_name[0] && 68468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(wpa_s->pending_interface_addr)) 68478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 68488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = p2p_get_go_neg_peer(global->p2p); 68508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer) { 68518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unauthorize pending GO Neg peer " 68528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(peer)); 68538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_unauthorize(global->p2p, peer); 685404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt found = 1; 68558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 68568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6857a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->scan_res_handler == wpas_p2p_scan_res_join) { 6858a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Stop pending scan for join"); 6859a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore; 6860a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt found = 1; 6861a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 6862a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 6863a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->pending_pd_before_join) { 6864a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Stop pending PD before join"); 6865a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 6866a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt found = 1; 6867a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 6868a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 68698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_stop_find(wpa_s); 68708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 68728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == global->p2p_group_formation && 68738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpa_s->p2p_in_provisioning || 68748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent->pending_interface_type == 68758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_IF_P2P_CLIENT)) { 68768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Interface %s in group " 68778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "formation found - cancelling", 68788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname); 68798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 68808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 68818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent, NULL); 6882adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen if (wpa_s->p2p_in_provisioning) { 6883a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpas_group_formation_completed(wpa_s, 0, 0); 6884adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen break; 6885adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen } 688661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, 688761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_REQUESTED); 68888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 688921de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt } else if (wpa_s->p2p_in_invitation) { 689021de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Interface %s in invitation found - cancelling", 689121de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt wpa_s->ifname); 689221de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt found = 1; 6893a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpas_p2p_group_formation_failed(wpa_s, 0); 68948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 68958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 68968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 68988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No ongoing group formation found"); 68998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 69008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 69018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 69038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 69048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s) 69078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 69088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group) 69098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 69108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not " 69128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "being available anymore"); 691361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_UNAVAILABLE); 69148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 69158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s, 69188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_24, int freq_5, int freq_overall) 69198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 69208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 6921fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p == NULL) 69228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 69238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_best_channels(p2p, freq_24, freq_5, freq_overall); 69248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 69258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr) 69288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 69298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 peer[ETH_ALEN]; 69308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 69318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6932fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (p2p == NULL) 69338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 69348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(addr, peer)) 69368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 69378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_unauthorize(p2p, peer); 69398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 69408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 69438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_disconnect - Disconnect from a P2P Group 69448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 69458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 69468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 69478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This can be used to disconnect from a group in which the local end is a P2P 69488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Client or to end a P2P Group in case the local end is the Group Owner. If a 69498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * virtual network interface was created for this group, that interface will be 69508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * removed. Otherwise, only the configured P2P group network will be removed 69518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from the interface. 69528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 69538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_disconnect(struct wpa_supplicant *wpa_s) 69548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 69558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 69578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 69588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69592b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED) < 0 ? 69602b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen -1 : 0; 69618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 69621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 69631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 69641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpas_p2p_in_progress(struct wpa_supplicant *wpa_s) 69651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 6966f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt int ret; 6967f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 69681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 69691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 69701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6971f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt ret = p2p_in_progress(wpa_s->global->p2p); 6972f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (ret == 0) { 6973f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 6974f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Check whether there is an ongoing WPS provisioning step (or 6975f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * other parts of group formation) on another interface since 6976f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * p2p_in_progress() does not report this to avoid issues for 6977f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * scans during such provisioning step. 6978f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 6979f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (wpa_s->global->p2p_group_formation && 6980f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_s->global->p2p_group_formation != wpa_s) { 6981f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Another interface (%s) " 6982f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "in group formation", 6983f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_s->global->p2p_group_formation->ifname); 6984f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt ret = 1; 6985f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 6986f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 6987f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 698892c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt if (!ret && wpa_s->global->p2p_go_wait_client.sec) { 6989fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now; 6990fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 6991fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (os_reltime_expired(&now, &wpa_s->global->p2p_go_wait_client, 6992fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt P2P_MAX_INITIAL_CONN_WAIT_GO)) { 699392c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt /* Wait for the first client has expired */ 699492c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt wpa_s->global->p2p_go_wait_client.sec = 0; 699592c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt } else { 699692c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Waiting for initial client connection during group formation"); 699792c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt ret = 1; 699892c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt } 699992c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt } 700092c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt 7001f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return ret; 70021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 70031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 70041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 70051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpas_p2p_network_removed(struct wpa_supplicant *wpa_s, 70061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *ssid) 70071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 70081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->p2p_in_provisioning && ssid->p2p_group && 70091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 70101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->parent, NULL) > 0) { 701104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /** 701204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Remove the network by scheduling the group formation 701304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * timeout to happen immediately. The teardown code 701404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * needs to be scheduled to run asynch later so that we 701504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * don't delete data from under ourselves unexpectedly. 701604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Calling wpas_p2p_group_formation_timeout directly 701704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * causes a series of crashes in WPS failure scenarios. 701804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 70191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to " 70201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P group network getting removed"); 702104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout, 702204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->parent, NULL); 70231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 70241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 70251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 70261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 70271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s, 7028c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt const u8 *addr, const u8 *ssid, 7029c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t ssid_len) 70301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 70311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *s; 70321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t i; 70331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 70341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 70351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->disabled != 2) 70361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 7037c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid && 7038c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt (ssid_len != s->ssid_len || 7039c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) != 0)) 7040c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 7041391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (addr == NULL) { 7042391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO) 7043391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return s; 7044391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 7045391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 70461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0) 70471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return s; /* peer is GO in the persistent group */ 70481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL) 70491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 70501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; i < s->num_p2p_clients; i++) { 7051ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN, 70521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt addr, ETH_ALEN) == 0) 70531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return s; /* peer is P2P client in persistent 70541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * group */ 70551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 70561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 70571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 70581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 70591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 70601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 70611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 70621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s, 70631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr) 70641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 70655605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 70665605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->parent, NULL) > 0) { 70675605286c30e1701491bd3af974ae423727750eddDmitry Shmidt /* 70685605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * This can happen if WPS provisioning step is not terminated 70695605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * cleanly (e.g., P2P Client does not send WSC_Done). Since the 70705605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * peer was able to connect, there is no need to time out group 70715605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * formation after this, though. In addition, this is used with 70725605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * the initial connection wait on the GO as a separate formation 70735605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * timeout and as such, expected to be hit after the initial WPS 70745605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * provisioning step. 70755605286c30e1701491bd3af974ae423727750eddDmitry Shmidt */ 70765605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Canceled P2P group formation timeout on data connection"); 70776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 70786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!wpa_s->p2p_go_group_formation_completed && 70796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !wpa_s->group_formation_reported) { 70806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 70816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * GO has not yet notified group formation success since 70826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * the WPS step was not completed cleanly. Do that 70836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * notification now since the P2P Client was able to 70846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * connect and as such, must have received the 70856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * credential from the WPS step. 70866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 70876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->global->p2p) 70886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt p2p_wps_success_cb(wpa_s->global->p2p, addr); 7089a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpas_group_formation_completed(wpa_s, 1, 0); 70906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 70915605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 70925605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (!wpa_s->p2p_go_group_formation_completed) { 70935605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Marking group formation completed on GO on first data connection"); 70945605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_go_group_formation_completed = 1; 70955605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 70965605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_s->p2p_in_provisioning = 0; 709721de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt wpa_s->p2p_in_invitation = 0; 70985605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 709992c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt wpa_s->global->p2p_go_wait_client.sec = 0; 71001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (addr == NULL) 71011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 71021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_add_persistent_group_client(wpa_s, addr); 71031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 7104c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 710504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 71067f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidtstatic int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s, 71077f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt int group_added) 710804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 710904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *group = wpa_s; 71107f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt int ret = 0; 71117f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt 711204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->global->p2p_group_formation) 711304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt group = wpa_s->global->p2p_group_formation; 7114a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt wpa_s = wpa_s->global->p2p_init_wpa_s; 711504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt offchannel_send_action_done(wpa_s); 711604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (group_added) 71177f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt ret = wpas_p2p_group_delete(group, P2P_GROUP_REMOVAL_SILENT); 711804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Fall back to GO Negotiation"); 711904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin, 712004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0, 712104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq, 712204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id, 712361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_pd_before_go_neg, 712468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->p2p_go_ht40, 712568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_s->p2p_go_vht); 71267f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt return ret; 712704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 712804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 712904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 713004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s) 713104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 71327f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt int res; 71337f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt 713404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->p2p_fallback_to_go_neg || 713504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_in_provisioning <= 5) 713604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 713704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 713804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr) > 0) 713904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; /* peer operating as a GO */ 714004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 714104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: GO not found for p2p_connect-auto - " 714204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "fallback to GO Negotiation"); 71437f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_FALLBACK_TO_GO_NEG 71447f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "reason=GO-not-found"); 71457f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt res = wpas_p2p_fallback_to_go_neg(wpa_s, 1); 714604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 71477f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt return res == 1 ? 2 : 1; 714804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 714904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 715061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 715161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtunsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s) 715261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 715361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpa_supplicant *ifs; 715461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 715561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->wpa_state > WPA_SCANNING) { 715661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search delay due to " 715761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "concurrent operation", 715809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt wpa_s->conf->p2p_search_delay); 715909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt return wpa_s->conf->p2p_search_delay; 716061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 716161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 716201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, 716301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt radio_list) { 716401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (ifs != wpa_s && ifs->wpa_state > WPA_SCANNING) { 716561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search " 716661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "delay due to concurrent operation on " 716761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "interface %s", 716809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt wpa_s->conf->p2p_search_delay, 716909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt ifs->ifname); 717009f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt return wpa_s->conf->p2p_search_delay; 717161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 717261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 717361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 717461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 717561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 717661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 717737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 7178391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int wpas_p2p_remove_psk_entry(struct wpa_supplicant *wpa_s, 7179391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *s, const u8 *addr, 7180391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int iface_addr) 7181391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 7182391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct psk_list_entry *psk, *tmp; 7183391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int changed = 0; 7184391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7185391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_for_each_safe(psk, tmp, &s->psk_list, struct psk_list_entry, 7186391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt list) { 7187391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if ((iface_addr && !psk->p2p && 7188391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcmp(addr, psk->addr, ETH_ALEN) == 0) || 7189391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (!iface_addr && psk->p2p && 7190391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcmp(addr, psk->addr, ETH_ALEN) == 0)) { 7191391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 7192391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt "P2P: Remove persistent group PSK list entry for " 7193391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR " p2p=%u", 7194391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(psk->addr), psk->p2p); 7195391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_del(&psk->list); 7196391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(psk); 7197391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt changed++; 7198391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7199391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7200391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7201391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return changed; 7202391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 7203391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7204391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7205391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr, 7206391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *p2p_dev_addr, 7207391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *psk, size_t psk_len) 7208391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 7209391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 7210391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *persistent; 72117832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt struct psk_list_entry *p, *last; 7212391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7213391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (psk_len != sizeof(p->psk)) 7214391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 7215391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7216391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p_dev_addr) { 7217391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR 7218391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt " p2p_dev_addr=" MACSTR, 7219391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(mac_addr), MAC2STR(p2p_dev_addr)); 7220391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (is_zero_ether_addr(p2p_dev_addr)) 7221391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dev_addr = NULL; 7222391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 7223391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR, 7224391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(mac_addr)); 7225391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7226391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7227391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) { 7228391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: new_psk_cb during group formation"); 7229391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* To be added to persistent group once created */ 7230391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->global->add_psk == NULL) { 7231391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = os_zalloc(sizeof(*p)); 7232391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->global->add_psk == NULL) 7233391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 7234391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7235391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p = wpa_s->global->add_psk; 7236391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p_dev_addr) { 7237391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p->p2p = 1; 7238391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN); 7239391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 7240391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p->p2p = 0; 7241391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->addr, mac_addr, ETH_ALEN); 7242391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7243391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->psk, psk, psk_len); 7244391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 7245391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7246391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7247391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GO || !ssid->p2p_persistent_group) { 7248391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Ignore new_psk_cb on not-persistent GO"); 7249391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 7250391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7251391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7252391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid, 7253391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid_len); 7254391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!persistent) { 7255391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not find persistent group information to store the new PSK"); 7256391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 7257391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7258391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7259391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p = os_zalloc(sizeof(*p)); 7260391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p == NULL) 7261391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 7262391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p_dev_addr) { 7263391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p->p2p = 1; 7264391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN); 7265391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 7266391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p->p2p = 0; 7267391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->addr, mac_addr, ETH_ALEN); 7268391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7269391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->psk, psk, psk_len); 7270391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 72717832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (dl_list_len(&persistent->psk_list) > P2P_MAX_STORED_CLIENTS && 72727832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt (last = dl_list_last(&persistent->psk_list, 72737832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt struct psk_list_entry, list))) { 7274391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove oldest PSK entry for " 7275391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR " (p2p=%u) to make room for a new one", 7276391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(last->addr), last->p2p); 7277391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_del(&last->list); 7278391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(last); 7279391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7280391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7281391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_p2p_remove_psk_entry(wpa_s->parent, persistent, 7282391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dev_addr ? p2p_dev_addr : mac_addr, 7283391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dev_addr == NULL); 7284391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p_dev_addr) { 7285391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for p2p_dev_addr=" 7286391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR, MAC2STR(p2p_dev_addr)); 7287391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 7288391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for addr=" MACSTR, 7289391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(mac_addr)); 7290391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7291391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_add(&persistent->psk_list, &p->list); 7292391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7293391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->parent->conf->update_config && 7294391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf)) 7295391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 7296391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 7297391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7298391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7299391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_remove_psk(struct wpa_supplicant *wpa_s, 7300391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *s, const u8 *addr, 7301391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int iface_addr) 7302391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 7303391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int res; 7304391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7305391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt res = wpas_p2p_remove_psk_entry(wpa_s, s, addr, iface_addr); 7306f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (res > 0 && wpa_s->conf->update_config && 7307f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_config_write(wpa_s->confname, wpa_s->conf)) 7308f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 7309f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt "P2P: Failed to update configuration"); 7310391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 7311391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7312391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7313391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_remove_client_go(struct wpa_supplicant *wpa_s, 7314391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *peer, int iface_addr) 7315391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 7316391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_data *hapd; 7317391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_wpa_psk *psk, *prev, *rem; 7318391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct sta_info *sta; 7319391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7320391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL || 7321391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->current_ssid->mode != WPAS_MODE_P2P_GO) 7322391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 7323391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7324391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Remove per-station PSK entry */ 7325391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hapd = wpa_s->ap_iface->bss[0]; 7326391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt prev = NULL; 7327391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt psk = hapd->conf->ssid.wpa_psk; 7328391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt while (psk) { 7329391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if ((iface_addr && os_memcmp(peer, psk->addr, ETH_ALEN) == 0) || 7330391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (!iface_addr && 7331391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcmp(peer, psk->p2p_dev_addr, ETH_ALEN) == 0)) { 7332391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove operating group PSK entry for " 7333391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR " iface_addr=%d", 7334391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(peer), iface_addr); 7335391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (prev) 7336391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt prev->next = psk->next; 7337391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else 7338391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hapd->conf->ssid.wpa_psk = psk->next; 7339391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt rem = psk; 7340391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt psk = psk->next; 7341391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(rem); 7342391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 7343391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt prev = psk; 7344391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt psk = psk->next; 7345391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7346391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7347391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7348391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Disconnect from group */ 7349391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (iface_addr) 7350391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sta = ap_get_sta(hapd, peer); 7351391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else 7352391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sta = ap_get_sta_p2p(hapd, peer); 7353391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (sta) { 7354391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disconnect peer " MACSTR 7355391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt " (iface_addr=%d) from group", 7356391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(peer), iface_addr); 7357391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 7358391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING); 7359391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ap_sta_deauthenticate(hapd, sta, WLAN_REASON_DEAUTH_LEAVING); 7360391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7361391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 7362391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7363391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7364391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer, 7365391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int iface_addr) 7366391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 7367391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *s; 7368391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_supplicant *w; 73698bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s; 7370391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7371391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove client " MACSTR, MAC2STR(peer)); 7372391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7373391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Remove from any persistent group */ 73748bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt for (s = p2p_wpa_s->conf->ssid; s; s = s->next) { 7375391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO) 7376391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 7377391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!iface_addr) 73788bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt wpas_remove_persistent_peer(p2p_wpa_s, s, peer, 0); 73798bd70b7d6ba220544ee2f0e201e5df23e277fa1dDmitry Shmidt wpas_p2p_remove_psk(p2p_wpa_s, s, peer, iface_addr); 7380391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7381391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7382391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Remove from any operating group */ 7383391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (w = wpa_s->global->ifaces; w; w = w->next) 7384391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_p2p_remove_client_go(w, peer, iface_addr); 7385391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 7386391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7387391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7388391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx) 7389391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 7390391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 7391391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_PSK_FAILURE); 7392391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 7393391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7394391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 739504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidtstatic void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx) 739604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt{ 739704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 739804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 739904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Frequency conflict - terminate group"); 740004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_FREQ_CONFLICT); 740104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt} 740204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 740304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 740404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidtint wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq, 740504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt struct wpa_ssid *ssid) 740604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt{ 740704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt struct wpa_supplicant *iface; 740804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 740904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { 741004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt if (!iface->current_ssid || 741104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt iface->current_ssid->frequency == freq || 741204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt (iface->p2p_group_interface == NOT_P2P_GROUP_INTERFACE && 741304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt !iface->current_ssid->p2p_group)) 741404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt continue; 741504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 741604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt /* Remove the connection with least priority */ 741704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt if (!wpas_is_p2p_prioritized(iface)) { 741804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt /* STA connection has priority over existing 741904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt * P2P connection, so remove the interface. */ 742004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Removing P2P connection due to single channel concurrent mode frequency conflict"); 742104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt eloop_register_timeout(0, 0, 742204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt wpas_p2p_group_freq_conflict, 742304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt iface, NULL); 742404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt /* If connection in progress is P2P connection, do not 742504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt * proceed for the connection. */ 742604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt if (wpa_s == iface) 742704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt return -1; 742804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt else 742904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt return 0; 743004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt } else { 743104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt /* P2P connection has priority, disable the STA network 743204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt */ 743304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt wpa_supplicant_disable_network(wpa_s->global->ifaces, 743404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt ssid); 743504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt wpa_msg(wpa_s->global->ifaces, MSG_INFO, 743604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt WPA_EVENT_FREQ_CONFLICT " id=%d", ssid->id); 743704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_memset(wpa_s->global->ifaces->pending_bssid, 0, 743804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt ETH_ALEN); 743904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt /* If P2P connection is in progress, continue 744004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt * connecting...*/ 744104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt if (wpa_s == iface) 744204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt return 0; 744304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt else 744404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt return -1; 744504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt } 744604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt } 744704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 744804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt return 0; 744904f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt} 745004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 745104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 7452391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtint wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s) 7453391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 7454391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 7455391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7456391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ssid == NULL || !ssid->p2p_group) 7457391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 7458391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7459391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->p2p_last_4way_hs_fail && 7460391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->p2p_last_4way_hs_fail == ssid) { 7461391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 7462391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *persistent; 7463391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7464391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpas_p2p_persistent_group(wpa_s, go_dev_addr, 7465391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid, 7466391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid_len) <= 0) { 7467391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not determine whether 4-way handshake failures were for a persistent group"); 7468391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt goto disconnect; 7469391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7470391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7471391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Two 4-way handshake failures for a P2P group - go_dev_addr=" 7472391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR, MAC2STR(go_dev_addr)); 7473391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt persistent = wpas_p2p_get_persistent(wpa_s->parent, go_dev_addr, 7474391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid, 7475391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid_len); 7476391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (persistent == NULL || persistent->mode != WPAS_MODE_INFRA) { 7477391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No matching persistent group stored"); 7478391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt goto disconnect; 7479391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7480391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 7481391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt P2P_EVENT_PERSISTENT_PSK_FAIL "%d", 7482391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt persistent->id); 7483391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt disconnect: 7484391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->p2p_last_4way_hs_fail = NULL; 7485391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* 7486391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Remove the group from a timeout to avoid issues with caller 7487391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * continuing to use the interface if this is on a P2P group 7488391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * interface. 7489391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt */ 7490391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt eloop_register_timeout(0, 0, wpas_p2p_psk_failure_removal, 7491391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s, NULL); 7492391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 1; 7493391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 7494391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7495391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->p2p_last_4way_hs_fail = ssid; 7496391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 7497391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 7498cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7499cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7500cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC 7501cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7502cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic struct wpabuf * wpas_p2p_nfc_handover(int ndef, struct wpabuf *wsc, 7503cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *p2p) 7504cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7505cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *ret; 7506cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt size_t wsc_len; 7507cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7508cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (p2p == NULL) { 7509cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(wsc); 7510cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No p2p buffer for handover"); 7511cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 7512cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7513cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7514cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wsc_len = wsc ? wpabuf_len(wsc) : 0; 7515cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ret = wpabuf_alloc(2 + wsc_len + 2 + wpabuf_len(p2p)); 7516cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (ret == NULL) { 7517cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(wsc); 7518cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(p2p); 7519cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 7520cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7521cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7522cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_put_be16(ret, wsc_len); 7523cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wsc) 7524cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_put_buf(ret, wsc); 7525cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_put_be16(ret, wpabuf_len(p2p)); 7526cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_put_buf(ret, p2p); 7527cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7528cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(wsc); 7529cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(p2p); 7530cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump_buf(MSG_DEBUG, 7531cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "P2P: Generated NFC connection handover message", ret); 7532cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7533cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (ndef && ret) { 7534cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *tmp; 7535cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt tmp = ndef_build_p2p(ret); 7536cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(ret); 7537cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (tmp == NULL) { 7538cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to NDEF encapsulate handover request"); 7539cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 7540cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7541cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ret = tmp; 7542cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7543cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7544cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return ret; 7545cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7546cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7547cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7548cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_cli_freq(struct wpa_supplicant *wpa_s, 7549cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpa_ssid **ssid, u8 *go_dev_addr) 7550cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7551cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpa_supplicant *iface; 7552cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7553cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (go_dev_addr) 7554cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 7555cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (ssid) 7556cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt *ssid = NULL; 7557cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { 7558cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (iface->wpa_state < WPA_ASSOCIATING || 7559cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt iface->current_ssid == NULL || iface->assoc_freq == 0 || 7560cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt !iface->current_ssid->p2p_group || 7561cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt iface->current_ssid->mode != WPAS_MODE_INFRA) 7562cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt continue; 7563cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (ssid) 7564cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt *ssid = iface->current_ssid; 7565cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (go_dev_addr) 7566cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(go_dev_addr, iface->go_dev_addr, ETH_ALEN); 7567cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return iface->assoc_freq; 7568cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7569cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 7570cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7571cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7572cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7573cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * wpas_p2p_nfc_handover_req(struct wpa_supplicant *wpa_s, 7574cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int ndef) 7575cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7576cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *wsc, *p2p; 7577cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpa_ssid *ssid; 7578cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 7579cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr); 7580cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7581cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) { 7582cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: P2P disabled - cannot build handover request"); 7583cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 7584cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7585cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7586cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->conf->wps_nfc_dh_pubkey == NULL && 7587cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey, 7588cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt &wpa_s->conf->wps_nfc_dh_privkey) < 0) { 7589cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No DH key available for handover request"); 7590cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 7591cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7592cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7593cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (cli_freq == 0) { 7594cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wsc = wps_build_nfc_handover_req_p2p( 7595cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->wps, wpa_s->conf->wps_nfc_dh_pubkey); 7596cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else 7597cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wsc = NULL; 7598cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p = p2p_build_nfc_handover_req(wpa_s->global->p2p, cli_freq, 7599cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt go_dev_addr, ssid ? ssid->ssid : NULL, 7600cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid ? ssid->ssid_len : 0); 7601cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7602cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_nfc_handover(ndef, wsc, p2p); 7603cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7604cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7605cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7606cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstruct wpabuf * wpas_p2p_nfc_handover_sel(struct wpa_supplicant *wpa_s, 7607cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int ndef, int tag) 7608cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7609cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *wsc, *p2p; 7610cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpa_ssid *ssid; 7611cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 7612cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr); 7613cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7614cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 7615cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 7616cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7617cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!tag && wpa_s->conf->wps_nfc_dh_pubkey == NULL && 7618cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey, 7619cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt &wpa_s->conf->wps_nfc_dh_privkey) < 0) 7620cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return NULL; 7621cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7622cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (cli_freq == 0) { 7623cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wsc = wps_build_nfc_handover_sel_p2p( 7624cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->wps, 7625cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt tag ? wpa_s->conf->wps_nfc_dev_pw_id : 7626cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt DEV_PW_NFC_CONNECTION_HANDOVER, 7627cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->conf->wps_nfc_dh_pubkey, 7628cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt tag ? wpa_s->conf->wps_nfc_dev_pw : NULL); 7629cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else 7630cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wsc = NULL; 7631cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p = p2p_build_nfc_handover_sel(wpa_s->global->p2p, cli_freq, 7632cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt go_dev_addr, ssid ? ssid->ssid : NULL, 7633cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid ? ssid->ssid_len : 0); 7634cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7635cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_nfc_handover(ndef, wsc, p2p); 7636cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7637cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7638cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7639cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_join_group(struct wpa_supplicant *wpa_s, 7640cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_nfc_params *params) 7641cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7642cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Initiate join-group based on NFC " 7643cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "connection handover (freq=%d)", 7644cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_freq); 7645cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7646cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (params->go_freq && params->go_ssid_len) { 7647cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_wps_method = WPS_NFC; 7648cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->pending_join_wps_method = WPS_NFC; 7649cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memset(wpa_s->pending_join_iface_addr, 0, ETH_ALEN); 7650cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(wpa_s->pending_join_dev_addr, params->go_dev_addr, 7651cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ETH_ALEN); 7652cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_join_start(wpa_s, params->go_freq, 7653cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_ssid, 7654cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_ssid_len); 7655cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7656cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7657cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL, 7658cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt WPS_NFC, 0, 0, 1, 0, wpa_s->conf->p2p_go_intent, 7659cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->go_freq, -1, 0, 1, 1); 7660cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7661cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7662cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7663cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_auth_join(struct wpa_supplicant *wpa_s, 7664cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_nfc_params *params, int tag) 7665cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7666cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int res, persistent; 7667cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpa_ssid *ssid; 7668cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7669cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Authorize join-group based on NFC " 7670cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "connection handover"); 7671cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 7672cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid = wpa_s->current_ssid; 7673cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (ssid == NULL) 7674cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt continue; 7675cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GO) 7676cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt continue; 7677cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->ap_iface == NULL) 7678cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt continue; 7679cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt break; 7680cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7681cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s == NULL) { 7682cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not find GO interface"); 7683cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7684cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7685cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7686cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->parent->p2p_oob_dev_pw_id != 7687cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt DEV_PW_NFC_CONNECTION_HANDOVER && 7688cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt !wpa_s->parent->p2p_oob_dev_pw) { 7689cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known"); 7690cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7691cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7692cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res = wpas_ap_wps_add_nfc_pw( 7693cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s, wpa_s->parent->p2p_oob_dev_pw_id, 7694cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_oob_dev_pw, 7695cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_peer_oob_pk_hash_known ? 7696cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_peer_oob_pubkey_hash : NULL); 7697cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (res) 7698cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return res; 7699cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7700cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!tag) { 7701cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Negotiated handover - wait for peer to join without invitation"); 7702cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 7703cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7704cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7705cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!params->peer || 7706cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt !(params->peer->dev_capab & P2P_DEV_CAPAB_INVITATION_PROCEDURE)) 7707cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 7708cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7709cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Static handover - invite peer " MACSTR 7710cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt " to join", MAC2STR(params->peer->p2p_device_addr)); 7711cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7712cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->global->p2p_invite_group = wpa_s; 7713cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt persistent = ssid->p2p_persistent_group && 7714cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpas_p2p_get_persistent(wpa_s->parent, 7715cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->peer->p2p_device_addr, 7716cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid->ssid, ssid->ssid_len); 7717cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->pending_invite_ssid_id = -1; 7718cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7719cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return p2p_invite(wpa_s->global->p2p, params->peer->p2p_device_addr, 7720cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt P2P_INVITE_ROLE_ACTIVE_GO, wpa_s->own_addr, 7721cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ssid->ssid, ssid->ssid_len, ssid->frequency, 7722cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->global->p2p_dev_addr, persistent, 0, 7723cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->parent->p2p_oob_dev_pw_id); 7724cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7725cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7726cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7727cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_init_go_neg(struct wpa_supplicant *wpa_s, 7728cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_nfc_params *params, 7729cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int forced_freq) 7730cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7731cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Initiate GO Negotiation based on NFC " 7732cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "connection handover"); 7733cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL, 7734cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt WPS_NFC, 0, 0, 0, 0, wpa_s->conf->p2p_go_intent, 7735cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt forced_freq, -1, 0, 1, 1); 7736cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7737cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7738cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7739cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_resp_go_neg(struct wpa_supplicant *wpa_s, 7740cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_nfc_params *params, 7741cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int forced_freq) 7742cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7743cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int res; 7744cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7745cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Authorize GO Negotiation based on NFC " 7746cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "connection handover"); 7747cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res = wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL, 7748cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt WPS_NFC, 0, 0, 0, 1, wpa_s->conf->p2p_go_intent, 7749cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt forced_freq, -1, 0, 1, 1); 7750cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (res) 7751cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return res; 7752cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7753cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res = wpas_p2p_listen(wpa_s, 60); 7754cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (res) { 7755cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_unauthorize(wpa_s->global->p2p, 7756cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params->peer->p2p_device_addr); 7757cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7758cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7759cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return res; 7760cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7761cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7762cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7763cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic int wpas_p2p_nfc_connection_handover(struct wpa_supplicant *wpa_s, 7764cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const struct wpabuf *data, 7765cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int sel, int tag, int forced_freq) 7766cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7767cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *pos, *end; 7768cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt u16 len, id; 7769cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct p2p_nfc_params params; 7770cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int res; 7771cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7772cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 7773cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.sel = sel; 7774cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7775cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump_buf(MSG_DEBUG, "P2P: Received NFC tag payload", data); 7776cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7777cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt pos = wpabuf_head(data); 7778cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt end = pos + wpabuf_len(data); 7779cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7780cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (end - pos < 2) { 7781cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of WSC " 7782cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "attributes"); 7783cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7784cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7785cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt len = WPA_GET_BE16(pos); 7786cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt pos += 2; 77876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len > end - pos) { 7788cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Not enough data for WSC " 7789cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "attributes"); 7790cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7791cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7792cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.wsc_attr = pos; 7793cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.wsc_len = len; 7794cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt pos += len; 7795cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7796cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (end - pos < 2) { 7797cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of P2P " 7798cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "attributes"); 7799cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7800cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7801cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt len = WPA_GET_BE16(pos); 7802cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt pos += 2; 78036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len > end - pos) { 7804cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Not enough data for P2P " 7805cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "attributes"); 7806cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7807cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7808cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.p2p_attr = pos; 7809cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.p2p_len = len; 7810cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt pos += len; 7811cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7812cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: WSC attributes", 7813cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.wsc_attr, params.wsc_len); 7814cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: P2P attributes", 7815cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.p2p_attr, params.p2p_len); 7816cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (pos < end) { 7817cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump(MSG_DEBUG, 7818cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "P2P: Ignored extra data after P2P attributes", 7819cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt pos, end - pos); 7820cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7821cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7822cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt res = p2p_process_nfc_connection_handover(wpa_s->global->p2p, ¶ms); 7823cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (res) 7824cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return res; 7825cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7826cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (params.next_step == NO_ACTION) 7827cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 7828cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7829cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (params.next_step == BOTH_GO) { 7830cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_BOTH_GO "peer=" MACSTR, 7831cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MAC2STR(params.peer->p2p_device_addr)); 7832cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 7833cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7834cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7835cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (params.next_step == PEER_CLIENT) { 7836cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!is_zero_ether_addr(params.go_dev_addr)) { 7837cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT 7838cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "peer=" MACSTR " freq=%d go_dev_addr=" MACSTR 7839cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt " ssid=\"%s\"", 7840cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MAC2STR(params.peer->p2p_device_addr), 7841cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.go_freq, 7842cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MAC2STR(params.go_dev_addr), 7843cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_ssid_txt(params.go_ssid, 7844cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.go_ssid_len)); 7845cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else { 7846cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT 7847cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "peer=" MACSTR " freq=%d", 7848cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MAC2STR(params.peer->p2p_device_addr), 7849cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.go_freq); 7850cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7851cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 7852cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7853cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7854cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpas_p2p_cli_freq(wpa_s, NULL, NULL)) { 7855cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_WHILE_CLIENT "peer=" 7856cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt MACSTR, MAC2STR(params.peer->p2p_device_addr)); 7857cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 7858cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7859cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7860cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(wpa_s->p2p_oob_dev_pw); 7861cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_oob_dev_pw = NULL; 7862cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7863cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (params.oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2) { 7864cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No peer OOB Dev Pw " 7865cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "received"); 7866cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7867cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7868cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7869cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt id = WPA_GET_BE16(params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN); 7870cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer OOB Dev Pw %u", id); 7871cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Peer OOB Public Key hash", 7872cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN); 7873cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memcpy(wpa_s->p2p_peer_oob_pubkey_hash, 7874cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN); 7875cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_peer_oob_pk_hash_known = 1; 7876cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7877cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (tag) { 7878cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (id < 0x10) { 7879cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Static handover - invalid " 7880cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "peer OOB Device Password Id %u", id); 7881cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7882cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7883cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Static handover - use peer OOB " 7884cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "Device Password Id %u", id); 7885cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "P2P: Peer OOB Device Password", 7886cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2, 7887cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.oob_dev_pw_len - 7888cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt WPS_OOB_PUBKEY_HASH_LEN - 2); 7889cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_oob_dev_pw_id = id; 7890cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_oob_dev_pw = wpabuf_alloc_copy( 7891cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2, 7892cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt params.oob_dev_pw_len - 7893cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt WPS_OOB_PUBKEY_HASH_LEN - 2); 7894cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->p2p_oob_dev_pw == NULL) 7895cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7896cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7897cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->conf->wps_nfc_dh_pubkey == NULL && 7898cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey, 7899cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt &wpa_s->conf->wps_nfc_dh_privkey) < 0) 7900cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7901cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else { 7902cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Using abbreviated WPS handshake " 7903cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "without Device Password"); 7904cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_oob_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER; 7905cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7906cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7907cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt switch (params.next_step) { 7908cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case NO_ACTION: 7909cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case BOTH_GO: 7910cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case PEER_CLIENT: 7911cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt /* already covered above */ 7912cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 7913cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case JOIN_GROUP: 7914cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_nfc_join_group(wpa_s, ¶ms); 7915cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case AUTH_JOIN: 7916cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_nfc_auth_join(wpa_s, ¶ms, tag); 7917cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case INIT_GO_NEG: 7918cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_nfc_init_go_neg(wpa_s, ¶ms, forced_freq); 7919cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case RESP_GO_NEG: 7920cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt /* TODO: use own OOB Dev Pw */ 7921cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_nfc_resp_go_neg(wpa_s, ¶ms, forced_freq); 7922cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7923cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7924cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7925cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7926cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7927cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7928cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpas_p2p_nfc_tag_process(struct wpa_supplicant *wpa_s, 7929cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const struct wpabuf *data, int forced_freq) 7930cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7931cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 7932cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7933cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7934cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return wpas_p2p_nfc_connection_handover(wpa_s, data, 1, 1, forced_freq); 7935cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7936cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7937cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7938cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init, 7939cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const struct wpabuf *req, 7940cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const struct wpabuf *sel, int forced_freq) 7941cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7942cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpabuf *tmp; 7943cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int ret; 7944cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7945cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 7946cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7947cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7948cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "NFC: P2P connection handover reported"); 7949cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7950cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "NFC: Req", 7951cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_head(req), wpabuf_len(req)); 7952cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "NFC: Sel", 7953cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_head(sel), wpabuf_len(sel)); 7954cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (forced_freq) 7955cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "NFC: Forced freq %d", forced_freq); 7956cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt tmp = ndef_parse_p2p(init ? sel : req); 7957cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (tmp == NULL) { 7958cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not parse NDEF"); 7959cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7960cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7961cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7962cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ret = wpas_p2p_nfc_connection_handover(wpa_s, tmp, init, 0, 7963cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt forced_freq); 7964cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(tmp); 7965cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7966cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return ret; 7967cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 7968cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7969cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7970cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled) 7971cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 7972cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt const u8 *if_addr; 7973cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt int go_intent = wpa_s->conf->p2p_go_intent; 7974cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct wpa_supplicant *iface; 7975cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7976cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->global->p2p == NULL) 7977cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7978cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7979cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!enabled) { 7980cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Disable use of own NFC Tag"); 7981cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) 7982cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt { 7983cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!iface->ap_iface) 7984cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt continue; 7985cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt hostapd_wps_nfc_token_disable(iface->ap_iface->bss[0]); 7986cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7987cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_set_authorized_oob_dev_pw_id(wpa_s->global->p2p, 0, 7988cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 0, NULL); 7989cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->p2p_nfc_tag_enabled) 7990cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 7991cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_nfc_tag_enabled = 0; 7992cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 7993cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 7994cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7995cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->global->p2p_disabled) 7996cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 7997cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 7998cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->conf->wps_nfc_dh_pubkey == NULL || 7999cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->conf->wps_nfc_dh_privkey == NULL || 8000cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->conf->wps_nfc_dev_pw == NULL || 8001cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->conf->wps_nfc_dev_pw_id < 0x10) { 8002cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: NFC password token not configured " 8003cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "to allow static handover cases"); 8004cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 8005cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 8006cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8007cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable use of own NFC Tag"); 8008cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8009cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_oob_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id; 8010cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(wpa_s->p2p_oob_dev_pw); 8011cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_oob_dev_pw = wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw); 8012cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->p2p_oob_dev_pw == NULL) 8013cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 8014cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_peer_oob_pk_hash_known = 0; 8015cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8016b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO || 8017b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT) { 8018b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt /* 8019b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt * P2P Group Interface present and the command came on group 8020b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt * interface, so enable the token for the current interface. 8021b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt */ 8022b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_s->create_p2p_iface = 0; 8023b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } else { 8024b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s); 8025b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 8026cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8027cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpa_s->create_p2p_iface) { 8028cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt enum wpa_driver_if_type iftype; 8029cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt /* Prepare to add a new interface for the group */ 8030cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt iftype = WPA_IF_P2P_GROUP; 8031cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (go_intent == 15) 8032cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt iftype = WPA_IF_P2P_GO; 8033cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) { 8034cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new " 8035cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "interface for the group"); 8036cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 8037cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 8038cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8039cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if_addr = wpa_s->pending_interface_addr; 8040cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else 8041cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if_addr = wpa_s->own_addr; 8042cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8043cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->p2p_nfc_tag_enabled = enabled; 8044cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8045cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { 8046cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct hostapd_data *hapd; 8047cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (iface->ap_iface == NULL) 8048cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt continue; 8049cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt hapd = iface->ap_iface->bss[0]; 8050cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(hapd->conf->wps_nfc_dh_pubkey); 8051cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt hapd->conf->wps_nfc_dh_pubkey = 8052cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey); 8053cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(hapd->conf->wps_nfc_dh_privkey); 8054cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt hapd->conf->wps_nfc_dh_privkey = 8055cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey); 8056cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_free(hapd->conf->wps_nfc_dev_pw); 8057cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt hapd->conf->wps_nfc_dev_pw = 8058cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw); 8059cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt hapd->conf->wps_nfc_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id; 8060cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8061cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (hostapd_wps_nfc_token_enable(iface->ap_iface->bss[0]) < 0) { 8062cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_dbg(iface, MSG_DEBUG, 8063cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "P2P: Failed to enable NFC Tag for GO"); 8064cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 8065cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 8066cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_set_authorized_oob_dev_pw_id( 8067cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_s->global->p2p, wpa_s->conf->wps_nfc_dev_pw_id, go_intent, 8068cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if_addr); 8069cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8070cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 8071cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 8072cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 8073cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */ 807443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 807543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 807643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtstatic void wpas_p2p_optimize_listen_channel(struct wpa_supplicant *wpa_s, 807743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_used_freq_data *freqs, 807843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt unsigned int num) 807943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{ 808043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt u8 curr_chan, cand, chan; 808143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt unsigned int i; 808243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 808343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt curr_chan = p2p_get_listen_channel(wpa_s->global->p2p); 808443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt for (i = 0, cand = 0; i < num; i++) { 808543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt ieee80211_freq_to_chan(freqs[i].freq, &chan); 808643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (curr_chan == chan) { 808743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt cand = 0; 808843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt break; 808943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 809043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 809143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (chan == 1 || chan == 6 || chan == 11) 809243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt cand = chan; 809343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 809443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 809543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (cand) { 809643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 8097216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: Update Listen channel to %u based on operating channel", 809843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt cand); 809943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt p2p_set_listen_channel(wpa_s->global->p2p, 81, cand, 0); 810043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 810143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt} 810243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 810343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 810443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtvoid wpas_p2p_indicate_state_change(struct wpa_supplicant *wpa_s) 810543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{ 810643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt struct wpa_used_freq_data *freqs; 810743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt unsigned int num = wpa_s->num_multichan_concurrent; 810843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 810943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 811043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 811143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 811243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt /* 811343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * If possible, optimize the Listen channel to be a channel that is 811443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt * already used by one of the other interfaces. 811543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt */ 811643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (!wpa_s->conf->p2p_optimize_listen_chan) 811743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 811843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 811943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (!wpa_s->current_ssid || wpa_s->wpa_state != WPA_COMPLETED) 812043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 812143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 812243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt freqs = os_calloc(num, sizeof(struct wpa_used_freq_data)); 812343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (!freqs) 812443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 812543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 812643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt num = get_shared_radio_freqs_data(wpa_s, freqs, num); 812743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 812843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpas_p2p_optimize_listen_channel(wpa_s, freqs, num); 812943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt os_free(freqs); 813043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt} 813143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 813243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 813343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtvoid wpas_p2p_deinit_iface(struct wpa_supplicant *wpa_s) 813443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{ 813543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) { 813643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing " 813743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt "the management interface is being removed"); 813843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpas_p2p_deinit_global(wpa_s->global); 813943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt } 814043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt} 814143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 814243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 814343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidtvoid wpas_p2p_ap_deinit(struct wpa_supplicant *wpa_s) 814443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt{ 814543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (wpa_s->ap_iface->bss) 814643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_s->ap_iface->bss[0]->p2p_group = NULL; 814743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpas_p2p_group_deinit(wpa_s); 814843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt} 8149