18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant - P2P 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/hostapd.h" 191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "ap/ap_config.h" 20391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "ap/sta_info.h" 21391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "ap/ap_drv_ops.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/p2p_hostapd.h" 2375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "eapol_supp/eapol_supp_sm.h" 2475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "rsn_supp/wpa.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config_ssid.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h" 331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "offchannel.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h" 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * How many times to try to scan to find the GO before giving up on join 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request. 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_MAX_JOIN_SCAN_ATTEMPTS 10 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#define P2P_AUTO_PD_SCAN_ATTEMPTS 5 4504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef P2P_MAX_CLIENT_IDLE 471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/* 481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * How many seconds to try to reconnect to the GO when connection in P2P client 491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * role has been lost. 501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 5198f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#ifdef ANDROID_P2P 5298f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#define P2P_MAX_CLIENT_IDLE 20 5398f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#else 541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define P2P_MAX_CLIENT_IDLE 10 5598f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#endif /* ANDROID_P2P */ 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 6104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * WPS provisioning step. 6204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#define P2P_MAX_INITIAL_CONN_WAIT 10 6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* P2P_MAX_INITIAL_CONN_WAIT */ 6504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6692c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt#ifndef P2P_MAX_INITIAL_CONN_WAIT_GO 6792c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt/* 6892c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * How many seconds to wait for initial 4-way handshake to get completed after 6992c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * WPS provisioning step on the GO. This controls the extra time the P2P 7092c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * operation is considered to be in progress (e.g., to delay other scans) after 7192c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt * WPS provisioning has been completed on the GO during group formation. 7292c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt */ 7392c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt#define P2P_MAX_INITIAL_CONN_WAIT_GO 10 7492c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt#endif /* P2P_MAX_INITIAL_CONN_WAIT_GO */ 7592c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt 7661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifndef P2P_CONCURRENT_SEARCH_DELAY 7761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#define P2P_CONCURRENT_SEARCH_DELAY 500 7861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* P2P_CONCURRENT_SEARCH_DELAY */ 7961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 8034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-" 8134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 8261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtenum p2p_group_removal_reason { 8361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_UNKNOWN, 8461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_SILENT, 8561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_FORMATION_FAILED, 8661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_REQUESTED, 8761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_IDLE_TIMEOUT, 8861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_UNAVAILABLE, 8961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_GO_ENDING_SESSION, 90391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt P2P_GROUP_REMOVAL_PSK_FAILURE, 9161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef ANDROID_P2P 9261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_FREQ_CONFLICT 9361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif 9461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}; 9561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 96dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join_start(struct wpa_supplicant *wpa_s); 10204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr, 10504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *dev_addr, enum p2p_wps_method wps_method, 10604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int auto_join); 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s); 111f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstatic void wpas_p2p_group_formation_timeout(void *eloop_ctx, 112f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt void *timeout_ctx); 1131cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt#ifdef ANDROID_P2P 1141cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidtstatic void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx); 1151cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt#endif 11604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s, 11704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int group_added); 118d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 121c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt/* 122c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * Get the number of concurrent channels that the HW can operate, but that are 123c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * currently not in use by any of the wpa_supplicant interfaces. 124c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt */ 125c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic int wpas_p2p_num_unused_channels(struct wpa_supplicant *wpa_s) 126c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{ 127c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int *freqs; 128c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int num; 129c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 130c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int)); 131c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 132c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 133c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 134c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num = get_shared_radio_freqs(wpa_s, freqs, 135c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_s->num_multichan_concurrent); 136c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 137c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 138c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return wpa_s->num_multichan_concurrent - num; 139c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 140c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 141c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 142c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt/* 143c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * Get the frequencies that are currently in use by one or more of the virtual 144c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * interfaces, and that are also valid for P2P operation. 145c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt */ 146c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic int wpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s, 147c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int *p2p_freqs, unsigned int len) 148c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{ 149c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int *freqs; 150c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned int num, i, j; 151c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 152c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int)); 153c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 154c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 155c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 156c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num = get_shared_radio_freqs(wpa_s, freqs, 157c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_s->num_multichan_concurrent); 158c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 159c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_memset(p2p_freqs, 0, sizeof(int) * len); 160c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 161c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0, j = 0; i < num && j < len; i++) { 162c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (p2p_supported_freq(wpa_s->global->p2p, freqs[i])) 163c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt p2p_freqs[j++] = freqs[i]; 164c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 165c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 166c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 167c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 168c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return j; 169c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 170c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 171c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 172700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_p2p_set_own_freq_preference(struct wpa_supplicant *wpa_s, 173700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt int freq) 174700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 175700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 176700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; 177c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (freq > 0 && wpa_s->num_multichan_concurrent > 1 && 178c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpas_p2p_num_unused_channels(wpa_s) > 0 && 179700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->parent->conf->p2p_ignore_shared_freq) 180700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt freq = 0; 181700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p_set_own_freq_preference(wpa_s->global->p2p, freq); 182700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 183700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 184700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res) 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS)", 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) scan_res->num); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < scan_res->num; i++) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *bss = scan_res->res[i]; 198f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct os_time time_tmp_age, entry_ts; 199f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt time_tmp_age.sec = bss->age / 1000; 200f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt time_tmp_age.usec = (bss->age % 1000) * 1000; 201f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_time_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid, 203f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt bss->freq, &entry_ts, bss->level, 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const u8 *) (bss + 1), 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->ie_len) > 0) 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_scan_res_handled(wpa_s->global->p2p); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq, 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int num_req_dev_types, 21504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *req_dev_types, const u8 *dev_id, u16 pw_id) 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 21861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpa_supplicant *ifs; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params params; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_ie, *ies; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int social_channels[] = { 2412, 2437, 2462, 0, 0 }; 2231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t ielen; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { 22961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ifs->sta_scan_pending && 23037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt (wpas_scan_scheduled(ifs) || ifs->scanning) && 23161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_in_progress(wpa_s) == 2) { 23261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Delaying P2P scan to allow " 23361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "pending station mode scan to be " 23461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "completed on interface %s", ifs->ifname); 235dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen wpa_s->global->p2p_cb_on_scan_complete = 1; 23661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_supplicant_req_scan(ifs, 0, 0); 23761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 23861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 23961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 24061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P Wildcard SSID */ 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_ssids = 1; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->wps->dev.p2p = 1; 24904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev, 25004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types, req_dev_types); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_ie == NULL) 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 2561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) { 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(ies, wps_ie); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 264c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_scan_ie(wpa_s->global->p2p, ies, dev_id); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p_probe = 1; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies = wpabuf_head(ies); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies_len = wpabuf_len(ies); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SCAN_SOCIAL: 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freqs = social_channels; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SCAN_FULL: 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SCAN_SOCIAL_PLUS_ONE: 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt social_channels[3] = freq; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freqs = social_channels; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_scan(wpa_s, ¶ms); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ret) { 287043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { 288043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen if (ifs->scanning || 289043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen ifs->scan_res_handler == wpas_p2p_scan_res_handler) { 290043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen wpa_s->global->p2p_cb_on_scan_complete = 1; 291043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen ret = 1; 292043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen break; 293043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen } 2941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 295444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } else { 296444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt os_get_time(&wpa_s->scan_trigger_time); 29704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_handler; 298444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ret; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum wpa_driver_if_type wpas_p2p_if_type(int p2p_group_interface) 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p_group_interface) { 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_INTERFACE_PENDING: 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_GROUP; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_INTERFACE_GO: 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_GO; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_INTERFACE_CLIENT: 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_CLIENT; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_GROUP; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * wpas_get_p2p_group(struct wpa_supplicant *wpa_s, 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ssid_len, int *go) 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled != 0 || !s->p2p_group || 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len != ssid_len || 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) != 0) 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO && 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s != wpa_s->current_ssid) 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *go = s->mode == WPAS_MODE_P2P_GO; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_s; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s, 34561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt enum p2p_group_removal_reason removal_reason) 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *gtype; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *reason; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The current SSID was not known, but there may still be a 355aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt * pending P2P group interface waiting for provisioning or a 356aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt * P2P group that is trying to reconnect. 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->conf->ssid; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 3609d71283328fbad680cc74d9b287580e373eb4d6cJouni Malinen if (ssid->p2p_group && ssid->disabled != 2) 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3645c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen if (ssid == NULL && 3655c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE) 3665c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen { 36761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: P2P group interface " 36861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "not found"); 36961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 37061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO) 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtype = "GO"; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT || 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ssid && ssid->mode == WPAS_MODE_INFRA)) { 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->reassociate = 0; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->disconnected = 1; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_deauthenticate(wpa_s, 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtype = "client"; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtype = "GO"; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->cross_connect_in_use) { 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_in_use = 0; 385b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 386b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s", 387b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, wpa_s->cross_connect_uplink); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (removal_reason) { 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_REMOVAL_REQUESTED: 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = " reason=REQUESTED"; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 39361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_GROUP_REMOVAL_FORMATION_FAILED: 39461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt reason = " reason=FORMATION_FAILED"; 39561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_REMOVAL_IDLE_TIMEOUT: 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = " reason=IDLE"; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_REMOVAL_UNAVAILABLE: 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = " reason=UNAVAILABLE"; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 40204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_GROUP_REMOVAL_GO_ENDING_SESSION: 40304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt reason = " reason=GO_ENDING_SESSION"; 40404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 405391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt case P2P_GROUP_REMOVAL_PSK_FAILURE: 406391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt reason = " reason=PSK_FAILURE"; 407391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt break; 408687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#ifdef ANDROID_P2P 409687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt case P2P_GROUP_REMOVAL_FREQ_CONFLICT: 410687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt reason = " reason=FREQ_CONFLICT"; 411687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt break; 412687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#endif 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = ""; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (removal_reason != P2P_GROUP_REMOVAL_SILENT) { 418b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 419b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_REMOVED "%s %s%s", 420b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, gtype, reason); 42104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4231cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt#ifdef ANDROID_P2P 4241cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL); 4251cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt#endif 42604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0) 42704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout"); 428f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 4292f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_s->parent, NULL) > 0) { 430f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group formation " 431f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "timeout"); 4322f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_s->p2p_in_provisioning = 0; 4332f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt } 43404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 43561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (removal_reason != P2P_GROUP_REMOVAL_SILENT && ssid) 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_group_removed(wpa_s, ssid, gtype); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) { 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *ifname; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_driver_if_type type; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove group interface %s", 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global = wpa_s->global; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname = os_strdup(wpa_s->ifname); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = wpas_p2p_if_type(wpa_s->p2p_group_interface); 447e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = global->ifaces; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s && ifname) 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_if_remove(wpa_s, type, ifname); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ifname); 4522b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 1; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network"); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid && (ssid->p2p_group || 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION || 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) { 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int id = ssid->id; 46075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ssid == wpa_s->current_ssid) { 46175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_sm_set_config(wpa_s->wpa, NULL); 46275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid = NULL; 46475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 46575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 46675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Networks objects created during any P2P activities are not 46775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * exposed out as they might/will confuse certain non-P2P aware 46875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * applications since these network objects won't behave like 46975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * regular ones. 47075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 47175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Likewise, we don't send out network removed signals for such 47275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * network objects. 47375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, id); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_clear_status(wpa_s); 476c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 47791c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt wpa_s->sta_scan_pending = 0; 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Temporary group network not " 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found"); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 48204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->ap_iface) 48304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_ap_deinit(wpa_s); 48404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 48504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_drv_deinit_p2p_cli(wpa_s); 48661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 48761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s, 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *go_dev_addr, 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, size_t ssid_len) 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_bss *bss; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid; 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->go_params) 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->go_params->peer_interface_addr; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->bssid; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss = wpa_bss_get(wpa_s, bssid, ssid, ssid_len); 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 iface_addr[ETH_ALEN]; 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_get_interface_addr(wpa_s->global->p2p, bssid, 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface_addr) == 0) 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss = wpa_bss_get(wpa_s, iface_addr, ssid, ssid_len); 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether " 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group is persistent - BSS " MACSTR " not found", 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid)); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) { 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether " 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group is persistent - BSS " MACSTR 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " did not include P2P IE", MAC2STR(bssid)); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Probe Response IEs", 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) (bss + 1), bss->ie_len); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Beacon IEs", 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((u8 *) bss + 1) + bss->ie_len, 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->beacon_ie_len); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = p2p_get_group_capab(p2p); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr = p2p_get_go_dev_addr(p2p); 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Checking whether group is persistent: " 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group_capab=0x%x", group_capab); 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(go_dev_addr, addr, ETH_ALEN); 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO Device Address " MACSTR, 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr)); 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p); 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: BSS " MACSTR " group_capab=0x%x " 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_dev_addr=" MACSTR, 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr)); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s, 55475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct wpa_ssid *ssid, 55575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen const u8 *go_dev_addr) 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int changed = 0; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Storing credentials for a persistent " 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group (GO Dev Addr " MACSTR ")", MAC2STR(go_dev_addr)); 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled == 2 && 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(go_dev_addr, s->bssid, ETH_ALEN) == 0 && 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len == ssid->ssid_len && 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid->ssid, s->ssid, ssid->ssid_len) == 0) 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s) { 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Update existing persistent group " 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "entry"); 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->passphrase && !s->passphrase) 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt changed = 1; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (ssid->passphrase && s->passphrase && 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(ssid->passphrase, s->passphrase) != 0) 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt changed = 1; 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Create a new persistent group " 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "entry"); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt changed = 1; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = wpa_config_add_network(wpa_s->conf); 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s == NULL) 58475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 58575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 58675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 58775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Instead of network_added we emit persistent_group_added 58875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * notification. Also to keep the defense checks in 58975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * persistent_group obj registration method, we set the 59075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * relevant flags in s to designate it as a persistent group. 59175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 59275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen s->p2p_group = 1; 59375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen s->p2p_persistent_group = 1; 59475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_persistent_group_added(wpa_s, s); 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_network_defaults(s); 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->p2p_group = 1; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->p2p_persistent_group = 1; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->disabled = 2; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->bssid_set = 1; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(s->bssid, go_dev_addr, ETH_ALEN); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->mode = ssid->mode; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->auth_alg = WPA_AUTH_ALG_OPEN; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->key_mgmt = WPA_KEY_MGMT_PSK; 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->proto = WPA_PROTO_RSN; 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->pairwise_cipher = WPA_CIPHER_CCMP; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->export_keys = 1; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->passphrase) { 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(s->passphrase); 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->passphrase = os_strdup(ssid->passphrase); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->psk_set) { 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->psk_set = 1; 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(s->psk, ssid->psk, 32); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->passphrase && !s->psk_set) 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_update_psk(s); 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->ssid == NULL || s->ssid_len < ssid->ssid_len) { 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(s->ssid); 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid = os_malloc(ssid->ssid_len); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->ssid) { 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len = ssid->ssid_len; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(s->ssid, ssid->ssid, s->ssid_len); 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 627391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO && wpa_s->global->add_psk) { 628391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_add(&s->psk_list, &wpa_s->global->add_psk->list); 629391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 630391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt changed = 1; 631391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (changed && wpa_s->conf->update_config && 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_write(wpa_s->confname, wpa_s->conf)) { 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */ 63975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 64075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return s->id; 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s, 6451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr) 6461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 6471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *ssid, *s; 6481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *n; 6491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t i; 65061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int found = 0; 6511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = wpa_s->current_ssid; 6531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 6541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !ssid->p2p_persistent_group) 6551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 6561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (s = wpa_s->parent->conf->ssid; s; s = s->next) { 6581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO) 6591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 6601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->ssid_len == ssid->ssid_len && 6621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0) 6631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 6641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s == NULL) 6671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 6681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) { 6701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr, 67161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ETH_ALEN) != 0) 67261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 67361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 67461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (i == s->num_p2p_clients - 1) 67561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; /* already the most recent entry */ 67661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 67761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* move the entry to mark it most recent */ 67861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memmove(s->p2p_client_list + i * ETH_ALEN, 67961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->p2p_client_list + (i + 1) * ETH_ALEN, 68061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (s->num_p2p_clients - i - 1) * ETH_ALEN); 68161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(s->p2p_client_list + 68261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (s->num_p2p_clients - 1) * ETH_ALEN, addr, ETH_ALEN); 68361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt found = 1; 68461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 6851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 68761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) { 68861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt n = os_realloc_array(s->p2p_client_list, 68961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->num_p2p_clients + 1, ETH_ALEN); 69061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (n == NULL) 69161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 69261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN); 69361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->p2p_client_list = n; 69461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->num_p2p_clients++; 69561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (!found) { 69661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Not enough room for an additional entry - drop the oldest 69761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * entry */ 69861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memmove(s->p2p_client_list, 69961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->p2p_client_list + ETH_ALEN, 70061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (s->num_p2p_clients - 1) * ETH_ALEN); 70161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(s->p2p_client_list + 70261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (s->num_p2p_clients - 1) * ETH_ALEN, 70361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt addr, ETH_ALEN); 70461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 7051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE 7071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->parent->conf->update_config && 7081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf)) 7091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 7101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */ 7111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 7121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_group_formation_completed(struct wpa_supplicant *wpa_s, 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int success) 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ssid_txt; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int client; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int persistent; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 72275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int network_id = -1; 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is likely called for the main interface. Update wpa_s 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to use the group interface if a new interface was created for the 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group. 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_group_formation) 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpa_s->global->p2p_group_formation; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_in_provisioning = 0; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 735b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 736b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_FAILURE); 73761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, 73861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_FORMATION_FAILED); 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 742b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 743b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_SUCCESS); 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) { 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->mode = WPAS_MODE_P2P_GO; 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_notif_formation_done(wpa_s->p2p_group); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_mac_addr_filter(wpa_s, NULL); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = 0; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid) { 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len); 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = ssid->mode == WPAS_MODE_INFRA; 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = ssid->p2p_persistent_group; 758497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr, 759497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt ETH_ALEN); 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = wpas_p2p_persistent_group(wpa_s, 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_dev_addr, 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid, 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len); 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_txt = ""; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = wpa_s->p2p_group_interface == 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_GROUP_INTERFACE_CLIENT; 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 0; 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client) { 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Indicate event only after successfully completed 4-way 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake, i.e., when the interface is ready for data 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * packets. 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 1; 7804b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt#ifdef ANDROID_P2P 7814b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt /* For client Second phase of Group formation (4-way handshake) can be still pending 7824b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt * So we need to restore wpa_s->global->p2p_group_formation */ 783a2854abb63b41c123e4c78e5653a55d902f00be6Dmitry Shmidt wpa_printf(MSG_INFO, "Restoring back wpa_s->global->p2p_group_formation to wpa_s %p\n", wpa_s); 7844b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt wpa_s->global->p2p_group_formation = wpa_s; 7854b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt#endif 7864b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (ssid && ssid->passphrase == NULL && ssid->psk_set) { 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char psk[65]; 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32); 790b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 791b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "%s GO ssid=\"%s\" freq=%d psk=%s go_dev_addr=" 792b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR "%s", 793b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, ssid_txt, ssid->frequency, psk, 794b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(go_dev_addr), 795b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt persistent ? " [PERSISTENT]" : ""); 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_cross_connect_setup(wpa_s); 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 799b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 800b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "%s GO ssid=\"%s\" freq=%d passphrase=\"%s\" " 801b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "go_dev_addr=" MACSTR "%s", 802b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, ssid_txt, 803b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt ssid ? ssid->frequency : 0, 804b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt ssid && ssid->passphrase ? ssid->passphrase : "", 805b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(go_dev_addr), 806b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt persistent ? " [PERSISTENT]" : ""); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_cross_connect_setup(wpa_s); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (persistent) 81275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = wpas_p2p_store_persistent_group(wpa_s->parent, 81375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ssid, go_dev_addr); 814391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else { 815391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(wpa_s->global->add_psk); 816391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 817391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 8181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (network_id < 0 && ssid) 81975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = ssid->id; 82092c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt if (!client) { 82175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0); 82292c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt os_get_time(&wpa_s->global->p2p_go_wait_client); 82392c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt } 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s, 8281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt unsigned int freq, 8291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *dst, const u8 *src, 8301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *bssid, 8311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *data, size_t data_len, 8321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt enum offchannel_send_action_result 8331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt result) 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt enum p2p_send_action_result res = P2P_SEND_ACTION_SUCCESS; 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (result) { 8431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OFFCHANNEL_SEND_ACTION_SUCCESS: 8441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = P2P_SEND_ACTION_SUCCESS; 8451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 8461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OFFCHANNEL_SEND_ACTION_NO_ACK: 8471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = P2P_SEND_ACTION_NO_ACK; 8481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 8491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OFFCHANNEL_SEND_ACTION_FAILED: 8501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = P2P_SEND_ACTION_FAILED; 8511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res); 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 856c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (result != OFFCHANNEL_SEND_ACTION_SUCCESS && 857c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->pending_pd_before_join && 8581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 || 859d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0) && 860d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->p2p_fallback_to_go_neg) { 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 862d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req " 863d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "during p2p_connect-auto"); 864d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_fallback_to_go_neg(wpa_s, 0); 865d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst, 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 8751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len, 8761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wait_time, 8771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_send_action_tx_status, 1); 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_send_action_done(void *ctx) 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 8841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offchannel_send_action_done(wpa_s); 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_copy_go_neg_results(struct wpa_supplicant *wpa_s, 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *params) 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->go_params == NULL) { 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->go_params = os_malloc(sizeof(*params)); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->go_params == NULL) 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->go_params, params, sizeof(*params)); 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s, 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *res) 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Start WPS Enrollee for peer " MACSTR, 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(res->peer_interface_addr)); 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Start WPS Enrollee for SSID", 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->ssid, res->ssid_len); 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_deinit(wpa_s); 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_copy_go_neg_results(wpa_s, res); 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->wps_method == WPS_PBC) 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1); 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 dev_pw_id = DEV_PW_DEFAULT; 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD) 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED; 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_wps_start_pin(wpa_s, res->peer_interface_addr, 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_pin, 1, dev_pw_id); 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 922391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_add_psk_list(struct wpa_supplicant *wpa_s, 923391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *ssid) 924391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 925391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *persistent; 926391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct psk_list_entry *psk; 927391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_data *hapd; 928391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 929391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!wpa_s->ap_iface) 930391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 931391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 932391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid, 933391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid_len); 934391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (persistent == NULL) 935391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 936391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 937391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hapd = wpa_s->ap_iface->bss[0]; 938391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 939391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_for_each(psk, &persistent->psk_list, struct psk_list_entry, 940391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt list) { 941391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_wpa_psk *hpsk; 942391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 943391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add persistent group PSK entry for " 944391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR " psk=%d", 945391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(psk->addr), psk->p2p); 946391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hpsk = os_zalloc(sizeof(*hpsk)); 947391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (hpsk == NULL) 948391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt break; 949391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(hpsk->psk, psk->psk, PMK_LEN); 950391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (psk->p2p) 951391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(hpsk->p2p_dev_addr, psk->addr, ETH_ALEN); 952391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else 953391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(hpsk->addr, psk->addr, ETH_ALEN); 954391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hpsk->next = hapd->conf->ssid.wpa_psk; 955391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hapd->conf->ssid.wpa_psk = hpsk; 956391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 957391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 958391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 959391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_configured(void *ctx, void *data) 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *params = data; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 96575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int network_id = -1; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_P2P_GO) { 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning"); 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_group_formation == wpa_s) 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 972a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (os_strlen(params->passphrase) > 0) { 973b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 974b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_STARTED 975b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "%s GO ssid=\"%s\" freq=%d " 976b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "passphrase=\"%s\" go_dev_addr=" MACSTR 977b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "%s", wpa_s->ifname, 978b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len), 979b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt ssid->frequency, params->passphrase, 980b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(wpa_s->global->p2p_dev_addr), 981b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt params->persistent_group ? 982b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " [PERSISTENT]" : ""); 983a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 984a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt char psk[65]; 985a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_snprintf_hex(psk, sizeof(psk), params->psk, 986a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(params->psk)); 987b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 988b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_STARTED 989b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "%s GO ssid=\"%s\" freq=%d psk=%s " 990b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "go_dev_addr=" MACSTR "%s", 991b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, 992b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len), 993b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt ssid->frequency, psk, 994b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(wpa_s->global->p2p_dev_addr), 995b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt params->persistent_group ? 996b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " [PERSISTENT]" : ""); 997a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 9981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 999391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (params->persistent_group) { 100075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = wpas_p2p_store_persistent_group( 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent, ssid, 1002497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt wpa_s->global->p2p_dev_addr); 1003391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_p2p_add_psk_list(wpa_s, ssid); 1004391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 100575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (network_id < 0) 100675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = ssid->id; 100775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0); 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_cross_connect_setup(wpa_s); 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Setting up WPS for GO provisioning"); 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_ap_mac_addr_filter(wpa_s, 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->peer_interface_addr)) { 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to setup MAC address " 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filtering"); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wps_method == WPS_PBC) 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr, 10221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->peer_device_addr); 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_s->p2p_pin[0]) 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr, 1025d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->p2p_pin, NULL, 0, 0); 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->go_params); 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->go_params = NULL; 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_start_wps_go(struct wpa_supplicant *wpa_s, 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *params, 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int group_formation) 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1037aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Starting GO"); 1038aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (wpas_copy_go_neg_results(wpa_s, params) < 0) { 1039aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not copy GO Negotiation " 1040aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "results"); 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1042aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_config_add_network(wpa_s->conf); 1045aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (ssid == NULL) { 1046aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not add network for GO"); 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1048aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->show_group_started = 0; 10511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_network_defaults(ssid); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->temporary = 1; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->p2p_group = 1; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->p2p_persistent_group = params->persistent_group; 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION : 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPAS_MODE_P2P_GO; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->frequency = params->freq; 105961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ssid->ht40 = params->ht40; 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid = os_zalloc(params->ssid_len + 1); 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->ssid) { 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid->ssid, params->ssid, params->ssid_len); 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len = params->ssid_len; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->auth_alg = WPA_AUTH_ALG_OPEN; 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->key_mgmt = WPA_KEY_MGMT_PSK; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->proto = WPA_PROTO_RSN; 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->pairwise_cipher = WPA_CIPHER_CCMP; 1069a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (os_strlen(params->passphrase) > 0) { 1070a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ssid->passphrase = os_strdup(params->passphrase); 1071a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (ssid->passphrase == NULL) { 1072b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_ERROR, 1073b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "P2P: Failed to copy passphrase for GO"); 1074a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, ssid->id); 1075a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return; 1076a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1077a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else 1078a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ssid->passphrase = NULL; 1079d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid->psk_set = params->psk_set; 1080d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (ssid->psk_set) 1081d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(ssid->psk, params->psk, sizeof(ssid->psk)); 1082a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else if (ssid->passphrase) 1083d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_config_update_psk(ssid); 108461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ssid->ap_max_inactivity = wpa_s->parent->conf->p2p_go_max_inactivity; 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ap_configured_cb = p2p_go_configured; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ap_configured_cb_ctx = wpa_s; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ap_configured_cb_data = wpa_s->go_params; 108975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->connect_without_scan = ssid; 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->reassociate = 1; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->disconnected = 0; 1092aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Request scan (that will be skipped) to " 1093aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "start GO)"); 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 0, 0); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_clone_config(struct wpa_supplicant *dst, 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_supplicant *src) 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_config *d; 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_config *s; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d = dst->conf; 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = src->conf; 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define C(n) if (s->n) d->n = os_strdup(s->n) 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(device_name); 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(manufacturer); 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(model_name); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(model_number); 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(serial_number); 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(config_methods); 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef C 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN); 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(d->sec_device_type, s->sec_device_type, 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(d->sec_device_type)); 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d->num_sec_device_types = s->num_sec_device_types; 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d->p2p_group_idle = s->p2p_group_idle; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d->p2p_intra_bss = s->p2p_intra_bss; 11231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt d->persistent_reconnect = s->persistent_reconnect; 112404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt d->max_num_sta = s->max_num_sta; 112504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt d->pbc_in_m1 = s->pbc_in_m1; 1126444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt d->ignore_old_scan_res = s->ignore_old_scan_res; 112751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt d->beacon_int = s->beacon_int; 1128b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt d->disassoc_low_ack = s->disassoc_low_ack; 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 113234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s, 113334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *ifname, size_t len) 113434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 113534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *ifname_ptr = wpa_s->ifname; 113634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 113734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX, 113834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) { 113934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1; 114034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 114134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 114234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx); 114334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (os_strlen(ifname) >= IFNAMSIZ && 114434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_strlen(wpa_s->ifname) < IFNAMSIZ) { 114534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt /* Try to avoid going over the IFNAMSIZ length limit */ 114634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_snprintf(ifname, sizeof(ifname), "p2p-%d", 114734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->p2p_group_idx); 114834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 114934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 115034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 115134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s, 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_driver_if_type type) 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char ifname[120], force_ifname[120]; 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->pending_interface_name[0]) { 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Pending virtual interface exists " 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "- skip creation of a new one"); 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(wpa_s->pending_interface_addr)) { 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Pending virtual address " 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unknown?! ifname='%s'", 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name); 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 116934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname)); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_ifname[0] = '\0'; 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group", 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname); 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group_idx++; 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_type = type; 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_if_add(wpa_s, type, ifname, NULL, NULL, force_ifname, 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_addr, NULL) < 0) { 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to create new group " 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface"); 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_ifname[0]) { 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s", 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_ifname); 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->pending_interface_name, force_ifname, 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->pending_interface_name)); 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->pending_interface_name, ifname, 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->pending_interface_name)); 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Created pending virtual interface %s addr " 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, wpa_s->pending_interface_name, 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_interface_addr)); 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_remove_pending_group_interface( 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s) 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->pending_interface_name[0] || 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt is_zero_ether_addr(wpa_s->pending_interface_addr)) 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending virtual interface */ 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Removing pending group interface %s", 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name); 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_if_remove(wpa_s, wpa_s->pending_interface_type, 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name); 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN); 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go) 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_interface iface; 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group_wpa_s; 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->pending_interface_name[0]) { 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: No pending group interface"); 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpas_p2p_create_iface(wpa_s)) 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Something has forced us to remove the pending interface; try 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to create a new one and hope for the best that we will get 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the same local address. 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO : 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_IF_P2P_CLIENT) < 0) 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&iface, 0, sizeof(iface)); 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.ifname = wpa_s->pending_interface_name; 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.driver = wpa_s->driver->name; 123934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (wpa_s->conf->ctrl_interface == NULL && 124034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->parent != wpa_s && 124134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->p2p_mgmt && 124234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) 124334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface; 124434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else 124534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.ctrl_interface = wpa_s->conf->ctrl_interface; 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.driver_param = wpa_s->conf->driver_param; 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface); 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s == NULL) { 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to create new " 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wpa_supplicant interface"); 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->parent = wpa_s; 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->p2p_group_interface = go ? P2P_GROUP_INTERFACE_GO : 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_GROUP_INTERFACE_CLIENT; 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = group_wpa_s; 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clone_config(group_wpa_s, wpa_s); 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group_wpa_s; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_formation_timeout(void *eloop_ctx, 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *timeout_ctx) 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out"); 127034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpas_p2p_group_formation_failed(wpa_s); 127134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 127234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 127334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 127434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtvoid wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s) 127534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 127634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 127734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->parent, NULL); 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_formation_failed(wpa_s->global->p2p); 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_p2p_group_formation_failed(wpa_s); 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_group_formation_completed(wpa_s, 0); 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1286391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s) 1287391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 1288391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->global->p2p_group_formation != wpa_s) 1289391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 1290391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Speed up group formation timeout since this cannot succeed */ 1291391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 1292391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->parent, NULL); 1293391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout, 1294391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->parent, NULL); 1295391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 1296391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 1297391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res) 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_cancel_remain_on_channel(wpa_s); 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->off_channel_freq = 0; 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->roc_waiting_drv_freq = 0; 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->status) { 1309b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 1310b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GO_NEG_FAILURE "status=%d", 1311b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt res->status); 13121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_notify_p2p_go_neg_completed(wpa_s, res); 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 131761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->p2p_go_ht40) 131861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res->ht40 = 1; 131961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1320b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS "role=%s " 1321b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt "freq=%d ht40=%d peer_dev=" MACSTR " peer_iface=" MACSTR 1322b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt " wps_method=%s", 1323b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt res->role_go ? "GO" : "client", res->freq, res->ht40, 1324b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt MAC2STR(res->peer_device_addr), 1325b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt MAC2STR(res->peer_interface_addr), 1326b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt p2p_wps_method_text(res->wps_method)); 13271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_notify_p2p_go_neg_completed(wpa_s, res); 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 132904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (res->role_go && wpa_s->p2p_persistent_id >= 0) { 133004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid; 133104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, 133204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id); 133304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid && ssid->disabled == 2 && 133404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->mode == WPAS_MODE_P2P_GO && ssid->passphrase) { 133504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t len = os_strlen(ssid->passphrase); 133604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Override passphrase based " 133704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "on requested persistent group"); 133804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(res->passphrase, ssid->passphrase, len); 133904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res->passphrase[len] = '\0'; 134004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 134104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 134204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->create_p2p_iface) { 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group_wpa_s = 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_init_group_interface(wpa_s, res->role_go); 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s == NULL) { 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s != wpa_s) { 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_wpa_s->p2p_pin, wpa_s->p2p_pin, 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(group_wpa_s->p2p_pin)); 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->p2p_wps_method = wpa_s->p2p_wps_method; 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN); 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->p2p_in_provisioning = 1; 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->role_go) 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(group_wpa_s, res, 1); 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_enrollee(group_wpa_s, res); 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_in_provisioning = 1; 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = wpa_s; 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->role_go) 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(wpa_s, res, 1); 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_enrollee(ctx, res); 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(15 + res->peer_config_timeout / 100, 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (res->peer_config_timeout % 100) * 10000, 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_formation_timeout, wpa_s, NULL); 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id) 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 1386b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_REQUEST MACSTR 1387b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " dev_passwd_id=%u", MAC2STR(src), dev_passwd_id); 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id); 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_dev_found(void *ctx, const u8 *addr, 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_peer_info *info, 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int new_device) 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 14008367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#define WFD_DEV_INFO_SIZE 9 14018367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff char wfd_dev_info_hex[2 * WFD_DEV_INFO_SIZE + 1]; 14028d96518810ad721dc2f07d3b08a186ce23db06ffIrfan Sheriff os_memset(wfd_dev_info_hex, 0, sizeof(wfd_dev_info_hex)); 14038367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#ifdef CONFIG_WIFI_DISPLAY 14048367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff if (info->wfd_subelems) { 14058367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff wpa_snprintf_hex(wfd_dev_info_hex, sizeof(wfd_dev_info_hex), 14068367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff wpabuf_head(info->wfd_subelems), 14078367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff WFD_DEV_INFO_SIZE); 14088367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff } 14098367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#endif /* CONFIG_WIFI_DISPLAY */ 1410b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR 1411b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " p2p_dev_addr=" MACSTR 1412b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " pri_dev_type=%s name='%s' config_methods=0x%x " 1413b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "dev_capab=0x%x group_capab=0x%x%s%s", 1414b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(addr), MAC2STR(info->p2p_device_addr), 1415b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wps_dev_type_bin2str(info->pri_dev_type, devtype, 1416b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt sizeof(devtype)), 1417b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt info->device_name, info->config_methods, 1418b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt info->dev_capab, info->group_capab, 1419b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wfd_dev_info_hex[0] ? " wfd_dev_info=0x" : "", wfd_dev_info_hex); 14201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device); 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_dev_lost(void *ctx, const u8 *dev_addr) 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 14291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1430b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST 1431b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "p2p_dev_addr=" MACSTR, MAC2STR(dev_addr)); 14321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_device_lost(wpa_s, dev_addr); 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1437b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void wpas_find_stopped(void *ctx) 1438b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 1439b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 1440b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_FIND_STOPPED); 1441b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 1442b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 1443b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_start_listen(void *ctx, unsigned int freq, 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int duration, 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *probe_resp_ie) 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_set_ap_wps_ie(wpa_s, NULL, probe_resp_ie, NULL); 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_probe_req_report(wpa_s, 1) < 0) { 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to " 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "report received Probe Request frames"); 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_freq = freq; 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_duration = duration; 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_remain_on_channel(wpa_s, freq, duration) < 0) { 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver " 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to remain on channel (%u MHz) for Listen " 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state", freq); 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_freq = 0; 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->off_channel_freq = 0; 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->roc_waiting_drv_freq = freq; 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_stop_listen(void *ctx) 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_cancel_remain_on_channel(wpa_s); 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->off_channel_freq = 0; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->roc_waiting_drv_freq = 0; 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_set_ap_wps_ie(wpa_s, NULL, NULL, NULL); 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_probe_req_report(wpa_s, 0); 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_send_probe_resp(void *ctx, const struct wpabuf *buf) 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 14911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1); 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1495d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/* 1496d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * DNS Header section is used only to calculate compression pointers, so the 1497d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * contents of this data does not matter, but the length needs to be reserved 1498d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * in the virtual packet. 1499d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 1500d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#define DNS_HEADER_LEN 12 1501d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1502d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/* 1503d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * 27-octet in-memory packet from P2P specification containing two implied 1504d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * queries for _tcp.lcoal. PTR IN and _udp.local. PTR IN 1505d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 1506d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#define P2P_SD_IN_MEMORY_LEN 27 1507d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1508d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int p2p_sd_dns_uncompress_label(char **upos, char *uend, u8 *start, 1509d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u8 **spos, const u8 *end) 1510d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 1511d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt while (*spos < end) { 1512d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u8 val = ((*spos)[0] & 0xc0) >> 6; 1513d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int len; 1514d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1515d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (val == 1 || val == 2) { 1516d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* These are reserved values in RFC 1035 */ 1517d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid domain name " 1518d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "sequence starting with 0x%x", val); 1519d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1520d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1521d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1522d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (val == 3) { 1523d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u16 offset; 1524d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u8 *spos_tmp; 1525d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1526d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Offset */ 1527d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (*spos + 2 > end) { 1528d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No room for full " 1529d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "DNS offset field"); 1530d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1531d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1532d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1533d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt offset = (((*spos)[0] & 0x3f) << 8) | (*spos)[1]; 1534d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (offset >= *spos - start) { 1535d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid DNS " 1536d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "pointer offset %u", offset); 1537d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1538d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1539d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1540d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*spos) += 2; 1541d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt spos_tmp = start + offset; 1542d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return p2p_sd_dns_uncompress_label(upos, uend, start, 1543d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt &spos_tmp, 1544d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *spos - 2); 1545d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1546d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1547d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Label */ 1548d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt len = (*spos)[0] & 0x3f; 1549d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (len == 0) 1550d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 1551d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1552d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*spos)++; 1553d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (*spos + len > end) { 1554d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid domain name " 1555d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "sequence - no room for label with length " 1556d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "%u", len); 1557d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1558d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1559d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1560d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (*upos + len + 2 > uend) 1561d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -2; 1562d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1563d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(*upos, *spos, len); 1564d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *spos += len; 1565d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *upos += len; 1566d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*upos)[0] = '.'; 1567d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*upos)++; 1568d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*upos)[0] = '\0'; 1569d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1570d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1571d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 1572d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 1573d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1574d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1575d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/* Uncompress domain names per RFC 1035 using the P2P SD in-memory packet. 1576d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * Returns -1 on parsing error (invalid input sequence), -2 if output buffer is 1577d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * not large enough */ 1578d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int p2p_sd_dns_uncompress(char *buf, size_t buf_len, const u8 *msg, 1579d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt size_t msg_len, size_t offset) 1580d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 1581d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 27-octet in-memory packet from P2P specification */ 1582d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const char *prefix = "\x04_tcp\x05local\x00\x00\x0C\x00\x01" 1583d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "\x04_udp\xC0\x11\x00\x0C\x00\x01"; 1584d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u8 *tmp, *end, *spos; 1585d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt char *upos, *uend; 1586d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int ret = 0; 1587d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1588d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (buf_len < 2) 1589d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1590d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (offset > msg_len) 1591d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1592d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1593d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tmp = os_malloc(DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN + msg_len); 1594d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (tmp == NULL) 1595d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1596d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt spos = tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN; 1597d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt end = spos + msg_len; 1598d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt spos += offset; 1599d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1600d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memset(tmp, 0, DNS_HEADER_LEN); 1601d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(tmp + DNS_HEADER_LEN, prefix, P2P_SD_IN_MEMORY_LEN); 1602d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN, msg, msg_len); 1603d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1604d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt upos = buf; 1605d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt uend = buf + buf_len; 1606d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1607d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ret = p2p_sd_dns_uncompress_label(&upos, uend, tmp, &spos, end); 1608d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (ret) { 1609d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(tmp); 1610d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return ret; 1611d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1612d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1613d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (upos == buf) { 1614d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt upos[0] = '.'; 1615d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt upos[1] = '\0'; 1616d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else if (upos[-1] == '.') 1617d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt upos[-1] = '\0'; 1618d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1619d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(tmp); 1620d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 1621d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 1622d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1623d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_srv_bonjour * 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_service_get_bonjour(struct wpa_supplicant *wpa_s, 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *query) 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = wpabuf_len(query); 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour, 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour, list) { 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len == wpabuf_len(bsrv->query) && 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(wpabuf_head(query), wpabuf_head(bsrv->query), 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len) == 0) 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return bsrv; 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_srv_upnp * 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_service_get_upnp(struct wpa_supplicant *wpa_s, u8 version, 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *service) 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp, 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp, list) { 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (version == usrv->version && 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(service, usrv->service) == 0) 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return usrv; 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_add_proto_not_avail(struct wpabuf *resp, u8 srv_proto, 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_trans_id) 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 5) 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Length (to be filled) */ 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_proto); 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_PROTO_NOT_AVAILABLE); 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data: empty */ 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2); 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_all_bonjour(struct wpa_supplicant *wpa_s, 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id) 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: SD Request for all Bonjour services"); 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) { 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available"); 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour, 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour, list) { 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5 + wpabuf_len(bsrv->query) + wpabuf_len(bsrv->resp)) 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Length (to be filled) */ 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_BONJOUR); 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service", 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(bsrv->resp), 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(bsrv->resp)); 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data */ 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(resp, bsrv->query); /* Key */ 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(resp, bsrv->resp); /* Value */ 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2); 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1714d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int match_bonjour_query(struct p2p_srv_bonjour *bsrv, const u8 *query, 1715d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt size_t query_len) 1716d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 1717d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt char str_rx[256], str_srv[256]; 1718d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1719d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (query_len < 3 || wpabuf_len(bsrv->query) < 3) 1720d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* Too short to include DNS Type and Version */ 1721d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (os_memcmp(query + query_len - 3, 1722d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_head_u8(bsrv->query) + wpabuf_len(bsrv->query) - 3, 1723d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3) != 0) 1724d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* Mismatch in DNS Type or Version */ 1725d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (query_len == wpabuf_len(bsrv->query) && 1726d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcmp(query, wpabuf_head(bsrv->query), query_len - 3) == 0) 1727d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; /* Binary match */ 1728d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1729d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p_sd_dns_uncompress(str_rx, sizeof(str_rx), query, query_len - 3, 1730d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 0)) 1731d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* Failed to uncompress query */ 1732d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p_sd_dns_uncompress(str_srv, sizeof(str_srv), 1733d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_head(bsrv->query), 1734d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_len(bsrv->query) - 3, 0)) 1735d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* Failed to uncompress service */ 1736d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1737d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return os_strcmp(str_rx, str_srv) == 0; 1738d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 1739d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1740d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_req_bonjour(struct wpa_supplicant *wpa_s, 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id, 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *query, size_t query_len) 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 1747d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int matches = 0; 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for Bonjour", 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query, query_len); 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) { 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available"); 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_add_proto_not_avail(resp, P2P_SERV_BONJOUR, 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (query_len == 0) { 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id); 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1763d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour, 1764d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct p2p_srv_bonjour, list) { 1765d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!match_bonjour_query(bsrv, query, query_len)) 1766d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt continue; 1767d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1768d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpabuf_tailroom(resp) < 1769d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5 + query_len + wpabuf_len(bsrv->resp)) 1770d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 1771d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1772d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt matches++; 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1774d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Length (to be filled) */ 1775d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt len_pos = wpabuf_put(resp, 2); 1776d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_BONJOUR); 1777d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 1778d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1779d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Status Code */ 1780d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); 1781d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service", 1782d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_head(bsrv->resp), 1783d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_len(bsrv->resp)); 1784d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1785d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Response Data */ 1786d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_data(resp, query, query_len); /* Key */ 1787d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_buf(resp, bsrv->resp); /* Value */ 1788d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1789d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2); 1790d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1791d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1792d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (matches == 0) { 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Requested Bonjour service not " 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available"); 1795d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpabuf_tailroom(resp) < 5) 1796d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 1797d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1798d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Length (to be filled) */ 1799d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt len_pos = wpabuf_put(resp, 2); 1800d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_BONJOUR); 1801d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE); 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data: empty */ 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2); 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_all_upnp(struct wpa_supplicant *wpa_s, 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id) 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: SD Request for all UPnP services"); 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) { 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available"); 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp, 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp, list) { 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 5 + 1 + os_strlen(usrv->service)) 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Length (to be filled) */ 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_UPNP); 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data */ 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, usrv->version); 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s", 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv->service); 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_str(resp, usrv->service); 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2); 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_req_upnp(struct wpa_supplicant *wpa_s, 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id, 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *query, size_t query_len) 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 version; 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *str; 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count = 0; 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for UPnP", 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query, query_len); 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) { 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available"); 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_add_proto_not_avail(resp, P2P_SERV_UPNP, 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (query_len == 0) { 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_upnp(wpa_s, resp, srv_trans_id); 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 5) 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Length (to be filled) */ 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_UPNP); 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version = query[0]; 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = os_malloc(query_len); 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (str == NULL) 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(str, query + 1, query_len - 1); 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str[query_len - 1] = '\0'; 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp, 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp, list) { 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (version != usrv->version) 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(str, "ssdp:all") != 0 && 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strstr(usrv->service, str) == NULL) 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 2) 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count == 0) { 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data */ 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, version); 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, ','); 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s", 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv->service); 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < os_strlen(usrv->service)) 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_str(resp, usrv->service); 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(str); 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count == 0) { 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Requested UPnP service not " 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available"); 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE); 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data: empty */ 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2); 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 192961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 193061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void wpas_sd_req_wfd(struct wpa_supplicant *wpa_s, 193161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id, 193261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *query, size_t query_len) 193361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 193461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *pos; 193561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 role; 193661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len_pos; 193761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 193861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: SD Request for WFD", query, query_len); 193961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 194061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!wpa_s->global->wifi_display) { 194161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: WFD protocol not available"); 194261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_sd_add_proto_not_avail(resp, P2P_SERV_WIFI_DISPLAY, 194361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt srv_trans_id); 194461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 194561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 194661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 194761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (query_len < 1) { 194861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Missing WFD Requested Device " 194961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "Role"); 195061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 195161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 195261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 195361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpabuf_tailroom(resp) < 5) 195461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 195561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 195661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = query; 195761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt role = *pos++; 195861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: WSD for device role 0x%x", role); 195961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 196061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* TODO: role specific handling */ 196161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 196261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Length (to be filled) */ 196361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 196461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_WIFI_DISPLAY); 196561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 196661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); /* Status Code */ 196761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 196861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (pos < query + query_len) { 196961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*pos < MAX_WFD_SUBELEMS && 197061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->global->wfd_subelem[*pos] && 197161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_tailroom(resp) >= 197261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(wpa_s->global->wfd_subelem[*pos])) { 197361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Add WSD response " 197461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "subelement %u", *pos); 197561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(resp, wpa_s->global->wfd_subelem[*pos]); 197661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 197761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 197861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 197961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 198061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2); 198161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 198261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 198361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 198461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token, 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 update_indic, const u8 *tlvs, size_t tlvs_len) 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = tlvs; 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end = tlvs + tlvs_len; 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *tlv_end; 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 slen; 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_proto, srv_trans_id; 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buf_len; 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf; 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Request TLVs", 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlvs, tlvs_len); 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf_len = 2 * tlvs_len + 1; 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(buf_len); 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf) { 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len); 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_ctrl(wpa_s, MSG_INFO, P2P_EVENT_SERV_DISC_REQ "%d " 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " %u %u %s", 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, MAC2STR(sa), dialog_token, update_indic, 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf); 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->p2p_sd_over_ctrl_iface) { 20121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token, 20131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt update_indic, tlvs, tlvs_len); 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* to be processed by an external program */ 20151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_alloc(10000); 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Request TLV"); 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt slen = WPA_GET_LE16(pos); 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + slen > end || slen < 2) { 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unexpected Query Data " 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length"); 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv_end = pos + slen; 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_proto = *pos++; 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u", 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_proto); 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id = *pos++; 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u", 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Query Data", 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, tlv_end - pos); 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->force_long_sd) { 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: SD test - force long " 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "response"); 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id); 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_upnp(wpa_s, resp, srv_trans_id); 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto done; 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (srv_proto) { 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SERV_ALL_SERVICES: 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Discovery Request " 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for all services"); 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_upnp) && 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) { 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No service " 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "discovery protocols available"); 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_add_proto_not_avail( 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp, P2P_SERV_ALL_SERVICES, 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id); 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_upnp(wpa_s, resp, srv_trans_id); 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SERV_BONJOUR: 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_req_bonjour(wpa_s, resp, srv_trans_id, 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, tlv_end - pos); 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SERV_UPNP: 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_req_upnp(wpa_s, resp, srv_trans_id, 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, tlv_end - pos); 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 207661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 207761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_SERV_WIFI_DISPLAY: 207861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_sd_req_wfd(wpa_s, resp, srv_trans_id, 207961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos, tlv_end - pos); 208061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 208161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unavailable service " 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "protocol %u", srv_proto); 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_add_proto_not_avail(resp, srv_proto, 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = tlv_end; 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdone: 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token, 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt update_indic, tlvs, tlvs_len); 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_response(wpa_s, freq, sa, dialog_token, resp); 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_sd_response(void *ctx, const u8 *sa, u16 update_indic, 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *tlvs, size_t tlvs_len) 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = tlvs; 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end = tlvs + tlvs_len; 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *tlv_end; 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 slen; 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buf_len; 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf; 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Response TLVs", 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlvs, tlvs_len); 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlvs_len > 1500) { 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: better way for handling this */ 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_ctrl(wpa_s, MSG_INFO, 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_SERV_DISC_RESP MACSTR 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " %u <long response: %u bytes>", 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), update_indic, 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) tlvs_len); 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf_len = 2 * tlvs_len + 1; 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(buf_len); 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf) { 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len); 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_ctrl(wpa_s, MSG_INFO, 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_SERV_DISC_RESP MACSTR " %u %s", 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), update_indic, buf); 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_proto, srv_trans_id, status; 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Response TLV"); 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt slen = WPA_GET_LE16(pos); 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + slen > end || slen < 3) { 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unexpected Response Data " 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length"); 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv_end = pos + slen; 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_proto = *pos++; 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u", 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_proto); 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id = *pos++; 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u", 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = *pos++; 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Status Code ID %u", 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status); 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Response Data", 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, tlv_end - pos); 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = tlv_end; 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_sd_response(wpa_s, sa, update_indic, tlvs, tlvs_len); 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu64 wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst, 21691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const struct wpabuf *tlvs) 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 21721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return wpa_drv_p2p_sd_request(wpa_s, dst, tlvs); 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 21741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 21751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return (uintptr_t) p2p_sd_request(wpa_s->global->p2p, dst, tlvs); 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu64 wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst, 21801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 version, const char *query) 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tlvs; 21831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u64 ret; 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlvs = wpabuf_alloc(2 + 1 + 1 + 1 + os_strlen(query)); 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlvs == NULL) 21871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_le16(tlvs, 1 + 1 + 1 + os_strlen(query)); 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(tlvs, P2P_SERV_UPNP); /* Service Protocol Type */ 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(tlvs, 1); /* Service Transaction ID */ 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(tlvs, version); 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_str(tlvs, query); 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = wpas_p2p_sd_request(wpa_s, dst, tlvs); 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tlvs); 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 219961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 220061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 220161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic u64 wpas_p2p_sd_request_wfd(struct wpa_supplicant *wpa_s, const u8 *dst, 220261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpabuf *tlvs) 220361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 220461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 220561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 220661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 220761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 220861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return (uintptr_t) p2p_sd_request_wfd(wpa_s->global->p2p, dst, tlvs); 220961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 221061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 221161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 221261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#define MAX_WFD_SD_SUBELEMS 20 221361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 221461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void wfd_add_sd_req_role(struct wpabuf *tlvs, u8 id, u8 role, 221561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *subelems) 221661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 221761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len; 221861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *pos; 221961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int val; 222061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int count = 0; 222161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 222261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len = wpabuf_put(tlvs, 2); 222361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(tlvs, P2P_SERV_WIFI_DISPLAY); /* Service Protocol Type */ 222461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(tlvs, id); /* Service Transaction ID */ 222561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 222661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(tlvs, role); 222761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 222861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = subelems; 222961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (*pos) { 223061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = atoi(pos); 223161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (val >= 0 && val < 256) { 223261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(tlvs, val); 223361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt count++; 223461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (count == MAX_WFD_SD_SUBELEMS) 223561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 223661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 223761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = os_strchr(pos + 1, ','); 223861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL) 223961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 224061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 224161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 224261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 224361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WPA_PUT_LE16(len, (u8 *) wpabuf_put(tlvs, 0) - len - 2); 224461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 224561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 224661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 224761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtu64 wpas_p2p_sd_request_wifi_display(struct wpa_supplicant *wpa_s, 224861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *dst, const char *role) 224961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 225061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *tlvs; 225161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u64 ret; 225261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *subelems; 225361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 id = 1; 225461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 225561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt subelems = os_strchr(role, ' '); 225661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (subelems == NULL) 225761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 225861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt subelems++; 225961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 226061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tlvs = wpabuf_alloc(4 * (2 + 1 + 1 + 1 + MAX_WFD_SD_SUBELEMS)); 226161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (tlvs == NULL) 226261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 226361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 226461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(role, "[source]")) 226561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_add_sd_req_role(tlvs, id++, 0x00, subelems); 226661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(role, "[pri-sink]")) 226761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_add_sd_req_role(tlvs, id++, 0x01, subelems); 226861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(role, "[sec-sink]")) 226961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_add_sd_req_role(tlvs, id++, 0x02, subelems); 227061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(role, "[source+sink]")) 227161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_add_sd_req_role(tlvs, id++, 0x03, subelems); 227261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 227361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ret = wpas_p2p_sd_request_wfd(wpa_s, dst, tlvs); 227461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(tlvs); 227561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return ret; 227661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 227761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 227861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 227961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 228061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, u64 req) 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 22841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return wpa_drv_p2p_sd_cancel_request(wpa_s, req); 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_sd_cancel_request(wpa_s->global->p2p, 22881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (void *) (uintptr_t) req); 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_sd_response(struct wpa_supplicant *wpa_s, int freq, 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dst, u8 dialog_token, 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *resp_tlvs) 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_p2p_sd_response(wpa_s, freq, dst, dialog_token, 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_tlvs); 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_response(wpa_s->global->p2p, freq, dst, dialog_token, 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_tlvs); 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2307eaf261d3b8eef1dcb8d645e0cd2b9016bb66cdfdDmitry Shmidt 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_sd_service_update(struct wpa_supplicant *wpa_s) 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_p2p_service_update(wpa_s); 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_service_update(wpa_s->global->p2p); 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_srv_bonjour_free(struct p2p_srv_bonjour *bsrv) 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&bsrv->list); 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(bsrv->query); 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(bsrv->resp); 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(bsrv); 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_srv_upnp_free(struct p2p_srv_upnp *usrv) 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&usrv->list); 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(usrv->service); 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(usrv); 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_service_flush(struct wpa_supplicant *wpa_s) 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv, *bn; 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv, *un; 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(bsrv, bn, &wpa_s->global->p2p_srv_bonjour, 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour, list) 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_srv_bonjour_free(bsrv); 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(usrv, un, &wpa_s->global->p2p_srv_upnp, 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp, list) 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_srv_upnp_free(usrv); 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_service_add_bonjour(struct wpa_supplicant *wpa_s, 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *query, struct wpabuf *resp) 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bsrv = os_zalloc(sizeof(*bsrv)); 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bsrv == NULL) 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bsrv->query = query; 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bsrv->resp = resp; 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&wpa_s->global->p2p_srv_bonjour, &bsrv->list); 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_service_del_bonjour(struct wpa_supplicant *wpa_s, 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *query) 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bsrv = wpas_p2p_service_get_bonjour(wpa_s, query); 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bsrv == NULL) 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_srv_bonjour_free(bsrv); 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_service_add_upnp(struct wpa_supplicant *wpa_s, u8 version, 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *service) 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_service_get_upnp(wpa_s, version, service)) 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Already listed */ 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv = os_zalloc(sizeof(*usrv)); 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (usrv == NULL) 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv->version = version; 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv->service = os_strdup(service); 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (usrv->service == NULL) { 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(usrv); 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&wpa_s->global->p2p_srv_upnp, &usrv->list); 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version, 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *service) 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv = wpas_p2p_service_get_upnp(wpa_s, version, service); 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (usrv == NULL) 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_srv_upnp_free(usrv); 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_prov_disc_local_display(struct wpa_supplicant *wpa_s, 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer, const char *params, 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int generated_pin) 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2425b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_SHOW_PIN MACSTR 2426b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " %08d%s", MAC2STR(peer), generated_pin, params); 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_prov_disc_local_keypad(struct wpa_supplicant *wpa_s, 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer, const char *params) 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2433b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_ENTER_PIN MACSTR 2434b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "%s", MAC2STR(peer), params); 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods, 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dev_addr, const u8 *pri_dev_type, 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *dev_name, u16 supp_config_methods, 24411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 dev_capab, u8 group_capab, const u8 *group_id, 24421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t group_id_len) 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 24461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char params[300]; 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 empty_dev_type[8]; 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int generated_pin = 0; 24491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *group = NULL; 24501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 24511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (group_id) { 24521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (group = wpa_s->global->ifaces; group; group = group->next) 24531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt { 24541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *s = group->current_ssid; 24551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s != NULL && 24561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt s->mode == WPAS_MODE_P2P_GO && 24571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group_id_len - ETH_ALEN == s->ssid_len && 24581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(group_id + ETH_ALEN, s->ssid, 24591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt s->ssid_len) == 0) 24601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 24611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 24621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pri_dev_type == NULL) { 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(empty_dev_type, 0, sizeof(empty_dev_type)); 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pri_dev_type = empty_dev_type; 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(params, sizeof(params), " p2p_dev_addr=" MACSTR 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " pri_dev_type=%s name='%s' config_methods=0x%x " 24701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "dev_capab=0x%x group_capab=0x%x%s%s", 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev_addr), 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(pri_dev_type, devtype, 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype)), 24741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev_name, supp_config_methods, dev_capab, group_capab, 24751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group ? " group=" : "", 24761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group ? group->ifname : ""); 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params[sizeof(params) - 1] = '\0'; 2478c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config_methods & WPS_CONFIG_DISPLAY) { 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generated_pin = wps_generate_pin(); 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_prov_disc_local_display(wpa_s, peer, params, 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generated_pin); 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (config_methods & WPS_CONFIG_KEYPAD) 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_prov_disc_local_keypad(wpa_s, peer, params); 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (config_methods & WPS_CONFIG_PUSHBUTTON) 2486b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_REQ 2487b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR "%s", MAC2STR(peer), params); 248875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 248975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_provision_discovery(wpa_s, peer, 1 /* request */, 249075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_SUCCESS, 249175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen config_methods, generated_pin); 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods) 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int generated_pin = 0; 249904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char params[20]; 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2501c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (wpa_s->pending_pd_before_join && 2502c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 || 2503c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) { 2504c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 2505c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Starting pending " 2506c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "join-existing-group operation"); 2507c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpas_p2p_join_start(wpa_s); 2508c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return; 2509c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 2510c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 251104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->pending_pd_use == AUTO_PD_JOIN || 251204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use == AUTO_PD_GO_NEG) 251304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_snprintf(params, sizeof(params), " peer_go=%d", 251404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use == AUTO_PD_JOIN); 251504949598a23f501be6eec21697465fd46a28840aDmitry 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, 25351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt enum p2p_prov_disc_status status) 253675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 253775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct wpa_supplicant *wpa_s = ctx; 253875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 253904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_fallback_to_go_neg) { 254004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: PD for p2p_connect-auto " 254104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "failed - fall back to GO Negotiation"); 254204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_fallback_to_go_neg(wpa_s, 0); 254304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 254404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 254504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2546d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (status == P2P_PROV_DISC_TIMEOUT_JOIN) { 25472b380488c6b5d21e54e98397c7a8d6a9f16dd8b5Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 2548d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Starting pending " 2549d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "join-existing-group operation (no ACK for PD " 2550d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "Req attempts)"); 2551d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_join_start(wpa_s); 2552d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 25532b380488c6b5d21e54e98397c7a8d6a9f16dd8b5Dmitry Shmidt } 2554d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2555b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE 2556b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " p2p_dev_addr=" MACSTR " status=%d", 2557b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(peer), status); 255804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 255975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */, 256075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen status, 0, 0); 256175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 256275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 256375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 2564f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidtstatic int freq_included(const struct p2p_channels *channels, unsigned int freq) 2565f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt{ 2566f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (channels == NULL) 2567f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return 1; /* Assume no restrictions */ 2568f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return p2p_channels_includes_freq(channels, freq); 2569f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 2570f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt} 2571f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 2572f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid, 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_dev_addr, const u8 *ssid, 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ssid_len, int *go, u8 *group_bssid, 2576f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt int *force_freq, int persistent_group, 2577f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt const struct p2p_channels *channels) 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *grp; 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!persistent_group) { 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " to join an active group", MAC2STR(sa)); 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) && 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN) 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0 || 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0)) { 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept previously " 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authorized invitation"); 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto accept_inv; 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Do not accept the invitation automatically; notify user and 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request approval. 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt grp = wpas_get_p2p_group(wpa_s, ssid, ssid_len, go); 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (grp) { 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept invitation to already " 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "running persistent group"); 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*go) 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_bssid, grp->own_addr, ETH_ALEN); 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto accept_inv; 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26117a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) && 26127a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0) { 26137a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept previously initiated " 26147a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "invitation to re-invoke a persistent group"); 26157a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else if (!wpa_s->conf->persistent_reconnect) 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled == 2 && 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(s->bssid, go_dev_addr, ETH_ALEN) == 0 && 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len == ssid_len && 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) == 0) 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!s) { 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested reinvocation of an unknown group", 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_UNKNOWN_GROUP; 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO && !wpas_p2p_create_iface(wpa_s)) { 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *go = 1; 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state >= WPA_AUTHENTICATING) { 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The only available " 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface is already in use - reject " 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation"); 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_bssid, wpa_s->own_addr, ETH_ALEN); 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (s->mode == WPAS_MODE_P2P_GO) { 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *go = 1; 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO) < 0) 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new " 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface address for the group"); 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_bssid, wpa_s->pending_interface_addr, 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtaccept_inv: 2655700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, 0); 2656700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2657c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt /* Get one of the frequencies currently in use */ 2658c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (wpas_p2p_valid_oper_freqs(wpa_s, &res, 1) > 0) { 2659c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to force channel to match a channel already used by one of the interfaces"); 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *force_freq = res; 2661700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, res); 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2664c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (*force_freq > 0 && wpa_s->num_multichan_concurrent > 1 && 2665c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpas_p2p_num_unused_channels(wpa_s) > 0) { 2666f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (*go == 0) { 2667f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt /* We are the client */ 2668f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer was found to be " 2669f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt "running a GO but we are capable of MCC, " 2670f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt "figure out the best channel to use"); 2671f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt *force_freq = 0; 2672f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt } else if (!freq_included(channels, *force_freq)) { 2673f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt /* We are the GO, and *force_freq is not in the 2674f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt * intersection */ 2675f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not " 2676f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt "in intersection but we are capable of MCC, " 2677f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt "figure out the best channel to use", 2678f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt *force_freq); 2679f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt *force_freq = 0; 2680f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt } 2681f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt } 2682f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_SUCCESS; 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, size_t ssid_len, 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_dev_addr, u8 status, 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int op_freq) 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled == 2 && 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len == ssid_len && 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) == 0) 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status == P2P_SC_SUCCESS) { 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " was accepted; op_freq=%d MHz", 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), op_freq); 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s) { 270791c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt int go = s->mode == WPAS_MODE_P2P_GO; 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_add_persistent( 27097a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s, s, go, go ? op_freq : 0, 0, NULL); 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (bssid) { 2711d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->user_initiated_pd = 0; 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_join(wpa_s, bssid, go_dev_addr, 271304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_wps_method, 0); 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " was rejected (status %u)", MAC2STR(sa), status); 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!s) { 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid) { 2726b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 2727b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_INVITATION_RECEIVED 2728b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "sa=" MACSTR " go_dev_addr=" MACSTR 2729b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " bssid=" MACSTR " unknown-network", 2730b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(sa), MAC2STR(go_dev_addr), 2731b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(bssid)); 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2733b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 2734b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_INVITATION_RECEIVED 2735b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "sa=" MACSTR " go_dev_addr=" MACSTR 2736b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " unknown-network", 2737b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(sa), MAC2STR(go_dev_addr)); 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO && op_freq) { 2743b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED 2744b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "sa=" MACSTR " persistent=%d freq=%d", 2745b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(sa), s->id, op_freq); 27467a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else { 2747b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED 2748b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "sa=" MACSTR " persistent=%d", 2749b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(sa), s->id); 27507a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2754700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s, 2755700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt struct wpa_ssid *ssid, 2756391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *peer, int inv) 2757700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 2758700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt size_t i; 2759700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2760700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (ssid == NULL) 2761700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; 2762700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2763700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) { 2764700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (os_memcmp(ssid->p2p_client_list + i * ETH_ALEN, peer, 2765700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ETH_ALEN) == 0) 2766700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt break; 2767700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 2768700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (i >= ssid->num_p2p_clients) { 2769700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GO && 2770700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) { 2771700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d " 2772700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "due to invitation result", ssid->id); 2773700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_notify_network_removed(wpa_s, ssid); 2774700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, ssid->id); 2775700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; 2776700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 2777700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; /* Peer not found in client list */ 2778700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 2779700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2780700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent " 2781391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt "group %d client list%s", 2782391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(peer), ssid->id, 2783391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt inv ? " due to invitation result" : ""); 2784700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt os_memmove(ssid->p2p_client_list + i * ETH_ALEN, 2785700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid->p2p_client_list + (i + 1) * ETH_ALEN, 2786700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt (ssid->num_p2p_clients - i - 1) * ETH_ALEN); 2787700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid->num_p2p_clients--; 2788700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE 2789700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->parent->conf->update_config && 2790700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf)) 2791700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 2792700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */ 2793700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 2794700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2795700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2796700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s, 2797700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt const u8 *peer) 2798700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 2799700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt struct wpa_ssid *ssid; 2800700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2801700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s = wpa_s->global->p2p_invite_group; 2802700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s == NULL) 2803700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; /* No known invitation group */ 2804700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid = wpa_s->current_ssid; 2805700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 2806700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt !ssid->p2p_persistent_group) 2807700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; /* Not operating as a GO in persistent group */ 2808700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid = wpas_p2p_get_persistent(wpa_s->parent, peer, 2809700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid->ssid, ssid->ssid_len); 2810391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_remove_persistent_peer(wpa_s, ssid, peer, 1); 2811700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 2812700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2813700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 28147a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtstatic void wpas_invitation_result(void *ctx, int status, const u8 *bssid, 2815700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt const struct p2p_channels *channels, 2816700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt const u8 *peer) 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid) { 2822b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT 2823b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "status=%d " MACSTR, 2824b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt status, MAC2STR(bssid)); 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2826b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT 2827b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "status=%d ", status); 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_invitation_result(wpa_s, status, bssid); 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2831700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR, 2832700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt status, MAC2STR(peer)); 2833700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->pending_invite_ssid_id == -1) { 2834700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (status == P2P_SC_FAIL_UNKNOWN_GROUP) 2835700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_remove_persistent_client(wpa_s, peer); 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Invitation to active group */ 2837700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28397a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { 28407a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another " 28417a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "invitation exchange to indicate readiness for " 28427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "re-invocation"); 28437a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 28447a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != P2P_SC_SUCCESS) { 2846700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (status == P2P_SC_FAIL_UNKNOWN_GROUP) { 2847700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid = wpa_config_get_network( 2848700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->conf, wpa_s->pending_invite_ssid_id); 2849391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_remove_persistent_peer(wpa_s, ssid, peer, 1); 2850700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_invite_ssid_id); 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Could not find persistent group " 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data matching with invitation"); 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28632c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen /* 28642c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * The peer could have missed our ctrl::ack frame for Invitation 28652c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * Response and continue retransmitting the frame. To reduce the 28662c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * likelihood of the peer not getting successful TX status for the 28672c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * Invitation Response frame, wait a short time here before starting 28682c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * the persistent group so that we will remain on the current channel to 28692c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * acknowledge any possible retransmission from the peer. 28702c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen */ 287181931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff#ifndef ANDROID_P2P 28722c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 50 ms wait on current channel before " 28732c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen "starting persistent group"); 28742c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen os_sleep(0, 50000); 287581931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff#else 287681931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 100 ms wait on current channel before " 287781931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff "starting persistent group"); 287881931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff os_sleep(0, 100000); 287981931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff#endif 28802c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_add_persistent(wpa_s, ssid, 288231be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen ssid->mode == WPAS_MODE_P2P_GO, 288331be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_persistent_go_freq, 28847a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->p2p_go_ht40, channels); 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_p2p_disallowed_freq(struct wpa_global *global, 288904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int freq) 289004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 289104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int i; 289204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 289304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (global->p2p_disallow_freq == NULL) 289404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 289504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 289604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < global->num_p2p_disallow_freq; i++) { 289704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (freq >= global->p2p_disallow_freq[i].min && 289804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq <= global->p2p_disallow_freq[i].max) 289904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 290004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 290104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 290204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 290304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 290404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 290504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 290604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_add_chan(struct p2p_reg_class *reg, u8 chan) 290704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 290804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt reg->channel[reg->channels] = chan; 290904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt reg->channels++; 291004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 291104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 291204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s, 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *chan) 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, cla = 0; 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz " 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Operating class 81 - 2.4 GHz band channels 1..13 */ 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_class[cla].reg_class = 81; 292304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan->reg_class[cla].channels = 0; 292404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < 11; i++) { 292504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 2412 + i * 5)) 292604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], i + 1); 292704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 292804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan->reg_class[cla].channels) 292904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cla++; 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz " 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Operating class 115 - 5 GHz, channels 36-48 */ 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_class[cla].reg_class = 115; 293604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan->reg_class[cla].channels = 0; 293704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 36 * 5)) 293804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 36); 293904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 40 * 5)) 294004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 40); 294104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 44 * 5)) 294204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 44); 294304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 48 * 5)) 294404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 48); 294504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan->reg_class[cla].channels) 294604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cla++; 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz " 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Operating class 124 - 5 GHz, channels 149,153,157,161 */ 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_class[cla].reg_class = 124; 295304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan->reg_class[cla].channels = 0; 295404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 149 * 5)) 295504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 149); 295604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 153 * 5)) 295704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 153); 295804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 156 * 5)) 295904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 157); 296004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 161 * 5)) 296104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 161); 296204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan->reg_class[cla].channels) 296304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cla++; 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_classes = cla; 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 num_modes, 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum hostapd_hw_mode mode) 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 i; 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_modes; i++) { 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (modes[i].mode == mode) 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &modes[i]; 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int has_channel(struct wpa_global *global, 298604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_hw_modes *mode, u8 chan, int *flags) 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 298904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int freq; 299004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 299104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq = (mode->mode == HOSTAPD_MODE_IEEE80211A ? 5000 : 2407) + 299204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan * 5; 299304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_p2p_disallowed_freq(global, freq)) 299404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < mode->num_channels; i++) { 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mode->channels[i].chan == chan) { 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags) 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *flags = mode->channels[i].flag; 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return !(mode->channels[i].flag & 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (HOSTAPD_CHAN_DISABLED | 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_CHAN_PASSIVE_SCAN | 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_CHAN_NO_IBSS | 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_CHAN_RADAR)); 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_oper_class_map { 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum hostapd_hw_mode mode; 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_class; 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 min_chan; 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 max_chan; 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 inc; 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { BW20, BW40PLUS, BW40MINUS } bw; 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 302161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct p2p_oper_class_map op_class[] = { 302261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 }, 302361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#if 0 /* Do not enable HT40 on 2 GHz for now */ 302461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS }, 302561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS }, 302661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif 302761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20 }, 302861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20 }, 302961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS }, 303061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS }, 303161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS }, 303261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS }, 303361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { -1, 0, 0, 0, 0, BW20 } 303461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}; 303561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 303661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 303761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s, 303861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_hw_modes *mode, 303961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 channel, u8 bw) 304061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 304161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int flag; 304261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 304361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!has_channel(wpa_s->global, mode, channel, &flag)) 304461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 304561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (bw == BW40MINUS && 304661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (!(flag & HOSTAPD_CHAN_HT40MINUS) || 304761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !has_channel(wpa_s->global, mode, channel - 4, NULL))) 304861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 304961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (bw == BW40PLUS && 305061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (!(flag & HOSTAPD_CHAN_HT40PLUS) || 305161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !has_channel(wpa_s->global, mode, channel + 4, NULL))) 305261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 305361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 305461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 305561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 305661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s, 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *chan) 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct hostapd_hw_modes *mode; 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int cla, op; 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->hw.modes == NULL) { 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching " 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "of all supported channels; assume dualband " 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "support"); 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpas_p2p_default_channels(wpa_s, chan); 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla = 0; 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (op = 0; op_class[op].op_class; op++) { 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_oper_class_map *o = &op_class[op]; 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ch; 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *reg = NULL; 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode); 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mode == NULL) 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { 308161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw) < 1) 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg == NULL) { 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Add operating " 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "class %u", o->op_class); 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg = &chan->reg_class[cla]; 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla++; 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg->reg_class = o->op_class; 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg->channel[reg->channels] = ch; 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg->channels++; 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg) { 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Channels", 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg->channel, reg->channels); 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_classes = cla; 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 310561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s, 310661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_hw_modes *mode, u8 channel) 310761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 310861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int op, ret; 310961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 311061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (op = 0; op_class[op].op_class; op++) { 311161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_oper_class_map *o = &op_class[op]; 311261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 ch; 311361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 311461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { 311561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (o->mode != HOSTAPD_MODE_IEEE80211A || 311661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt o->bw == BW20 || ch != channel) 311761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 311861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ret = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw); 311961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ret < 0) 312061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 312161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else if (ret > 0) 312261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return (o->bw == BW40MINUS) ? -1 : 1; 312361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 312461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 312561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 312661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 312761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 312861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 312961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 313061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf, 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buf_len) 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(wpa_s->own_addr, interface_addr, ETH_ALEN) == 0) 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_get_noa(wpa_s, buf, buf_len); 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3147c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpas_go_connected(void *ctx, const u8 *dev_addr) 3148c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 3149c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3150c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 3151c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 3152c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 3153c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid == NULL) 3154c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 3155c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid->mode != WPAS_MODE_INFRA) 3156c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 3157c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (wpa_s->wpa_state != WPA_COMPLETED && 3158c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->wpa_state != WPA_GROUP_HANDSHAKE) 3159c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 3160c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (os_memcmp(wpa_s->go_dev_addr, dev_addr, ETH_ALEN) == 0) 3161c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 1; 3162c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 3163c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 3164c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 0; 3165c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 3166c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 3167c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 3168b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void wpas_p2p_debug_print(void *ctx, int level, const char *msg) 3169b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 3170b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 3171b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, level, "P2P: %s", msg); 3172b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 3173b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 3174b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 317534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtint wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s) 317634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 317734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt struct wpa_interface iface; 317834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt struct wpa_supplicant *p2pdev_wpa_s; 317934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char ifname[100]; 318034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char force_name[100]; 318134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt int ret; 318234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 318334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s", 318434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->ifname); 318534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt force_name[0] = '\0'; 318634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE; 318734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL, 318834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt force_name, wpa_s->pending_interface_addr, NULL); 318934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (ret < 0) { 319034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface"); 319134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return ret; 319234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 319334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_strlcpy(wpa_s->pending_interface_name, ifname, 319434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt sizeof(wpa_s->pending_interface_name)); 319534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 319634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_memset(&iface, 0, sizeof(iface)); 319734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.p2p_mgmt = 1; 319834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.ifname = wpa_s->pending_interface_name; 319934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.driver = wpa_s->driver->name; 320034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.driver_param = wpa_s->conf->driver_param; 320134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt iface.confname = wpa_s->confname; 320234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface); 320334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!p2pdev_wpa_s) { 320434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface"); 320534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return -1; 320634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 320734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt p2pdev_wpa_s->parent = wpa_s; 320834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 320934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 321034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 321134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 321234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 321334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_init - Initialize P2P module for %wpa_supplicant 32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init() 32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) 32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_config p2p; 32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r; 32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3226391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->conf->p2p_disabled) 3227391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 3228391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)) 32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p) 32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_params params; 32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use driver-based P2P management"); 32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.dev_name = wpa_s->conf->device_name; 32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(params.pri_dev_type, wpa_s->conf->device_type, 32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_sec_dev_types = wpa_s->conf->num_sec_device_types; 32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(params.sec_dev_type, 32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->sec_device_type, 32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_sec_dev_types * WPS_DEV_TYPE_LEN); 32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_p2p_set_params(wpa_s, ¶ms) < 0) 32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&p2p, 0, sizeof(p2p)); 32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.cb_ctx = wpa_s; 3256b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p.debug_print = wpas_p2p_debug_print; 32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.p2p_scan = wpas_p2p_scan; 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.send_action = wpas_send_action; 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.send_action_done = wpas_send_action_done; 32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.go_neg_completed = wpas_go_neg_completed; 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.go_neg_req_rx = wpas_go_neg_req_rx; 32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.dev_found = wpas_dev_found; 32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.dev_lost = wpas_dev_lost; 3264b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p.find_stopped = wpas_find_stopped; 32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.start_listen = wpas_start_listen; 32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.stop_listen = wpas_stop_listen; 32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.send_probe_resp = wpas_send_probe_resp; 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.sd_request = wpas_sd_request; 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.sd_response = wpas_sd_response; 32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.prov_disc_req = wpas_prov_disc_req; 32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.prov_disc_resp = wpas_prov_disc_resp; 327275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p.prov_disc_fail = wpas_prov_disc_fail; 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.invitation_process = wpas_invitation_process; 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.invitation_received = wpas_invitation_received; 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.invitation_result = wpas_invitation_result; 32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.get_noa = wpas_get_noa; 3277c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p.go_connected = wpas_go_connected; 32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN); 32801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN); 32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.dev_name = wpa_s->conf->device_name; 32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.manufacturer = wpa_s->conf->manufacturer; 32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.model_name = wpa_s->conf->model_name; 32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.model_number = wpa_s->conf->model_number; 32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.serial_number = wpa_s->conf->serial_number; 32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wps) { 32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16); 32888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.config_methods = wpa_s->wps->config_methods; 32898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->p2p_listen_reg_class && 32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_listen_channel) { 32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.reg_class = wpa_s->conf->p2p_listen_reg_class; 32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.channel = wpa_s->conf->p2p_listen_channel; 32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.reg_class = 81; 32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Pick one of the social channels randomly as the listen 32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.channel = 1 + (r % 3) * 5; 33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d", p2p.channel); 33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->p2p_oper_reg_class && 33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_oper_channel) { 33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_reg_class = wpa_s->conf->p2p_oper_reg_class; 33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_channel = wpa_s->conf->p2p_oper_channel; 33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.cfg_op_channel = 1; 33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Configured operating channel: " 33128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d:%d", p2p.op_reg_class, p2p.op_channel); 33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_reg_class = 81; 33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use random operation channel from (1, 6, 11) if no other 33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * preference is indicated. 33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_channel = 1 + (r % 3) * 5; 33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.cfg_op_channel = 0; 33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Random operating channel: " 33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d:%d", p2p.op_reg_class, p2p.op_channel); 33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 332644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 332744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt if (wpa_s->conf->p2p_pref_chan && wpa_s->conf->num_p2p_pref_chan) { 332844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p.pref_chan = wpa_s->conf->p2p_pref_chan; 332944c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p.num_pref_chan = wpa_s->conf->num_p2p_pref_chan; 333044c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } 333144c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 33328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) { 33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.country, wpa_s->conf->country, 2); 33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.country[2] = 0x04; 33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.country, "XX\x04", 3); 33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_setup_channels(wpa_s, &p2p.channels)) { 33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to configure supported " 33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel list"); 33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type, 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types; 33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type, 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN); 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.concurrent_operations = !!(wpa_s->drv_flags & 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_FLAGS_P2P_CONCURRENT); 33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.max_peers = 100; 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->p2p_ssid_postfix) { 33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.ssid_postfix_len = 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(wpa_s->conf->p2p_ssid_postfix); 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p.ssid_postfix_len > sizeof(p2p.ssid_postfix)) 33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.ssid_postfix_len = sizeof(p2p.ssid_postfix); 33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.ssid_postfix, wpa_s->conf->p2p_ssid_postfix, 33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.ssid_postfix_len); 33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss; 33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3367d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p.max_listen = wpa_s->max_remain_on_chan; 3368d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->p2p = p2p_init(&p2p); 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p == NULL) 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 337204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt global->p2p_init_wpa_s = wpa_s; 33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) { 33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->wps_vendor_ext[i] == NULL) 33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_wps_vendor_extension( 33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->p2p, wpa_s->conf->wps_vendor_ext[i]); 33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_deinit - Deinitialize per-interface P2P data 33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 33888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 33898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitialize per-interface P2P data. 33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 33918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_deinit(struct wpa_supplicant *wpa_s) 33928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->driver && wpa_s->drv_priv) 33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_probe_req_report(wpa_s, 0); 33951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 33961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->go_params) { 33971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Clear any stored provisioning info */ 33981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_clear_provisioning_info( 33991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->global->p2p, 340004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->go_params->peer_device_addr); 34011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 34021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->go_params); 34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->go_params = NULL; 34051cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt#ifdef ANDROID_P2P 34061cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL); 34071cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt#endif 34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); 34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL); 34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: remove group interface from the driver if this wpa_s instance 34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is on top of a P2P group interface */ 34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_deinit_global - Deinitialize global P2P module 34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init() 34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitializes the global (per device) P2P module. 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_deinit_global(struct wpa_global *global) 34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s, *tmp; 34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 343061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s = global->ifaces; 343161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s) 343261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_service_flush(wpa_s); 343361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p == NULL) 34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Remove remaining P2P group interfaces */ 34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_s && wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) 34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpa_s->next; 34408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_s) { 34418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = global->ifaces; 34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (tmp && 34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (tmp == wpa_s || 34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)) { 34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = tmp->next; 34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 34488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 344904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Disconnect from the P2P group and deinit the interface */ 345004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_disconnect(tmp); 34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Deinit GO data on any possibly remaining interface (if main 34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface is used as GO). 34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface) 34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_deinit(wpa_s); 34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_deinit(global->p2p); 34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->p2p = NULL; 346404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt global->p2p_init_wpa_s = NULL; 34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s) 34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 347034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) && 347134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_s->conf->p2p_no_group_iface) 3472d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* separate interface disabled per configuration */ 34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & 34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE | 34758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P)) 34768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* P2P group requires a new interface in every case 34778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CONCURRENT)) 34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* driver does not support concurrent operations */ 34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->ifaces->next) 34818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* more that one interface already in use */ 34828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state >= WPA_AUTHENTICATING) 34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* this interface is already in use */ 34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s, 34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer_addr, 34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 349204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 3493d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ssid *ssid, unsigned int pref_freq) 34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (persistent_group && wpa_s->conf->persistent_reconnect) 34961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt persistent_group = 2; 34971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_connect(wpa_s, peer_addr, wps_method, 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent, own_interface_addr, 35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq, persistent_group); 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 350461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 350561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Increase GO config timeout if HT40 is used since it takes some time 350661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * to scan channels for coex purposes before the BSS can be started. 350761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 350861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_config_timeout(wpa_s->global->p2p, 350961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40 ? 255 : 100, 20); 351061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect(wpa_s->global->p2p, peer_addr, wps_method, 35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent, own_interface_addr, force_freq, 351304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt persistent_group, ssid ? ssid->ssid : NULL, 351404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid ? ssid->ssid_len : 0, 3515d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->p2p_pd_before_go_neg, pref_freq); 35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s, 35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer_addr, 35218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 35228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 352304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 3524d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ssid *ssid, unsigned int pref_freq) 35258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (persistent_group && wpa_s->conf->persistent_reconnect) 35271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt persistent_group = 2; 35281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 35308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_authorize(wpa_s->global->p2p, peer_addr, wps_method, 35338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent, own_interface_addr, force_freq, 353404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt persistent_group, ssid ? ssid->ssid : NULL, 3535d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid ? ssid->ssid_len : 0, pref_freq); 35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s) 35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_join_scan_count++; 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d", 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_join_scan_count); 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_join_scan_count > P2P_MAX_JOIN_SCAN_ATTEMPTS) { 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to find GO " MACSTR 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for join operationg - stop join attempt", 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_join_iface_addr)); 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 354904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_auto_pd) { 355004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 3551b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 3552b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_PROV_DISC_FAILURE 3553b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " p2p_dev_addr=" MACSTR " status=N/A", 3554b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 355504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 355604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 3557b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 3558b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_FAILURE); 35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 356304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq) 356404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 3565c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int *freqs, res, num, i; 356604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3567c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (wpas_p2p_num_unused_channels(wpa_s) > 0) { 3568c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt /* Multiple channels are supported and not all are in use */ 356904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 3570c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 357104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3572c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int)); 3573c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 3574c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return 1; 357504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3576c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num = wpas_p2p_valid_oper_freqs(wpa_s, freqs, 3577c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_s->num_multichan_concurrent); 3578c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (num < 0) { 3579c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = 1; 3580c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt goto exit_free; 358104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 358204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3583c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0; i < num; i++) { 3584c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (freqs[i] == freq) { 3585c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Frequency %d MHz in use by another virtual interface and can be used", 3586c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freq); 3587c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = 0; 3588c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt goto exit_free; 3589c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 359004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 359104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3592c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = 1; 3593c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 3594c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtexit_free: 3595c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 3596c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return res; 359704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 359804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 359904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 360004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s, 360104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *peer_dev_addr) 360204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 360304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 360404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int updated; 360504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 360604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bss = wpa_bss_get_p2p_dev_addr(wpa_s, peer_dev_addr); 360704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss == NULL) 360804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 360904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss->last_update_idx < wpa_s->bss_update_idx) { 361004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer BSS entry not updated in the " 361104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "last scan"); 361204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 361304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 361404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 361504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt updated = os_time_before(&wpa_s->p2p_auto_started, &bss->last_update); 361604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Current BSS entry for peer updated at " 361704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "%ld.%06ld (%supdated in last scan)", 361804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bss->last_update.sec, bss->last_update.usec, 361904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt updated ? "": "not "); 362004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 362104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return updated; 362204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 362304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 362404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, 36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res) 36278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_bss *bss; 36298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 36308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 iface_addr[ETH_ALEN]; 363104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 36328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 36338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 36358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 36368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 363704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS) for %sjoin", 363804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt scan_res ? (int) scan_res->num : -1, 363904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_join ? "auto_" : ""); 36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scan_res) 36428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_scan_res_handler(wpa_s, scan_res); 36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 364404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_auto_pd) { 364504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int join = wpas_p2p_peer_go(wpa_s, 364604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_join_dev_addr); 364704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join == 0 && 364804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry < P2P_AUTO_PD_SCAN_ATTEMPTS) { 364904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry++; 3650444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt bss = wpa_bss_get_bssid_latest( 3651444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt wpa_s, wpa_s->pending_join_dev_addr); 365204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss) { 365304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq = bss->freq; 365404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Scan retry %d for " 365504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "the peer " MACSTR " at %d MHz", 365604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry, 365704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(wpa_s-> 365804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pending_join_dev_addr), 365904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq); 366004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_join_scan_req(wpa_s, freq); 366104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 366204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 366304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 366404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 366504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join < 0) 366604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt join = 0; 366704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 366804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 366904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use = join ? AUTO_PD_JOIN : AUTO_PD_GO_NEG; 367004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Auto PD with " MACSTR " join=%d", 367104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr), join); 367204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_prov_disc_req(wpa_s->global->p2p, 367304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_join_dev_addr, 367404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_config_methods, join, 3675d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 0, wpa_s->user_initiated_pd) < 0) { 367604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 3677b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_INFO, 3678b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_PROV_DISC_FAILURE 3679b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " p2p_dev_addr=" MACSTR " status=N/A", 3680b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 368104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 368204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 368304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 368404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 368504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_auto_join) { 368604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int join = wpas_p2p_peer_go(wpa_s, 368704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_join_dev_addr); 368804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join < 0) { 368904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be " 369004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "running a GO -> use GO Negotiation"); 369104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, 369204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_pin, wpa_s->p2p_wps_method, 369304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_group, 0, 0, 0, 369404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_go_intent, 369504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_connect_freq, 369604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id, 369761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_pd_before_go_neg, 369861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40); 369904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 370004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 370104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 370204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer was found running GO%s -> " 370304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "try to join the group", join ? "" : 370404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " in older scan"); 370504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!join) 370604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 1; 370704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 370804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 37098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_get_oper_freq(wpa_s->global->p2p, 37108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_iface_addr); 37118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0 && 37128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_get_interface_addr(wpa_s->global->p2p, 37138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_dev_addr, 37148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface_addr) == 0 && 37158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(iface_addr, wpa_s->pending_join_dev_addr, ETH_ALEN) != 0) 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 37178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Overwrite pending interface " 37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "address for join from " MACSTR " to " MACSTR 37198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " based on newly discovered P2P peer entry", 37208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_join_iface_addr), 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(iface_addr)); 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, 37238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_get_oper_freq(wpa_s->global->p2p, 37268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_iface_addr); 37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 0) { 37298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " 37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from P2P peer table: %d MHz", freq); 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3732444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->pending_join_iface_addr); 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss) { 37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = bss->freq; 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from BSS table: %d MHz", freq); 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0) { 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 method; 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 374104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_check_freq_conflict(wpa_s, freq) > 0) { 3742b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 3743b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_FAILURE 3744b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "reason=FREQ_CONFLICT"); 374504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 374604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 374704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Send Provision Discovery Request " 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "prior to joining an existing group (GO " MACSTR 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " freq=%u MHz)", 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr), freq); 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_pd_before_join = 1; 37538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (wpa_s->pending_join_wps_method) { 37558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 37568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = WPS_CONFIG_KEYPAD; 37578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = WPS_CONFIG_DISPLAY; 37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 37628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = WPS_CONFIG_PUSHBUTTON; 37638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 37658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = 0; 37668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 37678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((p2p_get_provisioning_info(wpa_s->global->p2p, 37701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->pending_join_dev_addr) == 37711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt method)) { 37721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 37731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * We have already performed provision discovery for 37741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * joining the group. Proceed directly to join 37751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * operation without duplicated provision discovery. */ 37761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Provision discovery " 37771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "with " MACSTR " already done - proceed to " 37781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "join", 37791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 37801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->pending_pd_before_join = 0; 37811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto start; 37821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 37831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 37848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_prov_disc_req(wpa_s->global->p2p, 37851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->pending_join_dev_addr, method, 1, 3786d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt freq, wpa_s->user_initiated_pd) < 0) { 37878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to send Provision " 37888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Discovery Request before joining an " 37898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "existing group"); 37908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 37918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto start; 37928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 37948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to find BSS/GO - try again later"); 37978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 37988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL); 37998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_check_join_scan_limit(wpa_s); 38008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstart: 38038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start join operation immediately */ 38048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_join_start(wpa_s); 38058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 380804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq) 38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 38118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params params; 38128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_ie, *ies; 38131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t ielen; 381404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int freqs[2] = { 0, 0 }; 3815ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt#ifdef ANDROID_P2P 3816ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt int oper_freq; 38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3818ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt /* If freq is not provided, check the operating freq of the GO and do a 3819ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt * a directed scan to save time 3820ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt */ 3821ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt if(!freq) { 3822ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt freq = (oper_freq = p2p_get_oper_freq(wpa_s->global->p2p, 3823ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt wpa_s->pending_join_iface_addr) == -1) ? 0 : oper_freq; 3824ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt } 3825ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt#endif 38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 38278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P Wildcard SSID */ 38298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_ssids = 1; 38308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID; 38318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN; 38328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->wps->dev.p2p = 1; 383404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev, 383504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0, 383604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt NULL); 38378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_ie == NULL) { 38388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_scan_res_join(wpa_s, NULL); 38398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 38431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen); 38448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) { 38458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 38468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_scan_res_join(wpa_s, NULL); 38478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 38488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(ies, wps_ie); 38508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3852c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_scan_ie(wpa_s->global->p2p, ies, NULL); 38538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p_probe = 1; 38558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies = wpabuf_head(ies); 38568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies_len = wpabuf_len(ies); 385704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (freq > 0) { 385804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freqs[0] = freq; 385904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.freqs = freqs; 386004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 38618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 38638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Run a scan to update BSS table and start Provision Discovery once 38648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the new scan results become available. 38658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 38661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_scan(wpa_s, ¶ms); 3867444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (!ret) { 3868444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt os_get_time(&wpa_s->scan_trigger_time); 386904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_join; 3870444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } 38718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 38738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 38758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to start scan for join - " 38768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "try again later"); 38778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 38788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL); 38798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_check_join_scan_limit(wpa_s); 38808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx) 388504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 388604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 388704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_join_scan_req(wpa_s, 0); 388804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 388904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 389004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr, 389204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *dev_addr, enum p2p_wps_method wps_method, 389304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int auto_join) 38948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface " 389604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MACSTR " dev " MACSTR ")%s", 389704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(iface_addr), MAC2STR(dev_addr), 389804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt auto_join ? " (auto_join)" : ""); 38998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 390004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 390104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_join = !!auto_join; 39028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN); 39038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN); 39048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_wps_method = wps_method; 39058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we are not running find during connection establishment */ 39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_stop_find(wpa_s); 39088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_join_scan_count = 0; 39108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_join_scan(wpa_s, NULL); 39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join_start(struct wpa_supplicant *wpa_s) 39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group; 39188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 391904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 39208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = wpas_p2p_get_group_iface(wpa_s, 0, 0); 39228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) 39238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group != wpa_s) { 39258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group->p2p_pin, wpa_s->p2p_pin, 39268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(group->p2p_pin)); 39278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->p2p_wps_method = wpa_s->p2p_wps_method; 39284b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt } else { 39294b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt /* 39304b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * Need to mark the current interface for p2p_group_formation 39314b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * when a separate group interface is not used. This is needed 39324b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * to allow p2p_cancel stop a pending p2p_connect-join. 39334b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * wpas_p2p_init_group_interface() addresses this for the case 39344b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * where a separate group interface is used. 39354b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt */ 39364b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt wpa_s->global->p2p_group_formation = wpa_s; 39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->p2p_in_provisioning = 1; 394004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt group->p2p_fallback_to_go_neg = wpa_s->p2p_fallback_to_go_neg; 39418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 39438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr, 39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = wpa_s->pending_join_wps_method; 3946444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->pending_join_iface_addr); 394704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss) { 394804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res.freq = bss->freq; 394904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res.ssid_len = bss->ssid_len; 395004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(res.ssid, bss->ssid, bss->ssid_len); 395104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 395204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3953c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { 3954c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel prior to " 3955c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "starting client"); 3956c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_drv_cancel_remain_on_channel(wpa_s); 3957c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->off_channel_freq = 0; 3958c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->roc_waiting_drv_freq = 0; 3959c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 39608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_enrollee(group, &res); 39618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Allow a longer timeout for join-a-running-group than normal 15 39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * second group formation timeout since the GO may not have authorized 39658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * our connection yet. 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(60, 0, wpas_p2p_group_formation_timeout, 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s, NULL); 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39757a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtstatic int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq, 3976c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int *force_freq, int *pref_freq) 39777a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt{ 3978c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int *freqs, res; 3979c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned int freq_in_use = 0, num, i; 3980c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 3981c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int)); 3982c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 3983c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 3984c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 3985c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num = get_shared_radio_freqs(wpa_s, freqs, 3986c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_s->num_multichan_concurrent); 3987b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt wpa_printf(MSG_DEBUG, 3988b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt "P2P: Setup freqs: freq=%d num_MCC=%d shared_freqs=%u", 3989b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt freq, wpa_s->num_multichan_concurrent, num); 3990c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 39917a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (freq > 0) { 39927a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!p2p_supported_freq(wpa_s->global->p2p, freq)) { 39937a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The forced channel " 39947a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "(%u MHz) is not supported for P2P uses", 39957a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq); 3996c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = -3; 3997c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt goto exit_free; 39987a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 39997a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 4000c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0; i < num; i++) { 4001c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (freqs[i] == freq) 4002c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freq_in_use = 1; 4003c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4004c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 4005c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (num == wpa_s->num_multichan_concurrent && !freq_in_use) { 4006c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz as there are no available channels", 4007c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freq); 4008c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = -2; 4009c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt goto exit_free; 40107a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 40117a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the " 40127a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "requested channel (%u MHz)", freq); 40137a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt *force_freq = freq; 4014c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt goto exit_ok; 4015c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4016c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 4017c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0; i < num; i++) { 4018c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!p2p_supported_freq(wpa_s->global->p2p, freqs[i])) 4019c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt continue; 4020c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 402151a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt#ifndef ANDROID_P2P 4022c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Try to force us to use frequency (%u MHz) which is already in use", 4023c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt *force_freq); 4024c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt *force_freq = freqs[i]; 402551a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt#endif 4026c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 4027c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (*pref_freq == 0 && num < wpa_s->num_multichan_concurrent) { 4028c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Try to prefer a frequency we are already using"); 402951a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt *pref_freq = freqs[i]; 403051a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt#ifdef ANDROID_P2P 403151a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt } else { 403251a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Try to force us to use frequency (%u MHz) which is already in use", 403351a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt *force_freq); 403451a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt *force_freq = freqs[i]; 403551a47d533b6bf0efff06cc80195a588852a45058Dmitry Shmidt#endif 40367a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 4037c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt break; 40387a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 40397a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 4040c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (i == num) { 4041c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (num < wpa_s->num_multichan_concurrent) { 4042c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Current operating channels are not available for P2P. Try to use another channel"); 4043c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt *force_freq = 0; 4044c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } else { 4045c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: All channels are in use and none of them are P2P enabled. Cannot start P2P group"); 4046c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = -2; 4047c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt goto exit_free; 4048c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4049c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4050c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 4051c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtexit_ok: 4052c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = 0; 4053c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtexit_free: 4054c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 4055c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return res; 40567a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt} 40577a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 40587a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 40598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 40608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_connect - Request P2P Group Formation to be started 40618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 40628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @peer_addr: Address of the peer P2P Device 40638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pin: PIN to use during provisioning or %NULL to indicate PBC mode 40648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @persistent_group: Whether to create a persistent group 406504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @auto_join: Whether to select join vs. GO Negotiation automatically 40668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @join: Whether to join an existing group (as a client) instead of starting 40678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Group Owner negotiation; @peer_addr is BSSID in that case 40688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @auth: Whether to only authorize the connection instead of doing that and 40698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initiating Group Owner negotiation 40708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @go_intent: GO Intent or -1 to use default 40718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency for the group or 0 for auto-selection 407204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @persistent_id: Persistent group credentials to use for forcing GO 407304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * parameters or -1 to generate new values (SSID/passphrase) 407404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @pd: Whether to send Provision Discovery prior to GO Negotiation as an 407504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * interoperability workaround when initiating group formation 407661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @ht40: Start GO with 40 MHz channel width 40778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified 40788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure, -2 on failure due to channel not currently available, 40798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * -3 if forced channel is not supported 40808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 40818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 40828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pin, enum p2p_wps_method wps_method, 408304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int persistent_group, int auto_join, int join, int auth, 408461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int go_intent, int freq, int persistent_id, int pd, 408561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int ht40) 40868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4087c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int force_freq = 0, pref_freq = 0; 40887a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int ret = 0, res; 40898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_driver_if_type iftype; 40901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *if_addr; 409104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = NULL; 40928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 40948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 409604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (persistent_id >= 0) { 409704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, persistent_id); 409804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid == NULL || ssid->disabled != 2 || 409904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->mode != WPAS_MODE_P2P_GO) 410004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 410104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 410204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4103391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(wpa_s->global->add_psk); 4104391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 4105391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 41068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go_intent < 0) 41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent = wpa_s->conf->p2p_go_intent; 41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auth) 41108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 41118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_wps_method = wps_method; 411304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_group = !!persistent_group; 411404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id = persistent_id; 411504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_go_intent = go_intent; 411604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_connect_freq = freq; 411704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 0; 411804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_pd_before_go_neg = !!pd; 411961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40 = !!ht40; 41208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pin) 41228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin)); 41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wps_method == WPS_PIN_DISPLAY) { 41248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = wps_generate_pin(); 41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(wpa_s->p2p_pin, sizeof(wpa_s->p2p_pin), "%08d", 41268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret); 41278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Randomly generated PIN: %s", 41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_pin); 41298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 41308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_pin[0] = '\0'; 41318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 413204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join || auto_join) { 41338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN]; 41348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth) { 41358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to " 41368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connect a running group from " MACSTR, 41378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 41388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); 41398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 41408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, peer_addr, ETH_ALEN); 41428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr, 41438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface_addr) < 0) { 41448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, peer_addr, ETH_ALEN); 41458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_get_dev_addr(wpa_s->global->p2p, peer_addr, 41468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr); 41478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 414804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (auto_join) { 414904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_get_time(&wpa_s->p2p_auto_started); 415004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Auto join started at " 415104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "%ld.%06ld", 415204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.sec, 415304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.usec); 415404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 4155d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->user_initiated_pd = 1; 415604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method, 415704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt auto_join) < 0) 41588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 41608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4162c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq); 41637a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (res) 41647a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return res; 4165c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, force_freq); 41668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s); 41688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->create_p2p_iface) { 41701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Prepare to add a new interface for the group */ 41711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt iftype = WPA_IF_P2P_GROUP; 41721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (go_intent == 15) 41731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt iftype = WPA_IF_P2P_GO; 41741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) { 41751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new " 41761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "interface for the group"); 41778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 41798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if_addr = wpa_s->pending_interface_addr; 41811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else 41821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if_addr = wpa_s->own_addr; 41838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth) { 41858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method, 41861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt go_intent, if_addr, 4187d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt force_freq, persistent_group, ssid, 4188d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pref_freq) < 0) 41898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 41918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 41931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method, 41941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt go_intent, if_addr, force_freq, 4195d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt persistent_group, ssid, pref_freq) < 0) { 41961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->create_p2p_iface) 41971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 41988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 42018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 42058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_remain_on_channel_cb - Indication of remain-on-channel start 42068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 42078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency of the channel in MHz 42088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @duration: Duration of the stay on the channel in milliseconds 42098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is called when the driver indicates that it has started the 42118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requested remain-on-channel duration. 42128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 42138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 42148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int freq, unsigned int duration) 42158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 42178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 42188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->off_channel_freq == wpa_s->pending_listen_freq) { 42198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_cb(wpa_s->global->p2p, wpa_s->pending_listen_freq, 42208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_duration); 42218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_freq = 0; 42228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, 42278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int timeout) 42288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Limit maximum Listen state time based on driver limitation. */ 42308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout > wpa_s->max_remain_on_chan) 42318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = wpa_s->max_remain_on_chan; 42328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 42348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_listen(wpa_s, timeout); 42358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_listen(wpa_s->global->p2p, timeout); 42378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 42418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_cancel_remain_on_channel_cb - Remain-on-channel timeout 42428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 42438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency of the channel in MHz 42448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 42458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is called when the driver indicates that a remain-on-channel 42468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * operation has been completed, i.e., the duration on the requested channel 42478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has timed out. 42488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 42498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 42508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int freq) 42518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback " 42538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(p2p_long_listen=%d ms pending_action_tx=%p)", 4254a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->p2p_long_listen, offchannel_pending_action_tx(wpa_s)); 42558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 42568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 42578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen_end(wpa_s->global->p2p, freq) > 0) 42588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* P2P module started a new operation */ 4259a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (offchannel_pending_action_tx(wpa_s)) 42608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 42618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_long_listen > 0) 42628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen -= wpa_s->max_remain_on_chan; 42638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_long_listen > 0) { 42648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state"); 42658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_listen_start(wpa_s, wpa_s->p2p_long_listen); 4266391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 4267391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* 4268391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * When listen duration is over, stop listen & update p2p_state 4269391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * to IDLE. 4270391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt */ 4271391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_stop_listen(wpa_s->global->p2p); 42728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 42778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_group_remove - Remove a P2P group 42788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 42798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ifname: Network interface name of the group interface or "*" to remove all 42808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * groups 42818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 42828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 42838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to remove a P2P group. This can be used to disconnect 42848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from a group in which the local end is a P2P Client or to end a P2P Group in 42858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case the local end is the Group Owner. If a virtual network interface was 42868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * created for this group, that interface will be removed. Otherwise, only the 42878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured P2P group network will be removed from the interface. 42888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 42898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname) 42908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global = wpa_s->global; 42928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(ifname, "*") == 0) { 42948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *prev; 42958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = global->ifaces; 42968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_s) { 42978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = wpa_s; 42988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpa_s->next; 4299b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if (prev->p2p_group_interface != 4300b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt NOT_P2P_GROUP_INTERFACE || 4301b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt (prev->current_ssid && 4302b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt prev->current_ssid->p2p_group)) 4303b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt wpas_p2p_disconnect(prev); 43048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 43068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 43098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(wpa_s->ifname, ifname) == 0) 43108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 43118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpas_p2p_disconnect(wpa_s); 43148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43178bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq) 43188bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 43198bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt unsigned int r; 43208bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 43218bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (freq == 2) { 43228bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 2.4 GHz " 43238bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "band"); 43248bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (wpa_s->best_24_freq > 0 && 43258bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 43268bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_s->best_24_freq)) { 43278bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = wpa_s->best_24_freq; 43288bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use best 2.4 GHz band " 43298bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "channel: %d MHz", freq); 43308bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } else { 43318bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 43328bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = 2412 + (r % 3) * 25; 43338bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use random 2.4 GHz band " 43348bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "channel: %d MHz", freq); 43358bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 43368bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 43378bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 43388bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (freq == 5) { 43398bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 5 GHz " 43408bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "band"); 43418bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (wpa_s->best_5_freq > 0 && 43428bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 43438bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_s->best_5_freq)) { 43448bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = wpa_s->best_5_freq; 43458bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use best 5 GHz band " 43468bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "channel: %d MHz", freq); 43478bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } else { 43488bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 43498bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = 5180 + (r % 4) * 20; 43508bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (!p2p_supported_freq(wpa_s->global->p2p, freq)) { 43518bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not select " 43528bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "5 GHz channel for P2P group"); 43538bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return -1; 43548bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 43558bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use random 5 GHz band " 43568bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "channel: %d MHz", freq); 43578bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 43588bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 43598bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 43608bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (freq > 0 && !p2p_supported_freq(wpa_s->global->p2p, freq)) { 43618bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The forced channel for GO " 43628bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt "(%u MHz) is not supported for P2P uses", 43638bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq); 43648bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return -1; 43658bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 43668bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 43678bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return freq; 43688bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 43698bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 43708bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 43711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, 43721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_go_neg_results *params, 43737a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int freq, int ht40, 43747a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt const struct p2p_channels *channels) 43758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4376c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int res, *freqs; 437744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt unsigned int pref_freq; 4378c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned int num, i; 43798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(params, 0, sizeof(*params)); 43818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->role_go = 1; 438261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params->ht40 = ht40; 43838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq) { 43847a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!freq_included(channels, freq)) { 43857a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not " 43867a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "accepted", freq); 43877a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return -1; 43887a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 43898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced " 43908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frequency %d MHz", freq); 43918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = freq; 43928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_reg_class == 81 && 43938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_oper_channel >= 1 && 43947a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_channel <= 11 && 43957a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, 43967a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 2407 + 5 * wpa_s->conf->p2p_oper_channel)) { 43978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = 2407 + 5 * wpa_s->conf->p2p_oper_channel; 43988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured " 43998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frequency %d MHz", params->freq); 44007a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else if ((wpa_s->conf->p2p_oper_reg_class == 115 || 44017a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 116 || 44027a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 117 || 44037a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 124 || 44047a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 126 || 44057a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 127) && 44067a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, 44077a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 5000 + 5 * wpa_s->conf->p2p_oper_channel)) { 44088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel; 44098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured " 44108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frequency %d MHz", params->freq); 44118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_channel == 0 && 44128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_overall_freq > 0 && 44138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 44147a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->best_overall_freq) && 44157a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, wpa_s->best_overall_freq)) { 44168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = wpa_s->best_overall_freq; 44178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best overall " 44188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %d MHz", params->freq); 44198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_channel == 0 && 44208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_24_freq > 0 && 44218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 44227a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->best_24_freq) && 44237a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, wpa_s->best_24_freq)) { 44248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = wpa_s->best_24_freq; 44258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 2.4 GHz " 44268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %d MHz", params->freq); 44278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_channel == 0 && 44288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_5_freq > 0 && 44298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 44307a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->best_5_freq) && 44317a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, wpa_s->best_5_freq)) { 44328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = wpa_s->best_5_freq; 44338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz " 44348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %d MHz", params->freq); 443544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } else if ((pref_freq = p2p_get_pref_freq(wpa_s->global->p2p, 443644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt channels))) { 443744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt params->freq = pref_freq; 443844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz from preferred " 443944c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt "channels", params->freq); 44408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 444104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int chan; 444204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (chan = 0; chan < 11; chan++) { 444304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params->freq = 2412 + chan * 5; 444404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 44457a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt params->freq) && 44467a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, params->freq)) 444704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 444804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 444904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan == 11) { 445004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No 2.4 GHz channel " 445104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "allowed"); 445204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 445304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 44548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference " 44558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "known)", params->freq); 44568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int)); 4459c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freqs) 4460c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 4461c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 4462c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = wpas_p2p_valid_oper_freqs(wpa_s, freqs, 4463c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_s->num_multichan_concurrent); 4464c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (res < 0) { 4465c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 4466c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 4467c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4468c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num = res; 4469c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 4470c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!freq) { 4471c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0; i < num; i++) { 4472c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (freq_included(channels, freqs[i])) { 4473c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Force GO on a channel we are already using (%u MHz)", 4474c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt freqs[i]); 4475c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt params->freq = freqs[i]; 4476c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt break; 4477700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 44787a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 44798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4480c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (i == num) { 4481c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (num == wpa_s->num_multichan_concurrent) { 4482c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using"); 4483c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 4484c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 4485c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } else { 4486c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels"); 4487c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4488700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 4489c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } else { 4490c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0; i < num; i++) { 4491c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (freqs[i] == freq) 4492c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt break; 44937a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 44941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4495c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (i == num) { 4496c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (num == wpa_s->num_multichan_concurrent) { 4497c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on freq (%u MHz) as all the channels are in use", freq); 4498c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 4499c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return -1; 4500c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } else { 4501c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels"); 4502c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4503c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4504c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 4505c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(freqs); 45061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 45078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * 45118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, 45128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go) 45138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group_wpa_s; 45158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4516aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (!wpas_p2p_create_iface(wpa_s)) { 4517aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use same interface for group " 4518aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "operations"); 45198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_s; 4520aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 45218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO : 4523aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt WPA_IF_P2P_CLIENT) < 0) { 4524b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_ERROR, 4525b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "P2P: Failed to add group interface"); 45268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4527aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 45288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s = wpas_p2p_init_group_interface(wpa_s, go); 45298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s == NULL) { 4530b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s, MSG_ERROR, 4531b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "P2P: Failed to initialize group interface"); 45328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 45338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 45348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4536aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s", 4537aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt group_wpa_s->ifname); 45388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group_wpa_s; 45398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 45438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_group_add - Add a new P2P group with local end as Group Owner 45448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 45458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @persistent_group: Whether to create a persistent group 45468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency for the group or 0 to indicate no hardcoding 45478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 45488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 45498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function creates a new P2P group with the local end as the Group Owner, 45508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * i.e., without using Group Owner Negotiation. 45518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 45528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, 455361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int freq, int ht40) 45548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results params; 45568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 45588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 45598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4560391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(wpa_s->global->add_psk); 4561391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 4562391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 4563dca3979ccdf869f140f096b83df322a0efc84f22Dmitry Shmidt /* Make sure we are not running find during connection establishment */ 45641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND"); 4565d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_stop_find_oper(wpa_s); 4566dca3979ccdf869f140f096b83df322a0efc84f22Dmitry Shmidt 45678bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = wpas_p2p_select_go_freq(wpa_s, freq); 45688bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (freq < 0) 45698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 45708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45717a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, NULL)) 45721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 457304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (params.freq && 457404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt !p2p_supported_freq(wpa_s->global->p2p, params.freq)) { 457504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The selected channel for GO " 457604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "(%u MHz) is not supported for P2P uses", 457704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.freq); 457804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 457904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 45808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_params(wpa_s->global->p2p, ¶ms); 45818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.persistent_group = persistent_group; 45828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpas_p2p_get_group_iface(wpa_s, 0, 1); 45848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 45858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 45868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(wpa_s, ¶ms, 0); 45878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 45898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_start_p2p_client(struct wpa_supplicant *wpa_s, 45938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *params, int addr_allocated) 45948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 45968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0); 45988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 45998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4600391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->p2p_last_4way_hs_fail = NULL; 46018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_deinit(wpa_s); 46038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_config_add_network(wpa_s->conf); 46058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) 46068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 46078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_network_defaults(ssid); 46088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->temporary = 1; 46098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->proto = WPA_PROTO_RSN; 46108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->pairwise_cipher = WPA_CIPHER_CCMP; 46118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->group_cipher = WPA_CIPHER_CCMP; 46128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->key_mgmt = WPA_KEY_MGMT_PSK; 46138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid = os_malloc(params->ssid_len); 46148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->ssid == NULL) { 46158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, ssid->id); 46168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 46178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid->ssid, params->ssid, params->ssid_len); 46198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len = params->ssid_len; 46208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->p2p_group = 1; 46218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->export_keys = 1; 46228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->psk_set) { 46238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid->psk, params->psk, 32); 46248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->psk_set = 1; 46258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->passphrase) 46278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->passphrase = os_strdup(params->passphrase); 46288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_select_network(wpa_s, ssid); 46308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 1; 46328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 46348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, 46388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid, int addr_allocated, 46397a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int freq, int ht40, 46407a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt const struct p2p_channels *channels) 46418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results params; 46438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go = 0; 46448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->disabled != 2 || ssid->ssid == NULL) 46468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 46478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go) && 46498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go == (ssid->mode == WPAS_MODE_P2P_GO)) { 46508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Requested persistent group is " 46518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "already running"); 46528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 46538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4655391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(wpa_s->global->add_psk); 4656391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = NULL; 4657391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 46588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we are not running find during connection establishment */ 4659d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_stop_find_oper(wpa_s); 46608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 466104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 0; 466204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 46638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_INFRA) 46648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpas_start_p2p_client(wpa_s, ssid, addr_allocated); 46658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GO) 46678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 46688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46698bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt freq = wpas_p2p_select_go_freq(wpa_s, freq); 46708bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (freq < 0) 46718bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return -1; 46728bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 46737a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, channels)) 46741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 46758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.role_go = 1; 4677d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.psk_set = ssid->psk_set; 4678d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (params.psk_set) 4679d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(params.psk, ssid->psk, sizeof(params.psk)); 4680a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (ssid->passphrase) { 4681a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) { 4682a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Invalid passphrase in " 4683a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "persistent group"); 4684a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 4685a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 4686a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_strlcpy(params.passphrase, ssid->passphrase, 4687a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(params.passphrase)); 46888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(params.ssid, ssid->ssid, ssid->ssid_len); 46908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = ssid->ssid_len; 46918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.persistent_group = 1; 46928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 1); 46948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 46958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 46968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(wpa_s, ¶ms, 0); 46988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 47008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_ie_update(void *ctx, struct wpabuf *beacon_ies, 47048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *proberesp_ies) 47058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 47068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 47078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface) { 47088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = wpa_s->ap_iface->bss[0]; 47091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!(hapd->conf->p2p & P2P_GROUP_OWNER)) { 47101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(beacon_ies); 47111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(proberesp_ies); 47121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 47131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 47148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (beacon_ies) { 47158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_beacon_ie); 47168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_beacon_ie = beacon_ies; 47178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 47188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_probe_resp_ie); 47198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_probe_resp_ie = proberesp_ies; 47208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 47218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(beacon_ies); 47228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(proberesp_ies); 47238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 47248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_update_beacon(wpa_s); 47258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_idle_update(void *ctx, int idle) 47298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 47308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 47318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->ap_iface) 47328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 47338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO - group %sidle", idle ? "" : "not "); 473404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (idle) 47358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 47368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 47378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL); 47388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s, 474204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid) 47438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 47448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group; 47458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_config *cfg; 47468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 47488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 47498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 47508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 47518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg = os_zalloc(sizeof(*cfg)); 47538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg == NULL) 47548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 47558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 475604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid->p2p_persistent_group && wpa_s->conf->persistent_reconnect) 47571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cfg->persistent_group = 2; 475804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else if (ssid->p2p_persistent_group) 47591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cfg->persistent_group = 1; 47608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN); 47618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->max_stations && 47628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->max_stations < wpa_s->conf->max_num_sta) 47638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->max_clients = wpa_s->max_stations; 47648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 47658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->max_clients = wpa_s->conf->max_num_sta; 476604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(cfg->ssid, ssid->ssid, ssid->ssid_len); 476704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cfg->ssid_len = ssid->ssid_len; 47688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->cb_ctx = wpa_s; 47698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->ie_update = wpas_p2p_ie_update; 47708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->idle_update = wpas_p2p_idle_update; 47718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p_group_init(wpa_s->global->p2p, cfg); 47738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) 47748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(cfg); 477504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) 47768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_notif_formation_done(group); 47778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group = group; 47788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group; 47798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 47838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int registrar) 47848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 478504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 478604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 47878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->p2p_in_provisioning) { 47888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore WPS success event - P2P " 47898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "provisioning not in progress"); 47908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 47918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 47928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 479304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_INFRA) { 479404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 479504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(go_dev_addr, wpa_s->bssid, ETH_ALEN); 479604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid, 479704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->ssid_len); 479804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Clear any stored provisioning info */ 479904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_clear_provisioning_info(wpa_s->global->p2p, go_dev_addr); 480004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 48011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 48028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent, 48038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 480404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_INFRA) { 480504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 480604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Use a separate timeout for initial data connection to 480704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * complete to allow the group to be removed automatically if 480804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * something goes wrong in this step before the P2P group idle 480904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * timeout mechanism is taken into use. 481004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 481104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0, 481204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_group_formation_timeout, 481304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->parent, NULL); 481404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 48158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 48168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_success_cb(wpa_s->global->p2p, peer_addr); 48178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 48188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_wps_success_cb(wpa_s, peer_addr); 48198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_group_formation_completed(wpa_s, 1); 48208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 482375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s, 482475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct wps_event_fail *fail) 482575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 482675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!wpa_s->p2p_in_provisioning) { 482775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_DEBUG, "P2P: Ignore WPS fail event - P2P " 482875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "provisioning not in progress"); 482975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 483075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 48311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 48321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->go_params) { 48331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_clear_provisioning_info( 48341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->global->p2p, 483504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->go_params->peer_device_addr); 48361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 48371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 483875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_wps_failed(wpa_s, fail); 483975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 484075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 484175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 48428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 484304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *config_method, 484404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum wpas_p2p_prov_disc_use use) 48458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 config_methods; 48478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 484804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 0; 484904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use = NORMAL_PD; 48501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_strncmp(config_method, "display", 7) == 0) 48518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config_methods = WPS_CONFIG_DISPLAY; 48521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strncmp(config_method, "keypad", 6) == 0) 48538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config_methods = WPS_CONFIG_KEYPAD; 48541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strncmp(config_method, "pbc", 3) == 0 || 48551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_strncmp(config_method, "pushbutton", 10) == 0) 48568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config_methods = WPS_CONFIG_PUSHBUTTON; 48571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else { 48581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unknown config method"); 48598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 48618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 486204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (use == WPAS_P2P_PD_AUTO) { 486304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(wpa_s->pending_join_dev_addr, peer_addr, ETH_ALEN); 486404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_config_methods = config_methods; 486504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 1; 486604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_join = 0; 486704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_before_join = 0; 486804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry = 0; 486904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_stop_find(wpa_s); 487004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_join_scan_count = 0; 487104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_get_time(&wpa_s->p2p_auto_started); 487204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Auto PD started at %ld.%06ld", 487304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.sec, 487404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.usec); 487504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_join_scan(wpa_s, NULL); 487604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 487704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 487804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 48798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 48808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_prov_disc_req(wpa_s, peer_addr, 488104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt config_methods, 488204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt use == WPAS_P2P_PD_FOR_JOIN); 48838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 48848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) 48868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr, 488904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt config_methods, use == WPAS_P2P_PD_FOR_JOIN, 4890d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 0, 1); 48918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, 48958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end) 48968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_scan_result_text(ies, ies_len, buf, end); 48988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s) 49028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4903a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!offchannel_pending_action_tx(wpa_s)) 49048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 49058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new " 49078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operation request"); 4908a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt offchannel_clear_pending_action_tx(wpa_s); 49098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout, 49138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 4914c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types, 491561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *dev_id, unsigned int search_delay) 49168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clear_pending_action_tx(wpa_s); 49188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 49198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 49218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_find(wpa_s, timeout, type); 49228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 492304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL || 492404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_in_provisioning) 49258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4927c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 4928c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 49298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_find(wpa_s->global->p2p, timeout, type, 493061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt num_req_dev_types, req_dev_types, dev_id, 493161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt search_delay); 49328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4935d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s) 49368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clear_pending_action_tx(wpa_s); 49388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 49398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 49408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 4941dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen wpa_s->global->p2p_cb_on_scan_complete = 0; 49428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 49448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_p2p_stop_find(wpa_s); 4945d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 49468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 49498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(wpa_s->global->p2p); 49508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4951d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 4952d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 4953d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4954d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4955d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid wpas_p2p_stop_find(struct wpa_supplicant *wpa_s) 4956d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 4957d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpas_p2p_stop_find_oper(wpa_s) > 0) 4958d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 49598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 49608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx) 49648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 49668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 49678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout) 49718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 49738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 49758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4977c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 49788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clear_pending_action_tx(wpa_s); 49798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout == 0) { 49818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 49828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is a request for unlimited Listen state. However, at 49838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * least for now, this is mapped to a Listen state for one 49848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hour. 49858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 49868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = 3600; 49878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 49898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 49908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 49921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Stop previous find/listen operation to avoid trying to request a new 49931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * remain-on-channel operation while the driver is still running the 49941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * previous one. 49951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 49961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->global->p2p) 49971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_stop_find(wpa_s->global->p2p); 49981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 49998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpas_p2p_listen_start(wpa_s, timeout * 1000); 50008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) { 50018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = timeout * 1000; 50028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, 50038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_long_listen_timeout, 50048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s, NULL); 50058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 50068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 50088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, 50128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, int p2p_group) 50138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 50158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 50168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 50188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 50198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 50208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 50218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) 50228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 50238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE); 50258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len, 50268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group, p2p_ie); 50278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 50288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 50308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, 50341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *dst, const u8 *bssid, 503504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *ie, size_t ie_len, int ssi_signal) 50368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 50388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 50398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 50408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 50418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 504204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid, 504304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie, ie_len)) { 504404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_NOT_P2P: 504504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len, 504604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssi_signal); 504704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* fall through */ 504804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_MALFORMED: 504904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_NOT_LISTEN: 505004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_NOT_PROCESSED: 505104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt default: /* make gcc happy */ 505204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 505304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_PROCESSED: 505404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 505504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 50568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da, 50608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *bssid, 50618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 category, const u8 *data, size_t len, int freq) 50628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 50648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 50658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 50668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 50678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len, 50698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq); 50708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies) 50748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 50768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 50778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 50788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 50798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5080c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_scan_ie(wpa_s->global->p2p, ies, NULL); 50818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s) 50858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_deinit(wpa_s->p2p_group); 50878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group = NULL; 50881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 50891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ap_configured_cb = NULL; 50901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ap_configured_cb_ctx = NULL; 50911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ap_configured_cb_data = NULL; 50921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->connect_without_scan = NULL; 50938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr) 50978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 50998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 51018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_reject(wpa_s, addr); 51028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 51048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 51058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_reject(wpa_s->global->p2p, addr); 51078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 51088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Invite to reinvoke a persistent group */ 51118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 511231be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, 51137a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int ht40, int pref_freq) 51148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 51158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_invite_role role; 5116c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt u8 *bssid = NULL; 5117c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int force_freq = 0; 51187a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int res; 51197a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 5120700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->global->p2p_invite_group = NULL; 51217a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (peer_addr) 51227a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); 51237a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt else 51247a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 51258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 512631be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_persistent_go_freq = freq; 512731be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_go_ht40 = !!ht40; 51288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 51298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_GO; 51308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer_addr == NULL) { 51318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Missing peer " 51328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "address in invitation command"); 51338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 51348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 51358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_create_iface(wpa_s)) { 51368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, 51378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_IF_P2P_GO) < 0) { 51388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to " 51398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "allocate a new interface for the " 51408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group"); 51418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 51428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 51438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->pending_interface_addr; 51448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 51458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->own_addr; 51468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 51478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_CLIENT; 51488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer_addr = ssid->bssid; 51498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 51508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_invite_ssid_id = ssid->id; 51518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5152c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq); 51537a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (res) 51547a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return res; 5155af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff 51568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 51578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_invite(wpa_s, peer_addr, role, bssid, 51588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid, ssid->ssid_len, 51598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_dev_addr, 1); 51608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 51628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 51638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, 51657a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr, 51667a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 1, pref_freq); 51678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 51688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Invite to join an active group */ 51718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, 51728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer_addr, const u8 *go_dev_addr) 51738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 51748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global = wpa_s->global; 51758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_invite_role role; 5176c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt u8 *bssid = NULL; 51778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 5178c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt int persistent; 5179c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int force_freq = 0, pref_freq = 0; 51807a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int res; 51818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518231be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_persistent_go_freq = 0; 518331be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_go_ht40 = 0; 518431be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen 51858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 51868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(wpa_s->ifname, ifname) == 0) 51878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 51888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 51898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) { 51908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Interface '%s' not found", ifname); 51918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 51928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 51938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 51958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 51968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No current SSID to use for " 51978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation"); 51988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 51998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5201700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->global->p2p_invite_group = wpa_s; 5202c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt persistent = ssid->p2p_persistent_group && 5203c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpas_p2p_get_persistent(wpa_s->parent, peer_addr, 5204c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt ssid->ssid, ssid->ssid_len); 5205c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 52068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 52078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_ACTIVE_GO; 52088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->own_addr; 52098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go_dev_addr == NULL) 52101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt go_dev_addr = wpa_s->global->p2p_dev_addr; 52118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 52128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_CLIENT; 52138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state < WPA_ASSOCIATED) { 52148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Not associated - cannot " 52158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invite to current group"); 52168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 52178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->bssid; 52198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go_dev_addr == NULL && 52208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(wpa_s->go_dev_addr)) 52218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_dev_addr = wpa_s->go_dev_addr; 52228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent->pending_invite_ssid_id = -1; 52248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 52268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_invite(wpa_s, peer_addr, role, bssid, 52278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid, ssid->ssid_len, 5228c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt go_dev_addr, persistent); 52298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 52318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 52328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5233c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt res = wpas_p2p_setup_freqs(wpa_s, 0, &force_freq, &pref_freq); 52347a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (res) 52357a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return res; 5236c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, force_freq); 52377a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 52388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, 52397a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt ssid->ssid, ssid->ssid_len, force_freq, 52407a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt go_dev_addr, persistent, pref_freq); 52418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 52428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_completed(struct wpa_supplicant *wpa_s) 52458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 52468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 52478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ssid_txt; 52488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 524975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int network_id = -1; 52508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int persistent; 52511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int freq; 52528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 525304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) { 525404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 525504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->parent, NULL); 525604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 525704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 52588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->show_group_started || !ssid) 525961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto done; 52608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 0; 52628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len); 52648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 52658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->bssid_set) 52668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(go_dev_addr, ssid->bssid, ETH_ALEN); 52678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid, 52688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len); 52698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->go_dev_addr, go_dev_addr, ETH_ALEN); 52708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_group_formation == wpa_s) 52728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 52738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = wpa_s->current_bss ? wpa_s->current_bss->freq : 52751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (int) wpa_s->assoc_freq; 52768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->passphrase == NULL && ssid->psk_set) { 52778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char psk[65]; 52788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32); 5279b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 5280b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "%s client ssid=\"%s\" freq=%d psk=%s " 5281b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "go_dev_addr=" MACSTR "%s", 5282b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, ssid_txt, freq, psk, 5283b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(go_dev_addr), 5284b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt persistent ? " [PERSISTENT]" : ""); 52858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5286b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 5287b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "%s client ssid=\"%s\" freq=%d " 5288b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt "passphrase=\"%s\" go_dev_addr=" MACSTR "%s", 5289b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, ssid_txt, freq, 5290b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt ssid->passphrase ? ssid->passphrase : "", 5291b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MAC2STR(go_dev_addr), 5292b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt persistent ? " [PERSISTENT]" : ""); 52938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (persistent) 529675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = wpas_p2p_store_persistent_group(wpa_s->parent, 529775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ssid, go_dev_addr); 529875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (network_id < 0) 529975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = ssid->id; 530075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 1); 530161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 530261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtdone: 530337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpas_p2p_continue_after_scan(wpa_s); 53048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 53058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1, 53088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval1, u32 duration2, u32 interval2) 53098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 53108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 53118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 53128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 53138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 53148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state < WPA_ASSOCIATED || 53168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid == NULL || 53178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->mode != WPAS_MODE_INFRA) 53188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 53198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid, 53218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->own_addr, wpa_s->assoc_freq, 53228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt duration1, interval1, duration2, interval2); 53238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 53248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period, 53278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 53288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 53298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 53308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 53318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 53338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 53348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_ext_listen(wpa_s->global->p2p, period, interval); 53368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 53378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_p2p_is_client(struct wpa_supplicant *wpa_s) 53401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 5341d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->current_ssid == NULL) { 5342d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 5343d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * current_ssid can be cleared when P2P client interface gets 5344d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * disconnected, so assume this interface was used as P2P 5345d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * client. 5346d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 5347d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 5348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 5349d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return wpa_s->current_ssid->p2p_group && 53501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->current_ssid->mode == WPAS_MODE_INFRA; 53511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 53521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 53531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 53548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx) 53558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 53568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 53578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) { 53598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - " 53608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "disabled"); 53618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 53628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 53638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 536404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group idle timeout reached - terminate " 536504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "group"); 536661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_IDLE_TIMEOUT); 53678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 53688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s) 53718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 537204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int timeout; 537304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 537404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0) 537504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout"); 53761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 53771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group) 53788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 53798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout = wpa_s->conf->p2p_group_idle; 53811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA && 53821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE)) 53831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout = P2P_MAX_CLIENT_IDLE; 53841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 53851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (timeout == 0) 53868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 53878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (timeout < 0) { 538904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA) 539004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt timeout = 0; /* special client mode no-timeout */ 539104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 539204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 539304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 539404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 539504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_in_provisioning) { 539604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 539704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Use the normal group formation timeout during the 539804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * provisioning phase to avoid terminating this process too 539904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * early due to group idle timeout. 540004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 540104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout " 540204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "during provisioning"); 540304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 540404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 54059e4e8acef07b7053e93024a621489286900b9ec7Deepthi Gowri 540604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->show_group_started) { 540704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 540804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Use the normal group formation timeout between the end of 540904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * the provisioning phase and completion of 4-way handshake to 541004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * avoid terminating this process too early due to group idle 541104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * timeout. 541204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 541304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout " 541404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "while waiting for initial 4-way handshake to " 541504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "complete"); 541604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 541704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 541804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 54198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds", 54201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout); 54211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout, 54221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL); 54238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 54248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54262b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen/* Returns 1 if the interface was removed */ 54272b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenint wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, 54282b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen u16 reason_code, const u8 *ie, size_t ie_len, 54292b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen int locally_generated) 54308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 54318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 54322b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 0; 54338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 54342b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 0; 54358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 543604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!locally_generated) 543704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie, 543804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie_len); 543904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 544004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (reason_code == WLAN_REASON_DEAUTH_LEAVING && !locally_generated && 544104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid && 544204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid->p2p_group && 544304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid->mode == WPAS_MODE_INFRA) { 544404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group " 544504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "session is ending"); 54462b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen if (wpas_p2p_group_delete(wpa_s, 54472b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen P2P_GROUP_REMOVAL_GO_ENDING_SESSION) 54482b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen > 0) 54492b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 1; 545004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 54512b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen 54522b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 0; 54538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 54548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, 545704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 reason_code, const u8 *ie, size_t ie_len, 545804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int locally_generated) 54598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 54608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 54618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 54628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 54638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 54648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 546504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!locally_generated) 546604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie, 546704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie_len); 54688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 54698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_config(struct wpa_supplicant *wpa_s) 54728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 54738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 54748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 54768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 54778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)) 54798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 54808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME) 54828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_dev_name(p2p, wpa_s->conf->device_name); 54838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) 54858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type); 54868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wps && 54888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS)) 54898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_config_methods(p2p, wpa_s->wps->config_methods); 54908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wps && (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID)) 54928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_uuid(p2p, wpa_s->wps->uuid); 54938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_WPS_STRING) { 54958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_manufacturer(p2p, wpa_s->conf->manufacturer); 54968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_model_name(p2p, wpa_s->conf->model_name); 54978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_model_number(p2p, wpa_s->conf->model_number); 54988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_serial_number(p2p, wpa_s->conf->serial_number); 54998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 55008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) 55028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_sec_dev_types(p2p, 55038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (void *) wpa_s->conf->sec_device_type, 55048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->num_sec_device_types); 55058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION) { 55078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 55088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 55098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) { 55108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->wps_vendor_ext[i] == NULL) 55118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 55128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_wps_vendor_extension( 55138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, wpa_s->conf->wps_vendor_ext[i]); 55148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 55158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 55168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) && 55188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->country[0] && wpa_s->conf->country[1]) { 55198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char country[3]; 55208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[0] = wpa_s->conf->country[0]; 55218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[1] = wpa_s->conf->country[1]; 55228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[2] = 0x04; 55238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_country(p2p, country); 55248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 55258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_SSID_POSTFIX) { 55278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_ssid_postfix(p2p, (u8 *) wpa_s->conf->p2p_ssid_postfix, 55288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_ssid_postfix ? 55298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(wpa_s->conf->p2p_ssid_postfix) : 55308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0); 55318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 55328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_INTRA_BSS) 55348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_intra_bss_dist(p2p, wpa_s->conf->p2p_intra_bss); 553575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 553675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_LISTEN_CHANNEL) { 553775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen u8 reg_class, channel; 553875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int ret; 553975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen unsigned int r; 554075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->p2p_listen_reg_class && 554175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->conf->p2p_listen_channel) { 554275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen reg_class = wpa_s->conf->p2p_listen_reg_class; 554375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen channel = wpa_s->conf->p2p_listen_channel; 554475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 554575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen reg_class = 81; 554675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 554775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Pick one of the social channels randomly as the 554875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * listen channel. 554975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 555075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_get_random((u8 *) &r, sizeof(r)); 555175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen channel = 1 + (r % 3) * 5; 555275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 555375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ret = p2p_set_listen_channel(p2p, reg_class, channel); 555475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ret) 555575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_ERROR, "P2P: Own listen channel update " 555675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "failed: %d", ret); 555775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 555875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_OPER_CHANNEL) { 555975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen u8 op_reg_class, op_channel, cfg_op_channel; 556075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int ret = 0; 556175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen unsigned int r; 556275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->p2p_oper_reg_class && 556375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->conf->p2p_oper_channel) { 556475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_reg_class = wpa_s->conf->p2p_oper_reg_class; 556575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_channel = wpa_s->conf->p2p_oper_channel; 556675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen cfg_op_channel = 1; 556775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 556875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_reg_class = 81; 556975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 557075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Use random operation channel from (1, 6, 11) 557175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *if no other preference is indicated. 557275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 557375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_get_random((u8 *) &r, sizeof(r)); 557475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_channel = 1 + (r % 3) * 5; 557575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen cfg_op_channel = 0; 557675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 557775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ret = p2p_set_oper_channel(p2p, op_reg_class, op_channel, 557875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen cfg_op_channel); 557975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ret) 558075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_ERROR, "P2P: Own oper channel update " 558175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "failed: %d", ret); 558275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 558304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 558404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PREF_CHAN) { 558504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_set_pref_chan(p2p, wpa_s->conf->num_p2p_pref_chan, 558604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->conf->p2p_pref_chan) < 0) { 558704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Preferred channel list " 558804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "update failed"); 558904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 559004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 55918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 55928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start, 55958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int duration) 55968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 55978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->ap_iface) 55988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 55998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start, 56008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt duration); 56018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled) 56058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 56078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 56088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 56098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 56108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->cross_connection = enabled; 56128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_cross_connect(wpa_s->global->p2p, enabled); 56138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!enabled) { 56158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 56168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) 56188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 56198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->cross_connect_enabled == 0) 56208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 56218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_enabled = 0; 56238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_in_use = 0; 5624b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(iface->parent, MSG_INFO, 5625b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s", 5626b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt iface->ifname, 5627b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt iface->cross_connect_uplink); 56288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 56328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink) 56368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 56388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!uplink->global->cross_connection) 56408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 56418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = uplink->global->ifaces; iface; iface = iface->next) { 56438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface->cross_connect_enabled) 56448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 56458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) != 56468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 56478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 56488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->ap_iface == NULL) 56498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 56508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->cross_connect_in_use) 56518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 56528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_in_use = 1; 5654b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(iface->parent, MSG_INFO, 5655b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s", 5656b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt iface->ifname, iface->cross_connect_uplink); 56578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink) 56628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 56648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = uplink->global->ifaces; iface; iface = iface->next) { 56668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface->cross_connect_enabled) 56678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 56688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) != 56698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 56708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 56718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface->cross_connect_in_use) 56728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 56738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5674b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(iface->parent, MSG_INFO, 5675b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s", 5676b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt iface->ifname, iface->cross_connect_uplink); 56778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_in_use = 0; 56788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s) 56838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface || wpa_s->current_ssid == NULL || 56858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->mode != WPAS_MODE_INFRA || 56868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_disallowed) 56878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_disable_cross_connect(wpa_s); 56888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 56898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_enable_cross_connect(wpa_s); 569004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->ap_iface && 569104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0) 569204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout"); 56938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s) 56978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_disable_cross_connect(wpa_s); 56991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->ap_iface && 57001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !eloop_is_timeout_registered(wpas_p2p_group_idle_timeout, 57011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL)) 57028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 57038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 57048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s) 57078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 57088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 57098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->global->cross_connection) 57118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 57128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { 57148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface == wpa_s) 57158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 57168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->drv_flags & 57178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE) 57188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 57198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) 57208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 57218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_enabled = 1; 57238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname, 57248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->cross_connect_uplink)); 57258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from " 57268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s to %s whenever uplink is available", 57278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname, wpa_s->cross_connect_uplink); 57288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->ap_iface || iface->current_ssid == NULL || 57308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->current_ssid->mode != WPAS_MODE_INFRA || 57318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_disallowed || 57328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->wpa_state != WPA_COMPLETED) 57338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 57348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_in_use = 1; 5736b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 5737b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s", 5738b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_s->ifname, wpa_s->cross_connect_uplink); 57398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 57408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 57418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 57428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s) 57458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 57468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT && 57478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !wpa_s->p2p_in_provisioning) 57488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* not P2P client operation */ 57498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Terminate connection due to WPS PBC " 57518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "session overlap"); 57528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s != wpa_s->parent) 57538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_ctrl(wpa_s->parent, MSG_INFO, WPS_EVENT_OVERLAP); 575434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpas_p2p_group_formation_failed(wpa_s); 57558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 57568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 57578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s) 57608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 57618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels chan; 57628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global == NULL || wpa_s->global->p2p == NULL) 57648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 57658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&chan, 0, sizeof(chan)); 57678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_setup_channels(wpa_s, &chan)) { 57688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to update supported " 57698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel list"); 57708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 57718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 57728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_update_channel_list(wpa_s->global->p2p, &chan); 57748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 57758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5777a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void wpas_p2p_scan_res_ignore(struct wpa_supplicant *wpa_s, 5778a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt struct wpa_scan_results *scan_res) 5779a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 5780a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore scan results"); 5781a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 5782a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 5783a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 57848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_cancel(struct wpa_supplicant *wpa_s) 57858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 57868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global = wpa_s->global; 57878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 57888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer; 57898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p == NULL) 57918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 57928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to cancel group formation"); 57948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->pending_interface_name[0] && 57968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(wpa_s->pending_interface_addr)) 57978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 57988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = p2p_get_go_neg_peer(global->p2p); 58008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer) { 58018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unauthorize pending GO Neg peer " 58028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(peer)); 58038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_unauthorize(global->p2p, peer); 580404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt found = 1; 58058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 58068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5807a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->scan_res_handler == wpas_p2p_scan_res_join) { 5808a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Stop pending scan for join"); 5809a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore; 5810a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt found = 1; 5811a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 5812a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 5813a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->pending_pd_before_join) { 5814a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Stop pending PD before join"); 5815a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 5816a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt found = 1; 5817a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 5818a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 58198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_stop_find(wpa_s); 58208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 58228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == global->p2p_group_formation && 58238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpa_s->p2p_in_provisioning || 58248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent->pending_interface_type == 58258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_IF_P2P_CLIENT)) { 58268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Interface %s in group " 58278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "formation found - cancelling", 58288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname); 58298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 58308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 58318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent, NULL); 5832adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen if (wpa_s->p2p_in_provisioning) { 5833adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen wpas_group_formation_completed(wpa_s, 0); 5834adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen break; 5835adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen } 583661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, 583761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_REQUESTED); 58388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 58398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 58408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 58418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 58438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No ongoing group formation found"); 58448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 58458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 58468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 58488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 58498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s) 58528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 58538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group) 58548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 58558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not " 58578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "being available anymore"); 585861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_UNAVAILABLE); 58598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 58608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s, 58638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_24, int freq_5, int freq_overall) 58648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 58658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 58668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)) 58678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 58688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_best_channels(p2p, freq_24, freq_5, freq_overall); 58698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 58708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr) 58738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 58748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 peer[ETH_ALEN]; 58758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 58768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)) 58788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 58798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(addr, peer)) 58818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 58828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_unauthorize(p2p, peer); 58848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 58858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 58888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_disconnect - Disconnect from a P2P Group 58898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 58908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 58918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 58928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This can be used to disconnect from a group in which the local end is a P2P 58938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Client or to end a P2P Group in case the local end is the Group Owner. If a 58948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * virtual network interface was created for this group, that interface will be 58958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * removed. Otherwise, only the configured P2P group network will be removed 58968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from the interface. 58978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 58988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_disconnect(struct wpa_supplicant *wpa_s) 58998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 59008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 59028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 59038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59042b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED) < 0 ? 59052b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen -1 : 0; 59068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 59071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 59081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 59091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpas_p2p_in_progress(struct wpa_supplicant *wpa_s) 59101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 5911f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt int ret; 5912f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 59131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 59141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 59151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5916f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt ret = p2p_in_progress(wpa_s->global->p2p); 5917f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (ret == 0) { 5918f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 5919f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Check whether there is an ongoing WPS provisioning step (or 5920f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * other parts of group formation) on another interface since 5921f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * p2p_in_progress() does not report this to avoid issues for 5922f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * scans during such provisioning step. 5923f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 5924f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (wpa_s->global->p2p_group_formation && 5925f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_s->global->p2p_group_formation != wpa_s) { 5926f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Another interface (%s) " 5927f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "in group formation", 5928f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_s->global->p2p_group_formation->ifname); 5929f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt ret = 1; 5930f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 5931f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 5932f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 593392c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt if (!ret && wpa_s->global->p2p_go_wait_client.sec) { 593492c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt struct os_time now; 593592c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt os_get_time(&now); 593692c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt if (now.sec > wpa_s->global->p2p_go_wait_client.sec + 593792c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt P2P_MAX_INITIAL_CONN_WAIT_GO) { 593892c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt /* Wait for the first client has expired */ 593992c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt wpa_s->global->p2p_go_wait_client.sec = 0; 594092c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt } else { 594192c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Waiting for initial client connection during group formation"); 594292c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt ret = 1; 594392c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt } 594492c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt } 594592c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt 5946f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return ret; 59471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 59481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 59491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 59501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpas_p2p_network_removed(struct wpa_supplicant *wpa_s, 59511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *ssid) 59521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 59531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->p2p_in_provisioning && ssid->p2p_group && 59541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 59551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->parent, NULL) > 0) { 595604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /** 595704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Remove the network by scheduling the group formation 595804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * timeout to happen immediately. The teardown code 595904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * needs to be scheduled to run asynch later so that we 596004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * don't delete data from under ourselves unexpectedly. 596104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Calling wpas_p2p_group_formation_timeout directly 596204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * causes a series of crashes in WPS failure scenarios. 596304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 59641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to " 59651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P group network getting removed"); 596604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout, 596704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->parent, NULL); 59681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 59691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 59701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 59711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 59721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s, 5973c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt const u8 *addr, const u8 *ssid, 5974c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t ssid_len) 59751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 59761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *s; 59771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t i; 59781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 59791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 59801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->disabled != 2) 59811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 5982c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid && 5983c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt (ssid_len != s->ssid_len || 5984c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) != 0)) 5985c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 5986391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (addr == NULL) { 5987391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO) 5988391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return s; 5989391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 5990391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 59911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0) 59921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return s; /* peer is GO in the persistent group */ 59931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL) 59941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 59951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; i < s->num_p2p_clients; i++) { 59961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, 59971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt addr, ETH_ALEN) == 0) 59981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return s; /* peer is P2P client in persistent 59991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * group */ 60001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 60011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 60021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 60031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 60041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 60051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 60061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 60071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s, 60081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr) 60091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 601092c368d56f46a4e648b441085707c1381b5e5f63Dmitry Shmidt wpa_s->global->p2p_go_wait_client.sec = 0; 60111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (addr == NULL) 60121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 60131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_add_persistent_group_client(wpa_s, addr); 60141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 6015c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 601604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 601704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s, 601804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int group_added) 601904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 602004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *group = wpa_s; 602104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->global->p2p_group_formation) 602204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt group = wpa_s->global->p2p_group_formation; 602304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s = wpa_s->parent; 602404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt offchannel_send_action_done(wpa_s); 602504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (group_added) 602661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(group, P2P_GROUP_REMOVAL_SILENT); 602704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Fall back to GO Negotiation"); 602804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin, 602904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0, 603004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq, 603104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id, 603261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_pd_before_go_neg, 603361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40); 603404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 603504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 603604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 603704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s) 603804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 603904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->p2p_fallback_to_go_neg || 604004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_in_provisioning <= 5) 604104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 604204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 604304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr) > 0) 604404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; /* peer operating as a GO */ 604504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 604604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: GO not found for p2p_connect-auto - " 604704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "fallback to GO Negotiation"); 604804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_fallback_to_go_neg(wpa_s, 1); 604904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 605004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 605104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 605204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 605361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 605461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtunsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s) 605561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 605661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *rn, *rn2; 605761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpa_supplicant *ifs; 605861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 605961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->wpa_state > WPA_SCANNING) { 606061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search delay due to " 606161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "concurrent operation", 606261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_CONCURRENT_SEARCH_DELAY); 606361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return P2P_CONCURRENT_SEARCH_DELAY; 606461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 606561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 606661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!wpa_s->driver->get_radio_name) 606761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 606861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv); 606961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (rn == NULL || rn[0] == '\0') 607061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 607161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 607261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { 607361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ifs == wpa_s || !ifs->driver->get_radio_name) 607461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 607561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 607661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt rn2 = ifs->driver->get_radio_name(ifs->drv_priv); 607761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!rn2 || os_strcmp(rn, rn2) != 0) 607861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 607961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ifs->wpa_state > WPA_SCANNING) { 608061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search " 608161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "delay due to concurrent operation on " 608261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "interface %s", 608361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_CONCURRENT_SEARCH_DELAY, ifs->ifname); 608461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return P2P_CONCURRENT_SEARCH_DELAY; 608561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 608661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 608761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 608861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 608961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 609061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 609137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 609237d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidtvoid wpas_p2p_continue_after_scan(struct wpa_supplicant *wpa_s) 609337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt{ 609437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Station mode scan operation not " 609537d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt "pending anymore (sta_scan_pending=%d " 609637d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt "p2p_cb_on_scan_complete=%d)", wpa_s->sta_scan_pending, 609737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_s->global->p2p_cb_on_scan_complete); 609837d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_s->sta_scan_pending = 0; 609937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 610037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt if (!wpa_s->global->p2p_cb_on_scan_complete) 610137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt return; 610237d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_s->global->p2p_cb_on_scan_complete = 0; 610337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 610437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 610537d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt return; 610637d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 610737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) { 610837d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation " 610937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt "continued after successful connection"); 611037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt p2p_increase_search_delay(wpa_s->global->p2p, 611137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpas_p2p_search_delay(wpa_s)); 611237d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt } 611337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt} 611437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 6115391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6116391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int wpas_p2p_remove_psk_entry(struct wpa_supplicant *wpa_s, 6117391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *s, const u8 *addr, 6118391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int iface_addr) 6119391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 6120391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct psk_list_entry *psk, *tmp; 6121391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int changed = 0; 6122391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6123391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_for_each_safe(psk, tmp, &s->psk_list, struct psk_list_entry, 6124391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt list) { 6125391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if ((iface_addr && !psk->p2p && 6126391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcmp(addr, psk->addr, ETH_ALEN) == 0) || 6127391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (!iface_addr && psk->p2p && 6128391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcmp(addr, psk->addr, ETH_ALEN) == 0)) { 6129391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 6130391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt "P2P: Remove persistent group PSK list entry for " 6131391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR " p2p=%u", 6132391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(psk->addr), psk->p2p); 6133391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_del(&psk->list); 6134391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(psk); 6135391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt changed++; 6136391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6137391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6138391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6139391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return changed; 6140391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 6141391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6142391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6143391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr, 6144391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *p2p_dev_addr, 6145391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *psk, size_t psk_len) 6146391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 6147391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 6148391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *persistent; 6149391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct psk_list_entry *p; 6150391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6151391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (psk_len != sizeof(p->psk)) 6152391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 6153391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6154391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p_dev_addr) { 6155391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR 6156391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt " p2p_dev_addr=" MACSTR, 6157391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(mac_addr), MAC2STR(p2p_dev_addr)); 6158391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (is_zero_ether_addr(p2p_dev_addr)) 6159391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dev_addr = NULL; 6160391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 6161391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR, 6162391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(mac_addr)); 6163391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6164391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6165391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) { 6166391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: new_psk_cb during group formation"); 6167391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* To be added to persistent group once created */ 6168391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->global->add_psk == NULL) { 6169391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->global->add_psk = os_zalloc(sizeof(*p)); 6170391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->global->add_psk == NULL) 6171391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 6172391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6173391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p = wpa_s->global->add_psk; 6174391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p_dev_addr) { 6175391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p->p2p = 1; 6176391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN); 6177391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 6178391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p->p2p = 0; 6179391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->addr, mac_addr, ETH_ALEN); 6180391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6181391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->psk, psk, psk_len); 6182391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 6183391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6184391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6185391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GO || !ssid->p2p_persistent_group) { 6186391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Ignore new_psk_cb on not-persistent GO"); 6187391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 6188391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6189391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6190391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid, 6191391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid_len); 6192391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!persistent) { 6193391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not find persistent group information to store the new PSK"); 6194391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 6195391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6196391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6197391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p = os_zalloc(sizeof(*p)); 6198391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p == NULL) 6199391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 6200391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p_dev_addr) { 6201391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p->p2p = 1; 6202391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN); 6203391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 6204391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p->p2p = 0; 6205391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->addr, mac_addr, ETH_ALEN); 6206391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6207391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcpy(p->psk, psk, psk_len); 6208391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6209391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (dl_list_len(&persistent->psk_list) > P2P_MAX_STORED_CLIENTS) { 6210391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct psk_list_entry *last; 6211391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt last = dl_list_last(&persistent->psk_list, 6212391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct psk_list_entry, list); 6213391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove oldest PSK entry for " 6214391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR " (p2p=%u) to make room for a new one", 6215391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(last->addr), last->p2p); 6216391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_del(&last->list); 6217391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(last); 6218391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6219391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6220391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_p2p_remove_psk_entry(wpa_s->parent, persistent, 6221391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dev_addr ? p2p_dev_addr : mac_addr, 6222391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dev_addr == NULL); 6223391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (p2p_dev_addr) { 6224391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for p2p_dev_addr=" 6225391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR, MAC2STR(p2p_dev_addr)); 6226391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 6227391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for addr=" MACSTR, 6228391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(mac_addr)); 6229391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6230391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_add(&persistent->psk_list, &p->list); 6231391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6232391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE 6233391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->parent->conf->update_config && 6234391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf)) 6235391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 6236391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */ 6237391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 6238391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6239391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6240391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_remove_psk(struct wpa_supplicant *wpa_s, 6241391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *s, const u8 *addr, 6242391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int iface_addr) 6243391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 6244391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int res; 6245391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6246391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt res = wpas_p2p_remove_psk_entry(wpa_s, s, addr, iface_addr); 6247391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (res > 0) { 6248391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE 6249391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->conf->update_config && 6250391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_config_write(wpa_s->confname, wpa_s->conf)) 6251391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 6252391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt "P2P: Failed to update configuration"); 6253391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */ 6254391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6255391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 6256391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6257391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6258391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_remove_client_go(struct wpa_supplicant *wpa_s, 6259391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *peer, int iface_addr) 6260391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 6261391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_data *hapd; 6262391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_wpa_psk *psk, *prev, *rem; 6263391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct sta_info *sta; 6264391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6265391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL || 6266391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->current_ssid->mode != WPAS_MODE_P2P_GO) 6267391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 6268391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6269391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Remove per-station PSK entry */ 6270391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hapd = wpa_s->ap_iface->bss[0]; 6271391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt prev = NULL; 6272391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt psk = hapd->conf->ssid.wpa_psk; 6273391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt while (psk) { 6274391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if ((iface_addr && os_memcmp(peer, psk->addr, ETH_ALEN) == 0) || 6275391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (!iface_addr && 6276391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memcmp(peer, psk->p2p_dev_addr, ETH_ALEN) == 0)) { 6277391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove operating group PSK entry for " 6278391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR " iface_addr=%d", 6279391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(peer), iface_addr); 6280391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (prev) 6281391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt prev->next = psk->next; 6282391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else 6283391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hapd->conf->ssid.wpa_psk = psk->next; 6284391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt rem = psk; 6285391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt psk = psk->next; 6286391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(rem); 6287391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 6288391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt prev = psk; 6289391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt psk = psk->next; 6290391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6291391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6292391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6293391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Disconnect from group */ 6294391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (iface_addr) 6295391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sta = ap_get_sta(hapd, peer); 6296391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else 6297391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sta = ap_get_sta_p2p(hapd, peer); 6298391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (sta) { 6299391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disconnect peer " MACSTR 6300391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt " (iface_addr=%d) from group", 6301391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MAC2STR(peer), iface_addr); 6302391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 6303391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING); 6304391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ap_sta_deauthenticate(hapd, sta, WLAN_REASON_DEAUTH_LEAVING); 6305391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6306391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 6307391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6308391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6309391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtvoid wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer, 6310391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int iface_addr) 6311391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 6312391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *s; 6313391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_supplicant *w; 6314391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6315391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove client " MACSTR, MAC2STR(peer)); 6316391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6317391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Remove from any persistent group */ 6318391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (s = wpa_s->parent->conf->ssid; s; s = s->next) { 6319391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO) 6320391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 6321391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!iface_addr) 6322391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_remove_persistent_peer(wpa_s, s, peer, 0); 6323391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_p2p_remove_psk(wpa_s->parent, s, peer, iface_addr); 6324391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6325391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6326391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* Remove from any operating group */ 6327391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (w = wpa_s->global->ifaces; w; w = w->next) 6328391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_p2p_remove_client_go(w, peer, iface_addr); 6329391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 6330391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6331391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6332391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx) 6333391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 6334391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 6335391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_PSK_FAILURE); 6336391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 6337391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6338391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6339391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtint wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s) 6340391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 6341391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 6342391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6343391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ssid == NULL || !ssid->p2p_group) 6344391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 6345391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6346391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpa_s->p2p_last_4way_hs_fail && 6347391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->p2p_last_4way_hs_fail == ssid) { 6348391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 6349391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_ssid *persistent; 6350391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6351391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (wpas_p2p_persistent_group(wpa_s, go_dev_addr, 6352391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid, 6353391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid_len) <= 0) { 6354391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not determine whether 4-way handshake failures were for a persistent group"); 6355391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt goto disconnect; 6356391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6357391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6358391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Two 4-way handshake failures for a P2P group - go_dev_addr=" 6359391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt MACSTR, MAC2STR(go_dev_addr)); 6360391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt persistent = wpas_p2p_get_persistent(wpa_s->parent, go_dev_addr, 6361391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid, 6362391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ssid->ssid_len); 6363391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (persistent == NULL || persistent->mode != WPAS_MODE_INFRA) { 6364391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No matching persistent group stored"); 6365391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt goto disconnect; 6366391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6367391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_msg_global(wpa_s->parent, MSG_INFO, 6368391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt P2P_EVENT_PERSISTENT_PSK_FAIL "%d", 6369391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt persistent->id); 6370391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt disconnect: 6371391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->p2p_last_4way_hs_fail = NULL; 6372391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* 6373391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Remove the group from a timeout to avoid issues with caller 6374391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * continuing to use the interface if this is on a P2P group 6375391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * interface. 6376391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt */ 6377391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt eloop_register_timeout(0, 0, wpas_p2p_psk_failure_removal, 6378391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s, NULL); 6379391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 1; 6380391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6381391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6382391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_s->p2p_last_4way_hs_fail = ssid; 6383391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 6384391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 6385391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6386c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef ANDROID_P2P 63871cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidtstatic void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx) 63881cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt{ 63891cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 63901cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt 63911cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Frequency conflict - terminate group"); 63921cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_FREQ_CONFLICT); 63931cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt} 63941cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt 6395d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq, 6396d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ssid *ssid) 6397c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 6398c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct wpa_supplicant *iface = NULL; 6399c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 6400c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 6401c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { 640212b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson if ((iface->current_ssid) && 640312b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson (iface->current_ssid->frequency != freq) && 640412b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson ((iface->p2p_group_interface) || 640512b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson (iface->current_ssid->p2p_group))) { 640612b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson 640712b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson if ((iface->p2p_group_interface == P2P_GROUP_INTERFACE_GO) || 640812b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson (iface->current_ssid->mode == WPAS_MODE_P2P_GO)) { 640912b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson /* Try to see whether we can move the GO. If it 641012b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson * is not possible, remove the GO interface 641112b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson */ 641212b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson if (wpa_drv_switch_channel(iface, freq) == 0) { 641312b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson wpa_printf(MSG_ERROR, "P2P: GO Moved to freq(%d)", freq); 641412b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson iface->current_ssid->frequency = freq; 641512b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson continue; 641612b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson } 6417c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 6418c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 6419c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* If GO cannot be moved or if the conflicting interface is a 6420c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * P2P Client, remove the interface depending up on the connection 6421c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * priority */ 6422d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if(!wpas_is_p2p_prioritized(iface)) { 6423f4f5db315918f3f048324ea43dc37a3b0fb31eccDmitry Shmidt /* STA connection has priority over existing 6424c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * P2P connection. So remove the interface */ 6425d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Removing P2P connection due to Single channel" 6426687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt "concurrent mode frequency conflict"); 64271cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt eloop_register_timeout(0, 0, wpas_p2p_group_freq_conflict, 64281cf4573e05a4e7ce02e0ccc46771a1da5f303411Dmitry Shmidt iface, NULL); 6429d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* If connection in progress is p2p connection, do not proceed for the connection */ 6430d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s == iface) 6431d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 6432d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else 6433d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* If connection in progress is STA connection, proceed for the connection */ 6434d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 6435c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else { 6436d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* P2p connection has priority, disable the STA network*/ 6437d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_supplicant_disable_network(wpa_s->global->ifaces, ssid); 6438d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_msg(wpa_s->global->ifaces, MSG_INFO, WPA_EVENT_FREQ_CONFLICT 6439d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt " id=%d", ssid->id); 6440d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memset(wpa_s->global->ifaces->pending_bssid, 0, ETH_ALEN); 6441d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s == iface) { 6442d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* p2p connection is in progress, continue connecting...*/ 6443d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 6444d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 6445d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else { 6446d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* STA connection is in progress, do not allow to continue */ 6447d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 6448d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 6449c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 6450c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 6451c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 6452c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 0; 6453c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 6454c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif 6455