p2p_supplicant.c revision 444d567b27731d8572ef37697dd12fd1c37c2f24
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" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/p2p_hostapd.h" 2175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "eapol_supp/eapol_supp_sm.h" 2275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "rsn_supp/wpa.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config_ssid.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h" 311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "offchannel.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * How many times to try to scan to find the GO before giving up on join 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request. 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define P2P_MAX_JOIN_SCAN_ATTEMPTS 10 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#define P2P_AUTO_PD_SCAN_ATTEMPTS 5 4304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef P2P_MAX_CLIENT_IDLE 451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/* 461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * How many seconds to try to reconnect to the GO when connection in P2P client 471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * role has been lost. 481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 4998f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#ifdef ANDROID_P2P 5098f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#define P2P_MAX_CLIENT_IDLE 20 5198f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#else 521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define P2P_MAX_CLIENT_IDLE 10 5398f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#endif /* ANDROID_P2P */ 541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* P2P_MAX_CLIENT_IDLE */ 551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifndef P2P_MAX_INITIAL_CONN_WAIT 5704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/* 5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * How many seconds to wait for initial 4-way handshake to get completed after 5904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * WPS provisioning step. 6004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 6104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#define P2P_MAX_INITIAL_CONN_WAIT 10 6204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* P2P_MAX_INITIAL_CONN_WAIT */ 6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifndef P2P_CONCURRENT_SEARCH_DELAY 6561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#define P2P_CONCURRENT_SEARCH_DELAY 500 6661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* P2P_CONCURRENT_SEARCH_DELAY */ 6761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtenum p2p_group_removal_reason { 6961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_UNKNOWN, 7061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_SILENT, 7161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_FORMATION_FAILED, 7261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_REQUESTED, 7361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_IDLE_TIMEOUT, 7461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_UNAVAILABLE, 7561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_GO_ENDING_SESSION, 7661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef ANDROID_P2P 7761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_FREQ_CONFLICT 7861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif 7961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}; 8061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 81dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join_start(struct wpa_supplicant *wpa_s); 8704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr, 9004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *dev_addr, enum p2p_wps_method wps_method, 9104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int auto_join); 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s); 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx); 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s); 96f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstatic void wpas_p2p_group_formation_timeout(void *eloop_ctx, 97f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt void *timeout_ctx); 9804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s, 9904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int group_added); 100d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 103700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_p2p_set_own_freq_preference(struct wpa_supplicant *wpa_s, 104700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt int freq) 105700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 106700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 107700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; 108700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (freq > 0 && 109700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) && 110700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->parent->conf->p2p_ignore_shared_freq) 111700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt freq = 0; 112700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt p2p_set_own_freq_preference(wpa_s->global->p2p, freq); 113700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 114700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 115700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s, 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res) 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS)", 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) scan_res->num); 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < scan_res->num; i++) { 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *bss = scan_res->res[i]; 129f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct os_time time_tmp_age, entry_ts; 130f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt time_tmp_age.sec = bss->age / 1000; 131f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt time_tmp_age.usec = (bss->age % 1000) * 1000; 132f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_time_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid, 134f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt bss->freq, &entry_ts, bss->level, 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const u8 *) (bss + 1), 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->ie_len) > 0) 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_scan_res_handled(wpa_s->global->p2p); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq, 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int num_req_dev_types, 14604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *req_dev_types, const u8 *dev_id, u16 pw_id) 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 14961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpa_supplicant *ifs; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params params; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_ie, *ies; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int social_channels[] = { 2412, 2437, 2462, 0, 0 }; 1541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t ielen; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { 16061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ifs->sta_scan_pending && 16137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt (wpas_scan_scheduled(ifs) || ifs->scanning) && 16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_in_progress(wpa_s) == 2) { 16361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Delaying P2P scan to allow " 16461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "pending station mode scan to be " 16561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "completed on interface %s", ifs->ifname); 166dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen wpa_s->global->p2p_cb_on_scan_complete = 1; 16761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_supplicant_req_scan(ifs, 0, 0); 16861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 16961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P Wildcard SSID */ 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_ssids = 1; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->wps->dev.p2p = 1; 18004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev, 18104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_req_dev_types, req_dev_types); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_ie == NULL) 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 1871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) { 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(ies, wps_ie); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 195c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_scan_ie(wpa_s->global->p2p, ies, dev_id); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p_probe = 1; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies = wpabuf_head(ies); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies_len = wpabuf_len(ies); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SCAN_SOCIAL: 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freqs = social_channels; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SCAN_FULL: 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 207b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt case P2P_SCAN_SPECIFIC: 208b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt social_channels[0] = freq; 209b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt social_channels[1] = 0; 210b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt params.freqs = social_channels; 211b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt break; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SCAN_SOCIAL_PLUS_ONE: 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt social_channels[3] = freq; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freqs = social_channels; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_scan(wpa_s, ¶ms); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ret) { 223043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { 224043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen if (ifs->scanning || 225043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen ifs->scan_res_handler == wpas_p2p_scan_res_handler) { 226043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen wpa_s->global->p2p_cb_on_scan_complete = 1; 227043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen ret = 1; 228043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen break; 229043a5a9d2586bf379a3f3e811c8c64d92050e131Jouni Malinen } 2301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 231444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } else { 232444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt os_get_time(&wpa_s->scan_trigger_time); 23304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_handler; 234444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ret; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum wpa_driver_if_type wpas_p2p_if_type(int p2p_group_interface) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (p2p_group_interface) { 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_INTERFACE_PENDING: 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_GROUP; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_INTERFACE_GO: 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_GO; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_INTERFACE_CLIENT: 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_CLIENT; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WPA_IF_P2P_GROUP; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * wpas_get_p2p_group(struct wpa_supplicant *wpa_s, 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ssid_len, int *go) 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled != 0 || !s->p2p_group || 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len != ssid_len || 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) != 0) 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO && 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s != wpa_s->current_ssid) 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *go = s->mode == WPAS_MODE_P2P_GO; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_s; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s, 28161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt enum p2p_group_removal_reason removal_reason) 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *gtype; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *reason; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The current SSID was not known, but there may still be a 291aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt * pending P2P group interface waiting for provisioning or a 292aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt * P2P group that is trying to reconnect. 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->conf->ssid; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 2969d71283328fbad680cc74d9b287580e373eb4d6cJouni Malinen if (ssid->p2p_group && ssid->disabled != 2) 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3005c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen if (ssid == NULL && 3015c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE) 3025c44edb00c9384534a1b50981071874436aaecd5Jouni Malinen { 30361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: P2P group interface " 30461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "not found"); 30561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 30661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO) 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtype = "GO"; 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT || 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ssid && ssid->mode == WPAS_MODE_INFRA)) { 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->reassociate = 0; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->disconnected = 1; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_deauthenticate(wpa_s, 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtype = "client"; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gtype = "GO"; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->cross_connect_in_use) { 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_in_use = 0; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s", 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname, wpa_s->cross_connect_uplink); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (removal_reason) { 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_REMOVAL_REQUESTED: 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = " reason=REQUESTED"; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_GROUP_REMOVAL_FORMATION_FAILED: 33061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt reason = " reason=FORMATION_FAILED"; 33161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_REMOVAL_IDLE_TIMEOUT: 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = " reason=IDLE"; 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_GROUP_REMOVAL_UNAVAILABLE: 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = " reason=UNAVAILABLE"; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_GROUP_REMOVAL_GO_ENDING_SESSION: 33904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt reason = " reason=GO_ENDING_SESSION"; 34004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 341687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#ifdef ANDROID_P2P 342687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt case P2P_GROUP_REMOVAL_FREQ_CONFLICT: 343687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt reason = " reason=FREQ_CONFLICT"; 344687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt break; 345687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#endif 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason = ""; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (removal_reason != P2P_GROUP_REMOVAL_SILENT) { 35104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, 35204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_EVENT_GROUP_REMOVED "%s %s%s", 35304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->ifname, gtype, reason); 35404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0) 35704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout"); 358f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 3592f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_s->parent, NULL) > 0) { 360f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group formation " 361f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "timeout"); 3622f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_s->p2p_in_provisioning = 0; 3632f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt } 36404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 36561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (removal_reason != P2P_GROUP_REMOVAL_SILENT && ssid) 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_group_removed(wpa_s, ssid, gtype); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) { 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global; 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *ifname; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_driver_if_type type; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove group interface %s", 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname); 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global = wpa_s->global; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname = os_strdup(wpa_s->ifname); 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = wpas_p2p_if_type(wpa_s->p2p_group_interface); 377e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0); 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = global->ifaces; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s && ifname) 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_if_remove(wpa_s, type, ifname); 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ifname); 3822b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 1; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network"); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid && (ssid->p2p_group || 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION || 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) { 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int id = ssid->id; 39075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ssid == wpa_s->current_ssid) { 39175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_sm_set_config(wpa_s->wpa, NULL); 39275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid = NULL; 39475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 39575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 39675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Networks objects created during any P2P activities are not 39775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * exposed out as they might/will confuse certain non-P2P aware 39875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * applications since these network objects won't behave like 39975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * regular ones. 40075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * 40175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Likewise, we don't send out network removed signals for such 40275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * network objects. 40375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, id); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_clear_status(wpa_s); 406c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 40791c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt wpa_s->sta_scan_pending = 0; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Temporary group network not " 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found"); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->ap_iface) 41304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_ap_deinit(wpa_s); 41404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 41504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_drv_deinit_p2p_cli(wpa_s); 41661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 41761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s, 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *go_dev_addr, 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, size_t ssid_len) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_bss *bss; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 group_capab; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->go_params) 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->go_params->peer_interface_addr; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->bssid; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss = wpa_bss_get(wpa_s, bssid, ssid, ssid_len); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 iface_addr[ETH_ALEN]; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_get_interface_addr(wpa_s->global->p2p, bssid, 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface_addr) == 0) 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss = wpa_bss_get(wpa_s, iface_addr, ssid, ssid_len); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether " 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group is persistent - BSS " MACSTR " not found", 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid)); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) { 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether " 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group is persistent - BSS " MACSTR 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " did not include P2P IE", MAC2STR(bssid)); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Probe Response IEs", 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) (bss + 1), bss->ie_len); 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Beacon IEs", 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((u8 *) bss + 1) + bss->ie_len, 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->beacon_ie_len); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_capab = p2p_get_group_capab(p2p); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr = p2p_get_go_dev_addr(p2p); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Checking whether group is persistent: " 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group_capab=0x%x", group_capab); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) { 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(go_dev_addr, addr, ETH_ALEN); 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO Device Address " MACSTR, 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr)); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: BSS " MACSTR " group_capab=0x%x " 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_dev_addr=" MACSTR, 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr)); 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s, 48475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct wpa_ssid *ssid, 48575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen const u8 *go_dev_addr) 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int changed = 0; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Storing credentials for a persistent " 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group (GO Dev Addr " MACSTR ")", MAC2STR(go_dev_addr)); 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled == 2 && 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(go_dev_addr, s->bssid, ETH_ALEN) == 0 && 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len == ssid->ssid_len && 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid->ssid, s->ssid, ssid->ssid_len) == 0) 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s) { 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Update existing persistent group " 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "entry"); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->passphrase && !s->passphrase) 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt changed = 1; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (ssid->passphrase && s->passphrase && 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(ssid->passphrase, s->passphrase) != 0) 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt changed = 1; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Create a new persistent group " 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "entry"); 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt changed = 1; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = wpa_config_add_network(wpa_s->conf); 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s == NULL) 51475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return -1; 51575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 51675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 51775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Instead of network_added we emit persistent_group_added 51875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * notification. Also to keep the defense checks in 51975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * persistent_group obj registration method, we set the 52075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * relevant flags in s to designate it as a persistent group. 52175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 52275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen s->p2p_group = 1; 52375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen s->p2p_persistent_group = 1; 52475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_persistent_group_added(wpa_s, s); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_network_defaults(s); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->p2p_group = 1; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->p2p_persistent_group = 1; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->disabled = 2; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->bssid_set = 1; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(s->bssid, go_dev_addr, ETH_ALEN); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->mode = ssid->mode; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->auth_alg = WPA_AUTH_ALG_OPEN; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->key_mgmt = WPA_KEY_MGMT_PSK; 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->proto = WPA_PROTO_RSN; 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->pairwise_cipher = WPA_CIPHER_CCMP; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->export_keys = 1; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->passphrase) { 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(s->passphrase); 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->passphrase = os_strdup(ssid->passphrase); 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->psk_set) { 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->psk_set = 1; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(s->psk, ssid->psk, 32); 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->passphrase && !s->psk_set) 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_update_psk(s); 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->ssid == NULL || s->ssid_len < ssid->ssid_len) { 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(s->ssid); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid = os_malloc(ssid->ssid_len); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->ssid) { 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len = ssid->ssid_len; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(s->ssid, ssid->ssid, s->ssid_len); 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (changed && wpa_s->conf->update_config && 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_write(wpa_s->confname, wpa_s->conf)) { 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */ 56475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 56575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return s->id; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s, 5701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr) 5711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 5721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *ssid, *s; 5731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *n; 5741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t i; 57561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int found = 0; 5761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = wpa_s->current_ssid; 5781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 5791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !ssid->p2p_persistent_group) 5801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 5811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (s = wpa_s->parent->conf->ssid; s; s = s->next) { 5831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO) 5841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 5851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->ssid_len == ssid->ssid_len && 5871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0) 5881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 5891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 5901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s == NULL) 5921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 5931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) { 5951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr, 59661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ETH_ALEN) != 0) 59761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 59861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 59961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (i == s->num_p2p_clients - 1) 60061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; /* already the most recent entry */ 60161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 60261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* move the entry to mark it most recent */ 60361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memmove(s->p2p_client_list + i * ETH_ALEN, 60461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->p2p_client_list + (i + 1) * ETH_ALEN, 60561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (s->num_p2p_clients - i - 1) * ETH_ALEN); 60661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(s->p2p_client_list + 60761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (s->num_p2p_clients - 1) * ETH_ALEN, addr, ETH_ALEN); 60861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt found = 1; 60961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 6101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 61261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) { 61361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt n = os_realloc_array(s->p2p_client_list, 61461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->num_p2p_clients + 1, ETH_ALEN); 61561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (n == NULL) 61661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 61761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN); 61861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->p2p_client_list = n; 61961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->num_p2p_clients++; 62061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (!found) { 62161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Not enough room for an additional entry - drop the oldest 62261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * entry */ 62361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memmove(s->p2p_client_list, 62461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt s->p2p_client_list + ETH_ALEN, 62561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (s->num_p2p_clients - 1) * ETH_ALEN); 62661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(s->p2p_client_list + 62761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (s->num_p2p_clients - 1) * ETH_ALEN, 62861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt addr, ETH_ALEN); 62961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 6301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE 6321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->parent->conf->update_config && 6331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf)) 6341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 6351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */ 6361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 6371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_group_formation_completed(struct wpa_supplicant *wpa_s, 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int success) 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ssid_txt; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int client; 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int persistent; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 64775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int network_id = -1; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is likely called for the main interface. Update wpa_s 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to use the group interface if a new interface was created for the 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * group. 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_group_formation) 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpa_s->global->p2p_group_formation; 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_in_provisioning = 0; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!success) { 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_FAILURE); 66261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, 66361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_FORMATION_FAILED); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_FORMATION_SUCCESS); 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) { 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->mode = WPAS_MODE_P2P_GO; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_notif_formation_done(wpa_s->p2p_group); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_mac_addr_filter(wpa_s, NULL); 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = 0; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid) { 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = ssid->mode == WPAS_MODE_INFRA; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = ssid->p2p_persistent_group; 682497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr, 683497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt ETH_ALEN); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = wpas_p2p_persistent_group(wpa_s, 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_dev_addr, 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid, 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len); 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_txt = ""; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = wpa_s->p2p_group_interface == 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_GROUP_INTERFACE_CLIENT; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 0; 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client) { 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Indicate event only after successfully completed 4-way 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake, i.e., when the interface is ready for data 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * packets. 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 1; 7044b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt#ifdef ANDROID_P2P 7054b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt /* For client Second phase of Group formation (4-way handshake) can be still pending 7064b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt * So we need to restore wpa_s->global->p2p_group_formation */ 707a2854abb63b41c123e4c78e5653a55d902f00be6Dmitry Shmidt wpa_printf(MSG_INFO, "Restoring back wpa_s->global->p2p_group_formation to wpa_s %p\n", wpa_s); 7084b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt wpa_s->global->p2p_group_formation = wpa_s; 7094b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt#endif 7104b86ea55603eded752b5773179884a35e74e1a89Dmitry Shmidt 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (ssid && ssid->passphrase == NULL && ssid->psk_set) { 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char psk[65]; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s GO ssid=\"%s\" freq=%d psk=%s go_dev_addr=" MACSTR 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname, ssid_txt, ssid->frequency, psk, 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_dev_addr), 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent ? " [PERSISTENT]" : ""); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_cross_connect_setup(wpa_s); 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s GO ssid=\"%s\" freq=%d passphrase=\"%s\" " 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_dev_addr=" MACSTR "%s", 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname, ssid_txt, ssid ? ssid->frequency : 0, 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid && ssid->passphrase ? ssid->passphrase : "", 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_dev_addr), 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent ? " [PERSISTENT]" : ""); 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_cross_connect_setup(wpa_s); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (persistent) 73575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = wpas_p2p_store_persistent_group(wpa_s->parent, 73675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ssid, go_dev_addr); 7371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (network_id < 0 && ssid) 73875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = ssid->id; 73975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!client) 74075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0); 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s, 7451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt unsigned int freq, 7461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *dst, const u8 *src, 7471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *bssid, 7481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *data, size_t data_len, 7491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt enum offchannel_send_action_result 7501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt result) 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt enum p2p_send_action_result res = P2P_SEND_ACTION_SUCCESS; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (result) { 7601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OFFCHANNEL_SEND_ACTION_SUCCESS: 7611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = P2P_SEND_ACTION_SUCCESS; 7621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 7631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OFFCHANNEL_SEND_ACTION_NO_ACK: 7641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = P2P_SEND_ACTION_NO_ACK; 7651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 7661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OFFCHANNEL_SEND_ACTION_FAILED: 7671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = P2P_SEND_ACTION_FAILED; 7681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res); 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 773c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (result != OFFCHANNEL_SEND_ACTION_SUCCESS && 774c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->pending_pd_before_join && 7751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 || 776d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0) && 777d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->p2p_fallback_to_go_neg) { 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 779d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req " 780d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "during p2p_connect-auto"); 781d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_fallback_to_go_neg(wpa_s, 0); 782d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst, 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, const u8 *bssid, const u8 *buf, 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, unsigned int wait_time) 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 7921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len, 7931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wait_time, 7941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_send_action_tx_status, 1); 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_send_action_done(void *ctx) 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 8011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt offchannel_send_action_done(wpa_s); 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_copy_go_neg_results(struct wpa_supplicant *wpa_s, 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *params) 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->go_params == NULL) { 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->go_params = os_malloc(sizeof(*params)); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->go_params == NULL) 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->go_params, params, sizeof(*params)); 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s, 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *res) 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Start WPS Enrollee for peer " MACSTR, 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(res->peer_interface_addr)); 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Start WPS Enrollee for SSID", 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->ssid, res->ssid_len); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_deinit(wpa_s); 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_copy_go_neg_results(wpa_s, res); 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->wps_method == WPS_PBC) 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1); 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 dev_pw_id = DEV_PW_DEFAULT; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD) 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_wps_start_pin(wpa_s, res->peer_interface_addr, 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_pin, 1, dev_pw_id); 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_go_configured(void *ctx, void *data) 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *params = data; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 84475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int network_id = -1; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_P2P_GO) { 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning"); 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_group_formation == wpa_s) 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 851a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (os_strlen(params->passphrase) > 0) { 852a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 853a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "%s GO ssid=\"%s\" freq=%d passphrase=\"%s\" " 854a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "go_dev_addr=" MACSTR "%s", wpa_s->ifname, 855a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len), 856a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ssid->frequency, params->passphrase, 857a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt MAC2STR(wpa_s->global->p2p_dev_addr), 858a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt params->persistent_group ? " [PERSISTENT]" : 859a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ""); 860a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 861a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt char psk[65]; 862a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_snprintf_hex(psk, sizeof(psk), params->psk, 863a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(params->psk)); 864a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 865a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "%s GO ssid=\"%s\" freq=%d psk=%s " 866a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "go_dev_addr=" MACSTR "%s", wpa_s->ifname, 867a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len), 868a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ssid->frequency, psk, 869a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt MAC2STR(wpa_s->global->p2p_dev_addr), 870a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt params->persistent_group ? " [PERSISTENT]" : 871a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ""); 872a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 8731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->persistent_group) 87575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = wpas_p2p_store_persistent_group( 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent, ssid, 877497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt wpa_s->global->p2p_dev_addr); 87875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (network_id < 0) 87975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = ssid->id; 88075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0); 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_cross_connect_setup(wpa_s); 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Setting up WPS for GO provisioning"); 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_ap_mac_addr_filter(wpa_s, 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->peer_interface_addr)) { 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to setup MAC address " 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "filtering"); 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wps_method == WPS_PBC) 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr, 8951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->peer_device_addr); 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_s->p2p_pin[0]) 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr, 898d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->p2p_pin, NULL, 0, 0); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->go_params); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->go_params = NULL; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_start_wps_go(struct wpa_supplicant *wpa_s, 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results *params, 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int group_formation) 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 910aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Starting GO"); 911aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (wpas_copy_go_neg_results(wpa_s, params) < 0) { 912aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not copy GO Negotiation " 913aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "results"); 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 915aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_config_add_network(wpa_s->conf); 918aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (ssid == NULL) { 919aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not add network for GO"); 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 921aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->show_group_started = 0; 9241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_network_defaults(ssid); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->temporary = 1; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->p2p_group = 1; 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->p2p_persistent_group = params->persistent_group; 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION : 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPAS_MODE_P2P_GO; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->frequency = params->freq; 93261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ssid->ht40 = params->ht40; 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid = os_zalloc(params->ssid_len + 1); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->ssid) { 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid->ssid, params->ssid, params->ssid_len); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len = params->ssid_len; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->auth_alg = WPA_AUTH_ALG_OPEN; 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->key_mgmt = WPA_KEY_MGMT_PSK; 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->proto = WPA_PROTO_RSN; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->pairwise_cipher = WPA_CIPHER_CCMP; 942a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (os_strlen(params->passphrase) > 0) { 943a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ssid->passphrase = os_strdup(params->passphrase); 944a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (ssid->passphrase == NULL) { 945a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_msg(wpa_s, MSG_ERROR, "P2P: Failed to copy " 946a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "passphrase for GO"); 947a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, ssid->id); 948a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return; 949a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 950a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else 951a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ssid->passphrase = NULL; 952d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid->psk_set = params->psk_set; 953d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (ssid->psk_set) 954d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(ssid->psk, params->psk, sizeof(ssid->psk)); 955a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else if (ssid->passphrase) 956d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_config_update_psk(ssid); 95761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ssid->ap_max_inactivity = wpa_s->parent->conf->p2p_go_max_inactivity; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ap_configured_cb = p2p_go_configured; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ap_configured_cb_ctx = wpa_s; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ap_configured_cb_data = wpa_s->go_params; 96275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->connect_without_scan = ssid; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->reassociate = 1; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->disconnected = 0; 965aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Request scan (that will be skipped) to " 966aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "start GO)"); 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 0, 0); 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_clone_config(struct wpa_supplicant *dst, 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_supplicant *src) 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_config *d; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_config *s; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d = dst->conf; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = src->conf; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define C(n) if (s->n) d->n = os_strdup(s->n) 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(device_name); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(manufacturer); 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(model_name); 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(model_number); 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(serial_number); 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C(config_methods); 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef C 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN); 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(d->sec_device_type, s->sec_device_type, 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(d->sec_device_type)); 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d->num_sec_device_types = s->num_sec_device_types; 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d->p2p_group_idle = s->p2p_group_idle; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d->p2p_intra_bss = s->p2p_intra_bss; 9961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt d->persistent_reconnect = s->persistent_reconnect; 99704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt d->max_num_sta = s->max_num_sta; 99804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt d->pbc_in_m1 = s->pbc_in_m1; 999444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt d->ignore_old_scan_res = s->ignore_old_scan_res; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s, 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_driver_if_type type) 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char ifname[120], force_ifname[120]; 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->pending_interface_name[0]) { 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Pending virtual interface exists " 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "- skip creation of a new one"); 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_zero_ether_addr(wpa_s->pending_interface_addr)) { 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Pending virtual address " 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unknown?! ifname='%s'", 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name); 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(ifname, sizeof(ifname), "p2p-%s-%d", wpa_s->ifname, 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group_idx); 10221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_strlen(ifname) >= IFNAMSIZ && 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(wpa_s->ifname) < IFNAMSIZ) { 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to avoid going over the IFNAMSIZ length limit */ 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(ifname, sizeof(ifname), "p2p-%d", 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group_idx); 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_ifname[0] = '\0'; 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group", 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group_idx++; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_type = type; 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_if_add(wpa_s, type, ifname, NULL, NULL, force_ifname, 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_addr, NULL) < 0) { 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to create new group " 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface"); 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_ifname[0]) { 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s", 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_ifname); 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->pending_interface_name, force_ifname, 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->pending_interface_name)); 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->pending_interface_name, ifname, 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->pending_interface_name)); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Created pending virtual interface %s addr " 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, wpa_s->pending_interface_name, 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_interface_addr)); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_remove_pending_group_interface( 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s) 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->pending_interface_name[0] || 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt is_zero_ether_addr(wpa_s->pending_interface_addr)) 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* No pending virtual interface */ 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Removing pending group interface %s", 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name); 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_if_remove(wpa_s, wpa_s->pending_interface_type, 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name); 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN); 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go) 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_interface iface; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group_wpa_s; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->pending_interface_name[0]) { 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: No pending group interface"); 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpas_p2p_create_iface(wpa_s)) 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Something has forced us to remove the pending interface; try 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to create a new one and hope for the best that we will get 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the same local address. 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO : 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_IF_P2P_CLIENT) < 0) 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&iface, 0, sizeof(iface)); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.ifname = wpa_s->pending_interface_name; 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.driver = wpa_s->driver->name; 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.ctrl_interface = wpa_s->conf->ctrl_interface; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface.driver_param = wpa_s->conf->driver_param; 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface); 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s == NULL) { 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to create new " 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "wpa_supplicant interface"); 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->parent = wpa_s; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->p2p_group_interface = go ? P2P_GROUP_INTERFACE_GO : 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_GROUP_INTERFACE_CLIENT; 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = group_wpa_s; 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clone_config(group_wpa_s, wpa_s); 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group_wpa_s; 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_formation_timeout(void *eloop_ctx, 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *timeout_ctx) 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out"); 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_formation_failed(wpa_s->global->p2p); 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_p2p_group_formation_failed(wpa_s); 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_group_formation_completed(wpa_s, 0); 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res) 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_cancel_remain_on_channel(wpa_s); 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->off_channel_freq = 0; 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->roc_waiting_drv_freq = 0; 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->status) { 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_FAILURE "status=%d", 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->status); 11431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_notify_p2p_go_neg_completed(wpa_s, res); 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 114861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->p2p_go_ht40) 114961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res->ht40 = 1; 115061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS); 11521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_notify_p2p_go_neg_completed(wpa_s, res); 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 115404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (res->role_go && wpa_s->p2p_persistent_id >= 0) { 115504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid; 115604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, 115704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id); 115804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid && ssid->disabled == 2 && 115904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->mode == WPAS_MODE_P2P_GO && ssid->passphrase) { 116004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t len = os_strlen(ssid->passphrase); 116104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Override passphrase based " 116204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "on requested persistent group"); 116304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(res->passphrase, ssid->passphrase, len); 116404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res->passphrase[len] = '\0'; 116504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 116604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 116704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->create_p2p_iface) { 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group_wpa_s = 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_init_group_interface(wpa_s, res->role_go); 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s == NULL) { 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s != wpa_s) { 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_wpa_s->p2p_pin, wpa_s->p2p_pin, 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(group_wpa_s->p2p_pin)); 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->p2p_wps_method = wpa_s->p2p_wps_method; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN); 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_interface_name[0] = '\0'; 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s->p2p_in_provisioning = 1; 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->role_go) 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(group_wpa_s, res, 1); 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_enrollee(group_wpa_s, res); 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_in_provisioning = 1; 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = wpa_s; 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->role_go) 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(wpa_s, res, 1); 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_enrollee(ctx, res); 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(15 + res->peer_config_timeout / 100, 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (res->peer_config_timeout % 100) * 10000, 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_formation_timeout, wpa_s, NULL); 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id) 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_REQUEST MACSTR 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_passwd_id=%u", MAC2STR(src), dev_passwd_id); 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id); 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_dev_found(void *ctx, const u8 *addr, 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_peer_info *info, 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int new_device) 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 12258367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#define WFD_DEV_INFO_SIZE 9 12268367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff char wfd_dev_info_hex[2 * WFD_DEV_INFO_SIZE + 1]; 12278d96518810ad721dc2f07d3b08a186ce23db06ffIrfan Sheriff os_memset(wfd_dev_info_hex, 0, sizeof(wfd_dev_info_hex)); 12288367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#ifdef CONFIG_WIFI_DISPLAY 12298367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff if (info->wfd_subelems) { 12308367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff wpa_snprintf_hex(wfd_dev_info_hex, sizeof(wfd_dev_info_hex), 12318367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff wpabuf_head(info->wfd_subelems), 12328367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff WFD_DEV_INFO_SIZE); 12338367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff } 12348367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff#endif /* CONFIG_WIFI_DISPLAY */ 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " p2p_dev_addr=" MACSTR 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " pri_dev_type=%s name='%s' config_methods=0x%x " 12388367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff "dev_capab=0x%x group_capab=0x%x%s%s", 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr), MAC2STR(info->p2p_device_addr), 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(info->pri_dev_type, devtype, 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype)), 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info->device_name, info->config_methods, 12438367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff info->dev_capab, info->group_capab, 12448367dc909f536f600c7474582fe0a96bef7c78fcIrfan Sheriff wfd_dev_info_hex[0] ? " wfd_dev_info=0x" : "", wfd_dev_info_hex); 12451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device); 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_dev_lost(void *ctx, const u8 *dev_addr) 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 12541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1255497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST 1256497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt "p2p_dev_addr=" MACSTR, MAC2STR(dev_addr)); 12571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_device_lost(wpa_s, dev_addr); 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_start_listen(void *ctx, unsigned int freq, 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int duration, 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *probe_resp_ie) 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_set_ap_wps_ie(wpa_s, NULL, probe_resp_ie, NULL); 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_probe_req_report(wpa_s, 1) < 0) { 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to " 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "report received Probe Request frames"); 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_freq = freq; 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_duration = duration; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_remain_on_channel(wpa_s, freq, duration) < 0) { 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver " 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to remain on channel (%u MHz) for Listen " 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state", freq); 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_freq = 0; 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->off_channel_freq = 0; 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->roc_waiting_drv_freq = freq; 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_stop_listen(void *ctx) 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_cancel_remain_on_channel(wpa_s); 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->off_channel_freq = 0; 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->roc_waiting_drv_freq = 0; 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_set_ap_wps_ie(wpa_s, NULL, NULL, NULL); 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_probe_req_report(wpa_s, 0); 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_send_probe_resp(void *ctx, const struct wpabuf *buf) 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 13091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1); 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1313d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/* 1314d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * DNS Header section is used only to calculate compression pointers, so the 1315d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * contents of this data does not matter, but the length needs to be reserved 1316d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * in the virtual packet. 1317d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 1318d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#define DNS_HEADER_LEN 12 1319d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1320d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/* 1321d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * 27-octet in-memory packet from P2P specification containing two implied 1322d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * queries for _tcp.lcoal. PTR IN and _udp.local. PTR IN 1323d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 1324d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#define P2P_SD_IN_MEMORY_LEN 27 1325d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1326d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int p2p_sd_dns_uncompress_label(char **upos, char *uend, u8 *start, 1327d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u8 **spos, const u8 *end) 1328d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 1329d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt while (*spos < end) { 1330d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u8 val = ((*spos)[0] & 0xc0) >> 6; 1331d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int len; 1332d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1333d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (val == 1 || val == 2) { 1334d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* These are reserved values in RFC 1035 */ 1335d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid domain name " 1336d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "sequence starting with 0x%x", val); 1337d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1338d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1339d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1340d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (val == 3) { 1341d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u16 offset; 1342d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u8 *spos_tmp; 1343d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1344d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Offset */ 1345d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (*spos + 2 > end) { 1346d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No room for full " 1347d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "DNS offset field"); 1348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1349d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1350d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1351d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt offset = (((*spos)[0] & 0x3f) << 8) | (*spos)[1]; 1352d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (offset >= *spos - start) { 1353d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid DNS " 1354d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "pointer offset %u", offset); 1355d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1356d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1357d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1358d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*spos) += 2; 1359d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt spos_tmp = start + offset; 1360d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return p2p_sd_dns_uncompress_label(upos, uend, start, 1361d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt &spos_tmp, 1362d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *spos - 2); 1363d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1364d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1365d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Label */ 1366d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt len = (*spos)[0] & 0x3f; 1367d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (len == 0) 1368d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 1369d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1370d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*spos)++; 1371d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (*spos + len > end) { 1372d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid domain name " 1373d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "sequence - no room for label with length " 1374d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "%u", len); 1375d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1376d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1377d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1378d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (*upos + len + 2 > uend) 1379d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -2; 1380d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1381d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(*upos, *spos, len); 1382d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *spos += len; 1383d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *upos += len; 1384d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*upos)[0] = '.'; 1385d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*upos)++; 1386d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (*upos)[0] = '\0'; 1387d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1388d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1389d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 1390d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 1391d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1392d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1393d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/* Uncompress domain names per RFC 1035 using the P2P SD in-memory packet. 1394d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * Returns -1 on parsing error (invalid input sequence), -2 if output buffer is 1395d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * not large enough */ 1396d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int p2p_sd_dns_uncompress(char *buf, size_t buf_len, const u8 *msg, 1397d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt size_t msg_len, size_t offset) 1398d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 1399d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 27-octet in-memory packet from P2P specification */ 1400d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const char *prefix = "\x04_tcp\x05local\x00\x00\x0C\x00\x01" 1401d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "\x04_udp\xC0\x11\x00\x0C\x00\x01"; 1402d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u8 *tmp, *end, *spos; 1403d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt char *upos, *uend; 1404d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int ret = 0; 1405d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1406d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (buf_len < 2) 1407d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1408d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (offset > msg_len) 1409d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1410d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1411d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt tmp = os_malloc(DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN + msg_len); 1412d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (tmp == NULL) 1413d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 1414d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt spos = tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN; 1415d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt end = spos + msg_len; 1416d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt spos += offset; 1417d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1418d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memset(tmp, 0, DNS_HEADER_LEN); 1419d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(tmp + DNS_HEADER_LEN, prefix, P2P_SD_IN_MEMORY_LEN); 1420d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN, msg, msg_len); 1421d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1422d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt upos = buf; 1423d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt uend = buf + buf_len; 1424d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1425d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ret = p2p_sd_dns_uncompress_label(&upos, uend, tmp, &spos, end); 1426d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (ret) { 1427d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(tmp); 1428d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return ret; 1429d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1430d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1431d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (upos == buf) { 1432d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt upos[0] = '.'; 1433d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt upos[1] = '\0'; 1434d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else if (upos[-1] == '.') 1435d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt upos[-1] = '\0'; 1436d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1437d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(tmp); 1438d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 1439d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 1440d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1441d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_srv_bonjour * 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_service_get_bonjour(struct wpa_supplicant *wpa_s, 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *query) 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = wpabuf_len(query); 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour, 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour, list) { 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len == wpabuf_len(bsrv->query) && 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(wpabuf_head(query), wpabuf_head(bsrv->query), 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len) == 0) 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return bsrv; 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct p2p_srv_upnp * 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_service_get_upnp(struct wpa_supplicant *wpa_s, u8 version, 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *service) 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp, 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp, list) { 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (version == usrv->version && 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(service, usrv->service) == 0) 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return usrv; 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_add_proto_not_avail(struct wpabuf *resp, u8 srv_proto, 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_trans_id) 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 5) 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Length (to be filled) */ 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_proto); 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_PROTO_NOT_AVAILABLE); 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data: empty */ 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2); 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_all_bonjour(struct wpa_supplicant *wpa_s, 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id) 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: SD Request for all Bonjour services"); 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) { 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available"); 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour, 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour, list) { 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5 + wpabuf_len(bsrv->query) + wpabuf_len(bsrv->resp)) 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Length (to be filled) */ 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_BONJOUR); 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service", 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(bsrv->resp), 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(bsrv->resp)); 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data */ 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(resp, bsrv->query); /* Key */ 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(resp, bsrv->resp); /* Value */ 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2); 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1532d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int match_bonjour_query(struct p2p_srv_bonjour *bsrv, const u8 *query, 1533d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt size_t query_len) 1534d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 1535d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt char str_rx[256], str_srv[256]; 1536d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1537d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (query_len < 3 || wpabuf_len(bsrv->query) < 3) 1538d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* Too short to include DNS Type and Version */ 1539d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (os_memcmp(query + query_len - 3, 1540d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_head_u8(bsrv->query) + wpabuf_len(bsrv->query) - 3, 1541d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3) != 0) 1542d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* Mismatch in DNS Type or Version */ 1543d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (query_len == wpabuf_len(bsrv->query) && 1544d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcmp(query, wpabuf_head(bsrv->query), query_len - 3) == 0) 1545d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; /* Binary match */ 1546d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1547d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p_sd_dns_uncompress(str_rx, sizeof(str_rx), query, query_len - 3, 1548d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 0)) 1549d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* Failed to uncompress query */ 1550d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (p2p_sd_dns_uncompress(str_srv, sizeof(str_srv), 1551d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_head(bsrv->query), 1552d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_len(bsrv->query) - 3, 0)) 1553d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* Failed to uncompress service */ 1554d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1555d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return os_strcmp(str_rx, str_srv) == 0; 1556d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 1557d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1558d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_req_bonjour(struct wpa_supplicant *wpa_s, 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id, 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *query, size_t query_len) 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 1565d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int matches = 0; 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for Bonjour", 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query, query_len); 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) { 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available"); 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_add_proto_not_avail(resp, P2P_SERV_BONJOUR, 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (query_len == 0) { 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id); 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1581d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour, 1582d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct p2p_srv_bonjour, list) { 1583d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!match_bonjour_query(bsrv, query, query_len)) 1584d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt continue; 1585d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1586d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpabuf_tailroom(resp) < 1587d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5 + query_len + wpabuf_len(bsrv->resp)) 1588d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 1589d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1590d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt matches++; 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1592d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Length (to be filled) */ 1593d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt len_pos = wpabuf_put(resp, 2); 1594d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_BONJOUR); 1595d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 1596d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1597d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Status Code */ 1598d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); 1599d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service", 1600d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_head(bsrv->resp), 1601d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_len(bsrv->resp)); 1602d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1603d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Response Data */ 1604d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_data(resp, query, query_len); /* Key */ 1605d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_buf(resp, bsrv->resp); /* Value */ 1606d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1607d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2); 1608d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1609d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1610d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (matches == 0) { 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Requested Bonjour service not " 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available"); 1613d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpabuf_tailroom(resp) < 5) 1614d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 1615d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 1616d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Length (to be filled) */ 1617d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt len_pos = wpabuf_put(resp, 2); 1618d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_BONJOUR); 1619d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE); 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data: empty */ 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2); 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_all_upnp(struct wpa_supplicant *wpa_s, 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id) 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: SD Request for all UPnP services"); 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) { 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available"); 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp, 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp, list) { 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 5 + 1 + os_strlen(usrv->service)) 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Length (to be filled) */ 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_UPNP); 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data */ 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, usrv->version); 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s", 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv->service); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_str(resp, usrv->service); 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2); 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_sd_req_upnp(struct wpa_supplicant *wpa_s, 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id, 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *query, size_t query_len) 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len_pos; 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 version; 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *str; 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count = 0; 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for UPnP", 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt query, query_len); 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) { 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available"); 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_add_proto_not_avail(resp, P2P_SERV_UPNP, 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (query_len == 0) { 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_upnp(wpa_s, resp, srv_trans_id); 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 5) 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Length (to be filled) */ 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_UPNP); 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt version = query[0]; 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = os_malloc(query_len); 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (str == NULL) 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(str, query + 1, query_len - 1); 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str[query_len - 1] = '\0'; 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp, 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp, list) { 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (version != usrv->version) 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(str, "ssdp:all") != 0 && 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strstr(usrv->service, str) == NULL) 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < 2) 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count == 0) { 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data */ 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, version); 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, ','); 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s", 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv->service); 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_tailroom(resp) < os_strlen(usrv->service)) 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_str(resp, usrv->service); 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(str); 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count == 0) { 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Requested UPnP service not " 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available"); 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Status Code */ 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE); 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Response Data: empty */ 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2); 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 174761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 174861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void wpas_sd_req_wfd(struct wpa_supplicant *wpa_s, 174961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *resp, u8 srv_trans_id, 175061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *query, size_t query_len) 175161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 175261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *pos; 175361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 role; 175461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len_pos; 175561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 175661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: SD Request for WFD", query, query_len); 175761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 175861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!wpa_s->global->wifi_display) { 175961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: WFD protocol not available"); 176061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_sd_add_proto_not_avail(resp, P2P_SERV_WIFI_DISPLAY, 176161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt srv_trans_id); 176261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 176361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 176461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 176561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (query_len < 1) { 176661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Missing WFD Requested Device " 176761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "Role"); 176861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 176961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 177061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 177161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpabuf_tailroom(resp) < 5) 177261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 177361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 177461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = query; 177561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt role = *pos++; 177661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: WSD for device role 0x%x", role); 177761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 177861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* TODO: role specific handling */ 177961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 178061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Length (to be filled) */ 178161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len_pos = wpabuf_put(resp, 2); 178261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(resp, P2P_SERV_WIFI_DISPLAY); 178361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(resp, srv_trans_id); 178461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(resp, P2P_SD_SUCCESS); /* Status Code */ 178561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 178661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (pos < query + query_len) { 178761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*pos < MAX_WFD_SUBELEMS && 178861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->global->wfd_subelem[*pos] && 178961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_tailroom(resp) >= 179061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(wpa_s->global->wfd_subelem[*pos])) { 179161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Add WSD response " 179261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "subelement %u", *pos); 179361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(resp, wpa_s->global->wfd_subelem[*pos]); 179461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 179561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 179661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 179761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 179861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2); 179961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 180061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 180161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 180261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token, 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 update_indic, const u8 *tlvs, size_t tlvs_len) 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = tlvs; 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end = tlvs + tlvs_len; 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *tlv_end; 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 slen; 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_proto, srv_trans_id; 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buf_len; 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf; 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Request TLVs", 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlvs, tlvs_len); 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf_len = 2 * tlvs_len + 1; 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(buf_len); 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf) { 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len); 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_ctrl(wpa_s, MSG_INFO, P2P_EVENT_SERV_DISC_REQ "%d " 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " %u %u %s", 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq, MAC2STR(sa), dialog_token, update_indic, 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf); 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->p2p_sd_over_ctrl_iface) { 18301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token, 18311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt update_indic, tlvs, tlvs_len); 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* to be processed by an external program */ 18331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_alloc(10000); 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Request TLV"); 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt slen = WPA_GET_LE16(pos); 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + slen > end || slen < 2) { 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unexpected Query Data " 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length"); 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv_end = pos + slen; 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_proto = *pos++; 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u", 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_proto); 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id = *pos++; 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u", 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Query Data", 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, tlv_end - pos); 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->force_long_sd) { 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: SD test - force long " 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "response"); 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id); 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_upnp(wpa_s, resp, srv_trans_id); 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto done; 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (srv_proto) { 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SERV_ALL_SERVICES: 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Discovery Request " 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for all services"); 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dl_list_empty(&wpa_s->global->p2p_srv_upnp) && 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) { 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No service " 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "discovery protocols available"); 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_add_proto_not_avail( 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp, P2P_SERV_ALL_SERVICES, 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id); 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_all_upnp(wpa_s, resp, srv_trans_id); 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SERV_BONJOUR: 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_req_bonjour(wpa_s, resp, srv_trans_id, 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, tlv_end - pos); 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_SERV_UPNP: 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_req_upnp(wpa_s, resp, srv_trans_id, 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, tlv_end - pos); 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 189461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 189561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case P2P_SERV_WIFI_DISPLAY: 189661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_sd_req_wfd(wpa_s, resp, srv_trans_id, 189761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos, tlv_end - pos); 189861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 189961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unavailable service " 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "protocol %u", srv_proto); 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_sd_add_proto_not_avail(resp, srv_proto, 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = tlv_end; 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdone: 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token, 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt update_indic, tlvs, tlvs_len); 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_response(wpa_s, freq, sa, dialog_token, resp); 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_sd_response(void *ctx, const u8 *sa, u16 update_indic, 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *tlvs, size_t tlvs_len) 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = tlvs; 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end = tlvs + tlvs_len; 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *tlv_end; 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 slen; 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buf_len; 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf; 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Response TLVs", 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlvs, tlvs_len); 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlvs_len > 1500) { 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: better way for handling this */ 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_ctrl(wpa_s, MSG_INFO, 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_SERV_DISC_RESP MACSTR 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " %u <long response: %u bytes>", 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), update_indic, 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) tlvs_len); 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf_len = 2 * tlvs_len + 1; 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(buf_len); 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf) { 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len); 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_ctrl(wpa_s, MSG_INFO, 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_SERV_DISC_RESP MACSTR " %u %s", 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), update_indic, buf); 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_proto, srv_trans_id, status; 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Response TLV"); 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt slen = WPA_GET_LE16(pos); 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + slen > end || slen < 3) { 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unexpected Response Data " 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length"); 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlv_end = pos + slen; 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_proto = *pos++; 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u", 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_proto); 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id = *pos++; 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u", 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt srv_trans_id); 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = *pos++; 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Status Code ID %u", 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status); 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Response Data", 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, tlv_end - pos); 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = tlv_end; 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_sd_response(wpa_s, sa, update_indic, tlvs, tlvs_len); 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu64 wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst, 19871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const struct wpabuf *tlvs) 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 19901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return wpa_drv_p2p_sd_request(wpa_s, dst, tlvs); 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 19921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 19931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return (uintptr_t) p2p_sd_request(wpa_s->global->p2p, dst, tlvs); 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtu64 wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst, 19981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 version, const char *query) 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *tlvs; 20011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u64 ret; 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlvs = wpabuf_alloc(2 + 1 + 1 + 1 + os_strlen(query)); 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlvs == NULL) 20051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_le16(tlvs, 1 + 1 + 1 + os_strlen(query)); 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(tlvs, P2P_SERV_UPNP); /* Service Protocol Type */ 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(tlvs, 1); /* Service Transaction ID */ 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(tlvs, version); 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_str(tlvs, query); 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = wpas_p2p_sd_request(wpa_s, dst, tlvs); 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tlvs); 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 201761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 201861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 201961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic u64 wpas_p2p_sd_request_wfd(struct wpa_supplicant *wpa_s, const u8 *dst, 202061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpabuf *tlvs) 202161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 202261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 202361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 202461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 202561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 202661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return (uintptr_t) p2p_sd_request_wfd(wpa_s->global->p2p, dst, tlvs); 202761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 202861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 202961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 203061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#define MAX_WFD_SD_SUBELEMS 20 203161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 203261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void wfd_add_sd_req_role(struct wpabuf *tlvs, u8 id, u8 role, 203361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *subelems) 203461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 203561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *len; 203661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *pos; 203761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int val; 203861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int count = 0; 203961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 204061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len = wpabuf_put(tlvs, 2); 204161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(tlvs, P2P_SERV_WIFI_DISPLAY); /* Service Protocol Type */ 204261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(tlvs, id); /* Service Transaction ID */ 204361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 204461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(tlvs, role); 204561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 204661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = subelems; 204761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (*pos) { 204861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = atoi(pos); 204961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (val >= 0 && val < 256) { 205061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_u8(tlvs, val); 205161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt count++; 205261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (count == MAX_WFD_SD_SUBELEMS) 205361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 205461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 205561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = os_strchr(pos + 1, ','); 205661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL) 205761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 205861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 205961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 206061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 206161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WPA_PUT_LE16(len, (u8 *) wpabuf_put(tlvs, 0) - len - 2); 206261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 206361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 206461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 206561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtu64 wpas_p2p_sd_request_wifi_display(struct wpa_supplicant *wpa_s, 206661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *dst, const char *role) 206761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 206861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *tlvs; 206961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u64 ret; 207061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *subelems; 207161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 id = 1; 207261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 207361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt subelems = os_strchr(role, ' '); 207461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (subelems == NULL) 207561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 207661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt subelems++; 207761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 207861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tlvs = wpabuf_alloc(4 * (2 + 1 + 1 + 1 + MAX_WFD_SD_SUBELEMS)); 207961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (tlvs == NULL) 208061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 208161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 208261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(role, "[source]")) 208361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_add_sd_req_role(tlvs, id++, 0x00, subelems); 208461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(role, "[pri-sink]")) 208561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_add_sd_req_role(tlvs, id++, 0x01, subelems); 208661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(role, "[sec-sink]")) 208761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_add_sd_req_role(tlvs, id++, 0x02, subelems); 208861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(role, "[source+sink]")) 208961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_add_sd_req_role(tlvs, id++, 0x03, subelems); 209061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 209161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ret = wpas_p2p_sd_request_wfd(wpa_s, dst, tlvs); 209261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(tlvs); 209361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return ret; 209461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 209561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 209661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 209761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 209861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 20991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, u64 req) 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 21021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return wpa_drv_p2p_sd_cancel_request(wpa_s, req); 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_sd_cancel_request(wpa_s->global->p2p, 21061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (void *) (uintptr_t) req); 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_sd_response(struct wpa_supplicant *wpa_s, int freq, 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dst, u8 dialog_token, 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *resp_tlvs) 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_p2p_sd_response(wpa_s, freq, dst, dialog_token, 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_tlvs); 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_response(wpa_s->global->p2p, freq, dst, dialog_token, 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_tlvs); 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2125b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#ifdef ANDROID_P2P 2126b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidtvoid wpas_p2p_sd_service_update(struct wpa_supplicant *wpa_s, int action) 2127b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#else 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_sd_service_update(struct wpa_supplicant *wpa_s) 2129b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#endif 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_p2p_service_update(wpa_s); 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 2136b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#ifdef ANDROID_P2P 2137b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt p2p_sd_service_update(wpa_s->global->p2p, action); 2138b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#else 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_sd_service_update(wpa_s->global->p2p); 2140b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#endif 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_srv_bonjour_free(struct p2p_srv_bonjour *bsrv) 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&bsrv->list); 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(bsrv->query); 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(bsrv->resp); 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(bsrv); 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_srv_upnp_free(struct p2p_srv_upnp *usrv) 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&usrv->list); 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(usrv->service); 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(usrv); 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_service_flush(struct wpa_supplicant *wpa_s) 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv, *bn; 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv, *un; 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(bsrv, bn, &wpa_s->global->p2p_srv_bonjour, 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour, list) 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_srv_bonjour_free(bsrv); 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each_safe(usrv, un, &wpa_s->global->p2p_srv_upnp, 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp, list) 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_srv_upnp_free(usrv); 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2174b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#ifdef ANDROID_P2P 2175b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s, SRV_FLUSH); 2176b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#else 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 2178b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#endif 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_service_add_bonjour(struct wpa_supplicant *wpa_s, 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *query, struct wpabuf *resp) 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bsrv = os_zalloc(sizeof(*bsrv)); 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bsrv == NULL) 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bsrv->query = query; 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bsrv->resp = resp; 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&wpa_s->global->p2p_srv_bonjour, &bsrv->list); 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2194b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#ifdef ANDROID_P2P 2195b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s, SRV_ADD); 2196b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#else 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 2198b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#endif 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_service_del_bonjour(struct wpa_supplicant *wpa_s, 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *query) 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_bonjour *bsrv; 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bsrv = wpas_p2p_service_get_bonjour(wpa_s, query); 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bsrv == NULL) 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_srv_bonjour_free(bsrv); 2212b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#ifdef ANDROID_P2P 2213b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s, SRV_DEL); 2214b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#else 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 2216b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#endif 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_service_add_upnp(struct wpa_supplicant *wpa_s, u8 version, 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *service) 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_service_get_upnp(wpa_s, version, service)) 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Already listed */ 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv = os_zalloc(sizeof(*usrv)); 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (usrv == NULL) 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv->version = version; 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv->service = os_strdup(service); 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (usrv->service == NULL) { 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(usrv); 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&wpa_s->global->p2p_srv_upnp, &usrv->list); 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2239b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#ifdef ANDROID_P2P 2240b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s, SRV_ADD); 2241b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#else 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 2243b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#endif 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version, 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *service) 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_srv_upnp *usrv; 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usrv = wpas_p2p_service_get_upnp(wpa_s, version, service); 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (usrv == NULL) 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_srv_upnp_free(usrv); 2257b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#ifdef ANDROID_P2P 2258b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s, SRV_DEL); 2259b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#else 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_sd_service_update(wpa_s); 2261b5e8f06e18446918f6d801566e5709a8c87f1780Dmitry Shmidt#endif 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_prov_disc_local_display(struct wpa_supplicant *wpa_s, 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer, const char *params, 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int generated_pin) 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_SHOW_PIN MACSTR " %08d%s", 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer), generated_pin, params); 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_prov_disc_local_keypad(struct wpa_supplicant *wpa_s, 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer, const char *params) 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_ENTER_PIN MACSTR "%s", 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer), params); 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods, 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dev_addr, const u8 *pri_dev_type, 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *dev_name, u16 supp_config_methods, 22861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 dev_capab, u8 group_capab, const u8 *group_id, 22871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t group_id_len) 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 22911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char params[300]; 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 empty_dev_type[8]; 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int generated_pin = 0; 22941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *group = NULL; 22951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 22961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (group_id) { 22971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (group = wpa_s->global->ifaces; group; group = group->next) 22981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt { 22991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *s = group->current_ssid; 23001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s != NULL && 23011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt s->mode == WPAS_MODE_P2P_GO && 23021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group_id_len - ETH_ALEN == s->ssid_len && 23031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(group_id + ETH_ALEN, s->ssid, 23041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt s->ssid_len) == 0) 23051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 23061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 23071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pri_dev_type == NULL) { 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(empty_dev_type, 0, sizeof(empty_dev_type)); 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pri_dev_type = empty_dev_type; 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(params, sizeof(params), " p2p_dev_addr=" MACSTR 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " pri_dev_type=%s name='%s' config_methods=0x%x " 23151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "dev_capab=0x%x group_capab=0x%x%s%s", 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev_addr), 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(pri_dev_type, devtype, 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype)), 23191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev_name, supp_config_methods, dev_capab, group_capab, 23201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group ? " group=" : "", 23211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt group ? group->ifname : ""); 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params[sizeof(params) - 1] = '\0'; 2323c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config_methods & WPS_CONFIG_DISPLAY) { 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generated_pin = wps_generate_pin(); 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_prov_disc_local_display(wpa_s, peer, params, 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generated_pin); 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (config_methods & WPS_CONFIG_KEYPAD) 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_prov_disc_local_keypad(wpa_s, peer, params); 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (config_methods & WPS_CONFIG_PUSHBUTTON) 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_REQ MACSTR 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", MAC2STR(peer), params); 233375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 233475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_provision_discovery(wpa_s, peer, 1 /* request */, 233575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_SUCCESS, 233675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen config_methods, generated_pin); 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods) 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int generated_pin = 0; 234404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char params[20]; 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2346c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (wpa_s->pending_pd_before_join && 2347c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 || 2348c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) { 2349c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 2350c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Starting pending " 2351c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "join-existing-group operation"); 2352c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpas_p2p_join_start(wpa_s); 2353c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return; 2354c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 2355c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 235604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->pending_pd_use == AUTO_PD_JOIN || 235704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use == AUTO_PD_GO_NEG) 235804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_snprintf(params, sizeof(params), " peer_go=%d", 235904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use == AUTO_PD_JOIN); 236004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 236104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params[0] = '\0'; 236204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config_methods & WPS_CONFIG_DISPLAY) 236404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_prov_disc_local_keypad(wpa_s, peer, params); 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (config_methods & WPS_CONFIG_KEYPAD) { 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generated_pin = wps_generate_pin(); 236704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_prov_disc_local_display(wpa_s, peer, params, 236804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt generated_pin); 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (config_methods & WPS_CONFIG_PUSHBUTTON) 237004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP MACSTR 237104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "%s", MAC2STR(peer), params); 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 237375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */, 237475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_SUCCESS, 237575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen config_methods, generated_pin); 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_prov_disc_fail(void *ctx, const u8 *peer, 23801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt enum p2p_prov_disc_status status) 238175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 238275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct wpa_supplicant *wpa_s = ctx; 238375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 238404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_fallback_to_go_neg) { 238504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: PD for p2p_connect-auto " 238604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "failed - fall back to GO Negotiation"); 238704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_fallback_to_go_neg(wpa_s, 0); 238804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 238904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 239004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2391d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (status == P2P_PROV_DISC_TIMEOUT_JOIN) { 23922b380488c6b5d21e54e98397c7a8d6a9f16dd8b5Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 2393d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Starting pending " 2394d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "join-existing-group operation (no ACK for PD " 2395d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "Req attempts)"); 2396d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_join_start(wpa_s); 2397d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 23982b380488c6b5d21e54e98397c7a8d6a9f16dd8b5Dmitry Shmidt } 2399d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 240004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE 240104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " p2p_dev_addr=" MACSTR " status=%d", 240204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(peer), status); 240304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 240475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */, 240575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen status, 0, 0); 240675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 240775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 240875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid, 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_dev_addr, const u8 *ssid, 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ssid_len, int *go, u8 *group_bssid, 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int *force_freq, int persistent_group) 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 cur_bssid[ETH_ALEN]; 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *grp; 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!persistent_group) { 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " to join an active group", MAC2STR(sa)); 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) && 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN) 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0 || 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0)) { 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept previously " 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authorized invitation"); 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto accept_inv; 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Do not accept the invitation automatically; notify user and 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * request approval. 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt grp = wpas_get_p2p_group(wpa_s, ssid, ssid_len, go); 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (grp) { 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept invitation to already " 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "running persistent group"); 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*go) 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_bssid, grp->own_addr, ETH_ALEN); 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto accept_inv; 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24477a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) && 24487a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0) { 24497a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Accept previously initiated " 24507a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "invitation to re-invoke a persistent group"); 24517a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else if (!wpa_s->conf->persistent_reconnect) 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled == 2 && 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(s->bssid, go_dev_addr, ETH_ALEN) == 0 && 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len == ssid_len && 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) == 0) 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!s) { 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested reinvocation of an unknown group", 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_UNKNOWN_GROUP; 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO && !wpas_p2p_create_iface(wpa_s)) { 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *go = 1; 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state >= WPA_AUTHENTICATING) { 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The only available " 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface is already in use - reject " 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation"); 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_bssid, wpa_s->own_addr, ETH_ALEN); 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (s->mode == WPAS_MODE_P2P_GO) { 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *go = 1; 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO) < 0) 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new " 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface address for the group"); 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group_bssid, wpa_s->pending_interface_addr, 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtaccept_inv: 2491700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, 0); 2492700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, cur_bssid) == 0 && 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->assoc_freq) { 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to force channel to match " 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the channel we are already using"); 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *force_freq = wpa_s->assoc_freq; 2498700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, wpa_s->assoc_freq); 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_drv_shared_freq(wpa_s); 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res > 0) { 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to force channel to match " 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with the channel we are already using on a " 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "shared interface"); 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *force_freq = res; 2507700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, res); 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return P2P_SC_SUCCESS; 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, size_t ssid_len, 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *go_dev_addr, u8 status, 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int op_freq) 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *s; 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->disabled == 2 && 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->ssid_len == ssid_len && 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) == 0) 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status == P2P_SC_SUCCESS) { 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " was accepted; op_freq=%d MHz", 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), op_freq); 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s) { 253491c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt int go = s->mode == WPAS_MODE_P2P_GO; 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_add_persistent( 25367a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s, s, go, go ? op_freq : 0, 0, NULL); 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (bssid) { 2538d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->user_initiated_pd = 0; 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_join(wpa_s, bssid, go_dev_addr, 254004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_wps_method, 0); 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " was rejected (status %u)", MAC2STR(sa), status); 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!s) { 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid) { 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "sa=" MACSTR " go_dev_addr=" MACSTR 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " bssid=" MACSTR " unknown-network", 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), MAC2STR(go_dev_addr), 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bssid)); 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "sa=" MACSTR " go_dev_addr=" MACSTR 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " unknown-network", 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), MAC2STR(go_dev_addr)); 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25677a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (s->mode == WPAS_MODE_P2P_GO && op_freq) { 25687a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED "sa=" 25697a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt MACSTR " persistent=%d freq=%d", 25707a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt MAC2STR(sa), s->id, op_freq); 25717a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else { 25727a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED "sa=" 25737a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt MACSTR " persistent=%d", MAC2STR(sa), s->id); 25747a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s, 2579700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt struct wpa_ssid *ssid, 2580700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt const u8 *peer) 2581700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 2582700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt size_t i; 2583700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2584700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (ssid == NULL) 2585700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; 2586700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2587700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) { 2588700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (os_memcmp(ssid->p2p_client_list + i * ETH_ALEN, peer, 2589700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ETH_ALEN) == 0) 2590700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt break; 2591700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 2592700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (i >= ssid->num_p2p_clients) { 2593700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GO && 2594700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) { 2595700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d " 2596700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "due to invitation result", ssid->id); 2597700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_notify_network_removed(wpa_s, ssid); 2598700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, ssid->id); 2599700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; 2600700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 2601700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; /* Peer not found in client list */ 2602700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 2603700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2604700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent " 2605700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "group %d client list due to invitation result", 2606700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt MAC2STR(peer), ssid->id); 2607700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt os_memmove(ssid->p2p_client_list + i * ETH_ALEN, 2608700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid->p2p_client_list + (i + 1) * ETH_ALEN, 2609700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt (ssid->num_p2p_clients - i - 1) * ETH_ALEN); 2610700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid->num_p2p_clients--; 2611700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_WRITE 2612700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->parent->conf->update_config && 2613700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf)) 2614700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration"); 2615700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_WRITE */ 2616700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 2617700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2618700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2619700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtstatic void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s, 2620700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt const u8 *peer) 2621700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt{ 2622700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt struct wpa_ssid *ssid; 2623700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2624700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s = wpa_s->global->p2p_invite_group; 2625700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s == NULL) 2626700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; /* No known invitation group */ 2627700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid = wpa_s->current_ssid; 2628700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 2629700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt !ssid->p2p_persistent_group) 2630700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return; /* Not operating as a GO in persistent group */ 2631700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid = wpas_p2p_get_persistent(wpa_s->parent, peer, 2632700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid->ssid, ssid->ssid_len); 2633700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_remove_persistent_peer(wpa_s, ssid, peer); 2634700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt} 2635700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 2636700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 26377a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtstatic void wpas_invitation_result(void *ctx, int status, const u8 *bssid, 2638700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt const struct p2p_channels *channels, 2639700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt const u8 *peer) 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid) { 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d " MACSTR, 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status, MAC2STR(bssid)); 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d ", status); 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_p2p_invitation_result(wpa_s, status, bssid); 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2654700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR, 2655700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt status, MAC2STR(peer)); 2656700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->pending_invite_ssid_id == -1) { 2657700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (status == P2P_SC_FAIL_UNKNOWN_GROUP) 2658700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_remove_persistent_client(wpa_s, peer); 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Invitation to active group */ 2660700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26627a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { 26637a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another " 26647a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "invitation exchange to indicate readiness for " 26657a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "re-invocation"); 26667a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 26677a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != P2P_SC_SUCCESS) { 2669700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (status == P2P_SC_FAIL_UNKNOWN_GROUP) { 2670700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt ssid = wpa_config_get_network( 2671700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->conf, wpa_s->pending_invite_ssid_id); 2672700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_remove_persistent_peer(wpa_s, ssid, peer); 2673700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_invite_ssid_id); 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Could not find persistent group " 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data matching with invitation"); 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26862c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen /* 26872c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * The peer could have missed our ctrl::ack frame for Invitation 26882c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * Response and continue retransmitting the frame. To reduce the 26892c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * likelihood of the peer not getting successful TX status for the 26902c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * Invitation Response frame, wait a short time here before starting 26912c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * the persistent group so that we will remain on the current channel to 26922c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen * acknowledge any possible retransmission from the peer. 26932c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen */ 269481931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff#ifndef ANDROID_P2P 26952c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 50 ms wait on current channel before " 26962c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen "starting persistent group"); 26972c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen os_sleep(0, 50000); 269881931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff#else 269981931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 100 ms wait on current channel before " 270081931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff "starting persistent group"); 270181931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff os_sleep(0, 100000); 270281931b8bb302c38828763358f9e15af2b22c52c6Irfan Sheriff#endif 27032c5b17df4c29abdf11a85216c2f6272af796c576Jouni Malinen 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_add_persistent(wpa_s, ssid, 270531be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen ssid->mode == WPAS_MODE_P2P_GO, 270631be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_persistent_go_freq, 27077a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->p2p_go_ht40, channels); 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 271104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_p2p_disallowed_freq(struct wpa_global *global, 271204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int freq) 271304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 271404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int i; 271504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 271604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (global->p2p_disallow_freq == NULL) 271704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 271804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 271904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < global->num_p2p_disallow_freq; i++) { 272004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (freq >= global->p2p_disallow_freq[i].min && 272104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq <= global->p2p_disallow_freq[i].max) 272204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 272304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 272404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 272504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 272604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 272704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 272804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 272904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_add_chan(struct p2p_reg_class *reg, u8 chan) 273004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 273104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt reg->channel[reg->channels] = chan; 273204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt reg->channels++; 273304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 273404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 273504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s, 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *chan) 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, cla = 0; 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz " 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Operating class 81 - 2.4 GHz band channels 1..13 */ 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_class[cla].reg_class = 81; 274604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan->reg_class[cla].channels = 0; 274704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < 11; i++) { 274804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 2412 + i * 5)) 274904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], i + 1); 275004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 275104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan->reg_class[cla].channels) 275204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cla++; 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz " 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Operating class 115 - 5 GHz, channels 36-48 */ 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_class[cla].reg_class = 115; 275904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan->reg_class[cla].channels = 0; 276004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 36 * 5)) 276104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 36); 276204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 40 * 5)) 276304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 40); 276404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 44 * 5)) 276504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 44); 276604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 48 * 5)) 276704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 48); 276804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan->reg_class[cla].channels) 276904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cla++; 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz " 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Operating class 124 - 5 GHz, channels 149,153,157,161 */ 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_class[cla].reg_class = 124; 277604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan->reg_class[cla].channels = 0; 277704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 149 * 5)) 277804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 149); 277904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 153 * 5)) 278004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 153); 278104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 156 * 5)) 278204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 157); 278304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 161 * 5)) 278404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_add_chan(&chan->reg_class[cla], 161); 278504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan->reg_class[cla].channels) 278604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cla++; 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_classes = cla; 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 num_modes, 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum hostapd_hw_mode mode) 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 i; 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_modes; i++) { 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (modes[i].mode == mode) 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &modes[i]; 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 280804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int has_channel(struct wpa_global *global, 280904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_hw_modes *mode, u8 chan, int *flags) 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 281204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int freq; 281304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 281404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq = (mode->mode == HOSTAPD_MODE_IEEE80211A ? 5000 : 2407) + 281504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan * 5; 281604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_p2p_disallowed_freq(global, freq)) 281704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < mode->num_channels; i++) { 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mode->channels[i].chan == chan) { 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags) 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *flags = mode->channels[i].flag; 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return !(mode->channels[i].flag & 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (HOSTAPD_CHAN_DISABLED | 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_CHAN_PASSIVE_SCAN | 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_CHAN_NO_IBSS | 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_CHAN_RADAR)); 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_oper_class_map { 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum hostapd_hw_mode mode; 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_class; 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 min_chan; 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 max_chan; 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 inc; 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { BW20, BW40PLUS, BW40MINUS } bw; 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 284461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct p2p_oper_class_map op_class[] = { 284561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 }, 284661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#if 0 /* Do not enable HT40 on 2 GHz for now */ 284761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS }, 284861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS }, 284961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif 285061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20 }, 285161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20 }, 285261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS }, 285361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS }, 285461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS }, 285561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS }, 285661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { -1, 0, 0, 0, 0, BW20 } 285761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}; 285861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 285961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 286061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s, 286161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_hw_modes *mode, 286261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 channel, u8 bw) 286361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 286461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int flag; 286561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 286661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!has_channel(wpa_s->global, mode, channel, &flag)) 286761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 286861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (bw == BW40MINUS && 286961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (!(flag & HOSTAPD_CHAN_HT40MINUS) || 287061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !has_channel(wpa_s->global, mode, channel - 4, NULL))) 287161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 287261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (bw == BW40PLUS && 287361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (!(flag & HOSTAPD_CHAN_HT40PLUS) || 287461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !has_channel(wpa_s->global, mode, channel + 4, NULL))) 287561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 287661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 287761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 287861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 287961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s, 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *chan) 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct hostapd_hw_modes *mode; 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int cla, op; 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->hw.modes == NULL) { 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching " 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "of all supported channels; assume dualband " 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "support"); 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpas_p2p_default_channels(wpa_s, chan); 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla = 0; 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (op = 0; op_class[op].op_class; op++) { 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_oper_class_map *o = &op_class[op]; 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ch; 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *reg = NULL; 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode); 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mode == NULL) 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { 290461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw) < 1) 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg == NULL) { 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Add operating " 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "class %u", o->op_class); 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg = &chan->reg_class[cla]; 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cla++; 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg->reg_class = o->op_class; 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg->channel[reg->channels] = ch; 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg->channels++; 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg) { 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Channels", 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reg->channel, reg->channels); 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan->reg_classes = cla; 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 292861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s, 292961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_hw_modes *mode, u8 channel) 293061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 293161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int op, ret; 293261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 293361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (op = 0; op_class[op].op_class; op++) { 293461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_oper_class_map *o = &op_class[op]; 293561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 ch; 293661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 293761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { 293861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (o->mode != HOSTAPD_MODE_IEEE80211A || 293961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt o->bw == BW20 || ch != channel) 294061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 294161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ret = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw); 294261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ret < 0) 294361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 294461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else if (ret > 0) 294561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return (o->bw == BW40MINUS) ? -1 : 1; 294661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 294761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 294861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 294961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 295061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 295161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 295261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 295361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf, 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buf_len) 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(wpa_s->own_addr, interface_addr, ETH_ALEN) == 0) 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_get_noa(wpa_s, buf, buf_len); 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2970c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpas_go_connected(void *ctx, const u8 *dev_addr) 2971c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 2972c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 2973c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2974c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) { 2975c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 2976c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid == NULL) 2977c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 2978c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid->mode != WPAS_MODE_INFRA) 2979c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 2980c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (wpa_s->wpa_state != WPA_COMPLETED && 2981c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->wpa_state != WPA_GROUP_HANDSHAKE) 2982c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 2983c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (os_memcmp(wpa_s->go_dev_addr, dev_addr, ETH_ALEN) == 0) 2984c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 1; 2985c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 2986c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2987c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 0; 2988c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 2989c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 2990c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_init - Initialize P2P module for %wpa_supplicant 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init() 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_config p2p; 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r; 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)) 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p) 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_params params; 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use driver-based P2P management"); 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.dev_name = wpa_s->conf->device_name; 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(params.pri_dev_type, wpa_s->conf->device_type, 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_sec_dev_types = wpa_s->conf->num_sec_device_types; 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(params.sec_dev_type, 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->sec_device_type, 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_sec_dev_types * WPS_DEV_TYPE_LEN); 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_p2p_set_params(wpa_s, ¶ms) < 0) 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&p2p, 0, sizeof(p2p)); 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.msg_ctx = wpa_s; 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.cb_ctx = wpa_s; 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.p2p_scan = wpas_p2p_scan; 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.send_action = wpas_send_action; 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.send_action_done = wpas_send_action_done; 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.go_neg_completed = wpas_go_neg_completed; 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.go_neg_req_rx = wpas_go_neg_req_rx; 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.dev_found = wpas_dev_found; 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.dev_lost = wpas_dev_lost; 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.start_listen = wpas_start_listen; 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.stop_listen = wpas_stop_listen; 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.send_probe_resp = wpas_send_probe_resp; 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.sd_request = wpas_sd_request; 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.sd_response = wpas_sd_response; 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.prov_disc_req = wpas_prov_disc_req; 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.prov_disc_resp = wpas_prov_disc_resp; 304575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p.prov_disc_fail = wpas_prov_disc_fail; 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.invitation_process = wpas_invitation_process; 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.invitation_received = wpas_invitation_received; 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.invitation_result = wpas_invitation_result; 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.get_noa = wpas_get_noa; 3050c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p.go_connected = wpas_go_connected; 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN); 30531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN); 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.dev_name = wpa_s->conf->device_name; 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.manufacturer = wpa_s->conf->manufacturer; 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.model_name = wpa_s->conf->model_name; 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.model_number = wpa_s->conf->model_number; 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.serial_number = wpa_s->conf->serial_number; 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wps) { 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16); 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.config_methods = wpa_s->wps->config_methods; 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->p2p_listen_reg_class && 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_listen_channel) { 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.reg_class = wpa_s->conf->p2p_listen_reg_class; 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.channel = wpa_s->conf->p2p_listen_channel; 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.reg_class = 81; 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Pick one of the social channels randomly as the listen 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * channel. 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.channel = 1 + (r % 3) * 5; 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d", p2p.channel); 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->p2p_oper_reg_class && 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_oper_channel) { 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_reg_class = wpa_s->conf->p2p_oper_reg_class; 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_channel = wpa_s->conf->p2p_oper_channel; 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.cfg_op_channel = 1; 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Configured operating channel: " 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d:%d", p2p.op_reg_class, p2p.op_channel); 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_reg_class = 81; 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use random operation channel from (1, 6, 11) if no other 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * preference is indicated. 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.op_channel = 1 + (r % 3) * 5; 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.cfg_op_channel = 0; 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Random operating channel: " 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d:%d", p2p.op_reg_class, p2p.op_channel); 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) { 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.country, wpa_s->conf->country, 2); 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.country[2] = 0x04; 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.country, "XX\x04", 3); 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_setup_channels(wpa_s, &p2p.channels)) { 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to configure supported " 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel list"); 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type, 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_TYPE_LEN); 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types; 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type, 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN); 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.concurrent_operations = !!(wpa_s->drv_flags & 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_FLAGS_P2P_CONCURRENT); 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.max_peers = 100; 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->p2p_ssid_postfix) { 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.ssid_postfix_len = 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(wpa_s->conf->p2p_ssid_postfix); 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p.ssid_postfix_len > sizeof(p2p.ssid_postfix)) 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.ssid_postfix_len = sizeof(p2p.ssid_postfix); 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p2p.ssid_postfix, wpa_s->conf->p2p_ssid_postfix, 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.ssid_postfix_len); 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss; 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3134d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p.max_listen = wpa_s->max_remain_on_chan; 3135d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 313604abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt#ifdef ANDROID_P2P 3137af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff if(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) { 313804abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt p2p.p2p_concurrency = P2P_MULTI_CHANNEL_CONCURRENT; 3139af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff wpa_printf(MSG_DEBUG, "P2P: Multi channel concurrency support"); 3140af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff } else { 3141af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff // Add support for WPA_DRIVER_FLAGS_P2P_CONCURRENT 314204abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt p2p.p2p_concurrency = P2P_SINGLE_CHANNEL_CONCURRENT; 3143af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff wpa_printf(MSG_DEBUG, "P2P: Single channel concurrency support"); 3144af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff } 314504abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt#endif 314604abaa93653bcee36d59576c90f283d4efdb0a64Dmitry Shmidt 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->p2p = p2p_init(&p2p); 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p == NULL) 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 315004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt global->p2p_init_wpa_s = wpa_s; 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) { 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->wps_vendor_ext[i] == NULL) 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_wps_vendor_extension( 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->p2p, wpa_s->conf->wps_vendor_ext[i]); 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_deinit - Deinitialize per-interface P2P data 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitialize per-interface P2P data. 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_deinit(struct wpa_supplicant *wpa_s) 31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->driver && wpa_s->drv_priv) 31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_probe_req_report(wpa_s, 0); 31731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->go_params) { 31751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Clear any stored provisioning info */ 31761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_clear_provisioning_info( 31771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->global->p2p, 317804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->go_params->peer_device_addr); 31791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 31801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->go_params); 31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->go_params = NULL; 31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); 31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL); 31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: remove group interface from the driver if this wpa_s instance 31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is on top of a P2P group interface */ 31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_deinit_global - Deinitialize global P2P module 31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init() 31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitializes the global (per device) P2P module. 32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_deinit_global(struct wpa_global *global) 32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s, *tmp; 32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 320561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s = global->ifaces; 320661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s) 320761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_service_flush(wpa_s); 320861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p == NULL) 32108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Remove remaining P2P group interfaces */ 32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_s && wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) 32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpa_s->next; 32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_s) { 32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = global->ifaces; 32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (tmp && 32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (tmp == wpa_s || 32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)) { 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = tmp->next; 32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 322404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Disconnect from the P2P group and deinit the interface */ 322504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_disconnect(tmp); 32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Deinit GO data on any possibly remaining interface (if main 32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface is used as GO). 32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface) 32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_group_deinit(wpa_s); 32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_deinit(global->p2p); 32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->p2p = NULL; 323904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt global->p2p_init_wpa_s = NULL; 32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s) 32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3245d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->conf->p2p_no_group_iface) 3246d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; /* separate interface disabled per configuration */ 32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & 32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE | 32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P)) 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* P2P group requires a new interface in every case 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CONCURRENT)) 32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* driver does not support concurrent operations */ 32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->ifaces->next) 32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* more that one interface already in use */ 32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state >= WPA_AUTHENTICATING) 32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* this interface is already in use */ 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s, 32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer_addr, 32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 326604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 3267d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ssid *ssid, unsigned int pref_freq) 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (persistent_group && wpa_s->conf->persistent_reconnect) 32701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt persistent_group = 2; 32711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_connect(wpa_s, peer_addr, wps_method, 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent, own_interface_addr, 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt force_freq, persistent_group); 32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 327861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 327961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Increase GO config timeout if HT40 is used since it takes some time 328061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * to scan channels for coex purposes before the BSS can be started. 328161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 328261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p2p_set_config_timeout(wpa_s->global->p2p, 328361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40 ? 255 : 100, 20); 328461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_connect(wpa_s->global->p2p, peer_addr, wps_method, 32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent, own_interface_addr, force_freq, 328704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt persistent_group, ssid ? ssid->ssid : NULL, 328804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid ? ssid->ssid_len : 0, 3289d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->p2p_pd_before_go_neg, pref_freq); 32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s, 32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer_addr, 32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_wps_method wps_method, 32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go_intent, const u8 *own_interface_addr, 329704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt unsigned int force_freq, int persistent_group, 3298d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ssid *ssid, unsigned int pref_freq) 32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (persistent_group && wpa_s->conf->persistent_reconnect) 33011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt persistent_group = 2; 33021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_authorize(wpa_s->global->p2p, peer_addr, wps_method, 33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent, own_interface_addr, force_freq, 330804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt persistent_group, ssid ? ssid->ssid : NULL, 3309d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid ? ssid->ssid_len : 0, pref_freq); 33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s) 33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_join_scan_count++; 33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d", 33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_join_scan_count); 33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_join_scan_count > P2P_MAX_JOIN_SCAN_ATTEMPTS) { 33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to find GO " MACSTR 33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for join operationg - stop join attempt", 33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_join_iface_addr)); 33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 332304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_auto_pd) { 332404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 332504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE 332604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " p2p_dev_addr=" MACSTR " status=N/A", 332704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 332804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 332904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 33308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, 33318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_GROUP_FORMATION_FAILURE); 33328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 333604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq) 333704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 333804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *iface; 333904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int shared_freq; 334004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 bssid[ETH_ALEN]; 334104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 334204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) 334304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 334404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 334504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { 334604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_create_iface(wpa_s) && iface == wpa_s) 334704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 334804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (iface->current_ssid == NULL || iface->assoc_freq == 0) 334904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 335004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (iface->current_ssid->mode == WPAS_MODE_AP || 335104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->current_ssid->mode == WPAS_MODE_P2P_GO) 335204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt shared_freq = iface->current_ssid->frequency; 335304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else if (wpa_drv_get_bssid(iface, bssid) == 0) 335404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt shared_freq = iface->assoc_freq; 335504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 335604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt shared_freq = 0; 335704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 335804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (shared_freq && freq != shared_freq) { 335904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Frequency conflict - %s " 336004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "connected on %d MHz - new connection on " 336104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "%d MHz", iface->ifname, shared_freq, freq); 336204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 336304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 336404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 336504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 336604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt shared_freq = wpa_drv_shared_freq(wpa_s); 336704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (shared_freq > 0 && shared_freq != freq) { 336804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Frequency conflict - shared " 336904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "virtual interface connected on %d MHz - new " 337004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "connection on %d MHz", shared_freq, freq); 337104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 337204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 337304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 337404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 337504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 337604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 337704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 337804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s, 337904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *peer_dev_addr) 338004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 338104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 338204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int updated; 338304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 338404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bss = wpa_bss_get_p2p_dev_addr(wpa_s, peer_dev_addr); 338504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss == NULL) 338604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 338704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss->last_update_idx < wpa_s->bss_update_idx) { 338804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer BSS entry not updated in the " 338904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "last scan"); 339004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 339104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 339204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 339304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt updated = os_time_before(&wpa_s->p2p_auto_started, &bss->last_update); 339404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Current BSS entry for peer updated at " 339504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "%ld.%06ld (%supdated in last scan)", 339604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bss->last_update.sec, bss->last_update.usec, 339704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt updated ? "": "not "); 339804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 339904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return updated; 340004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 340104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 340204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, 34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res) 34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_bss *bss; 34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 iface_addr[ETH_ALEN]; 340904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 341504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS) for %sjoin", 341604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt scan_res ? (int) scan_res->num : -1, 341704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_join ? "auto_" : ""); 34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scan_res) 34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_scan_res_handler(wpa_s, scan_res); 34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 342204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_auto_pd) { 342304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int join = wpas_p2p_peer_go(wpa_s, 342404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_join_dev_addr); 342504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join == 0 && 342604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry < P2P_AUTO_PD_SCAN_ATTEMPTS) { 342704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry++; 3428444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt bss = wpa_bss_get_bssid_latest( 3429444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt wpa_s, wpa_s->pending_join_dev_addr); 343004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss) { 343104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq = bss->freq; 343204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Scan retry %d for " 343304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "the peer " MACSTR " at %d MHz", 343404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry, 343504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(wpa_s-> 343604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pending_join_dev_addr), 343704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freq); 343804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_join_scan_req(wpa_s, freq); 343904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 344004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 344104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 344204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 344304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join < 0) 344404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt join = 0; 344504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 344604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 344704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use = join ? AUTO_PD_JOIN : AUTO_PD_GO_NEG; 344804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Auto PD with " MACSTR " join=%d", 344904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr), join); 345004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_prov_disc_req(wpa_s->global->p2p, 345104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_join_dev_addr, 345204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_config_methods, join, 3453d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 0, wpa_s->user_initiated_pd) < 0) { 345404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 345504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE 345604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " p2p_dev_addr=" MACSTR " status=N/A", 345704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 345804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 345904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 346004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 346104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 346204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_auto_join) { 346304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int join = wpas_p2p_peer_go(wpa_s, 346404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_join_dev_addr); 346504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join < 0) { 346604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be " 346704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "running a GO -> use GO Negotiation"); 346804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, 346904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_pin, wpa_s->p2p_wps_method, 347004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_group, 0, 0, 0, 347104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_go_intent, 347204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_connect_freq, 347304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id, 347461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_pd_before_go_neg, 347561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40); 347604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 347704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 347804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 347904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Peer was found running GO%s -> " 348004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "try to join the group", join ? "" : 348104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " in older scan"); 348204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!join) 348304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 1; 348404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 348504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_get_oper_freq(wpa_s->global->p2p, 34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_iface_addr); 34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0 && 34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_get_interface_addr(wpa_s->global->p2p, 34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_dev_addr, 34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface_addr) == 0 && 34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(iface_addr, wpa_s->pending_join_dev_addr, ETH_ALEN) != 0) 34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Overwrite pending interface " 34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "address for join from " MACSTR " to " MACSTR 34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " based on newly discovered P2P peer entry", 34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_join_iface_addr), 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(iface_addr)); 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_get_oper_freq(wpa_s->global->p2p, 35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_iface_addr); 35048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 0) { 35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " 35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from P2P peer table: %d MHz", freq); 35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3509444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->pending_join_iface_addr); 35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss) { 35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = bss->freq; 35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " 35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from BSS table: %d MHz", freq); 35148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0) { 35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 method; 35178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 351804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_check_freq_conflict(wpa_s, freq) > 0) { 351904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, 352004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt P2P_EVENT_GROUP_FORMATION_FAILURE 352104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "reason=FREQ_CONFLICT"); 352204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 352304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 352404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 35258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Send Provision Discovery Request " 35268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "prior to joining an existing group (GO " MACSTR 35278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " freq=%u MHz)", 35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr), freq); 35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_pd_before_join = 1; 35308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (wpa_s->pending_join_wps_method) { 35328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_DISPLAY: 35338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = WPS_CONFIG_KEYPAD; 35348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PIN_KEYPAD: 35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = WPS_CONFIG_DISPLAY; 35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WPS_PBC: 35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = WPS_CONFIG_PUSHBUTTON; 35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = 0; 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((p2p_get_provisioning_info(wpa_s->global->p2p, 35471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->pending_join_dev_addr) == 35481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt method)) { 35491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 35501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * We have already performed provision discovery for 35511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * joining the group. Proceed directly to join 35521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * operation without duplicated provision discovery. */ 35531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Provision discovery " 35541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "with " MACSTR " already done - proceed to " 35551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "join", 35561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(wpa_s->pending_join_dev_addr)); 35571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->pending_pd_before_join = 0; 35581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto start; 35591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 35601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_prov_disc_req(wpa_s->global->p2p, 35621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->pending_join_dev_addr, method, 1, 3563d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt freq, wpa_s->user_initiated_pd) < 0) { 35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to send Provision " 35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Discovery Request before joining an " 35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "existing group"); 35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto start; 35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to find BSS/GO - try again later"); 35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL); 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_check_join_scan_limit(wpa_s); 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstart: 35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start join operation immediately */ 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_join_start(wpa_s); 35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq) 35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params params; 35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_ie, *ies; 35901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t ielen; 359104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int freqs[2] = { 0, 0 }; 3592ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt#ifdef ANDROID_P2P 3593ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt int oper_freq; 35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3595ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt /* If freq is not provided, check the operating freq of the GO and do a 3596ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt * a directed scan to save time 3597ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt */ 3598ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt if(!freq) { 3599ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt freq = (oper_freq = p2p_get_oper_freq(wpa_s->global->p2p, 3600ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt wpa_s->pending_join_iface_addr) == -1) ? 0 : oper_freq; 3601ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt } 3602ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt#endif 36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* P2P Wildcard SSID */ 36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_ssids = 1; 36078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID; 36088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN; 36098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->wps->dev.p2p = 1; 361104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev, 361204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0, 361304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt NULL); 36148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_ie == NULL) { 36158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_scan_res_join(wpa_s, NULL); 36168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 36178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 36201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen); 36218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) { 36228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_scan_res_join(wpa_s, NULL); 36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(ies, wps_ie); 36278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 36288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3629c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_scan_ie(wpa_s->global->p2p, ies, NULL); 36308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p_probe = 1; 36328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies = wpabuf_head(ies); 36338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.extra_ies_len = wpabuf_len(ies); 363404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (freq > 0) { 363504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt freqs[0] = freq; 363604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.freqs = freqs; 363704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 36388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Run a scan to update BSS table and start Provision Discovery once 36418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the new scan results become available. 36428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 36431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_scan(wpa_s, ¶ms); 3644444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (!ret) { 3645444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt os_get_time(&wpa_s->scan_trigger_time); 364604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_join; 3647444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } 36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ies); 36508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 36528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to start scan for join - " 36538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "try again later"); 36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL); 36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_check_join_scan_limit(wpa_s); 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 366104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx) 366204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 366304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 366404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_join_scan_req(wpa_s, 0); 366504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 366604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 366704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr, 366904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *dev_addr, enum p2p_wps_method wps_method, 367004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int auto_join) 36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface " 367304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MACSTR " dev " MACSTR ")%s", 367404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(iface_addr), MAC2STR(dev_addr), 367504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt auto_join ? " (auto_join)" : ""); 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 367704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 0; 367804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_join = !!auto_join; 36798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN); 36808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN); 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_join_wps_method = wps_method; 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we are not running find during connection establishment */ 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_stop_find(wpa_s); 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_join_scan_count = 0; 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_join_scan(wpa_s, NULL); 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_join_start(struct wpa_supplicant *wpa_s) 36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group; 36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results res; 369604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = wpas_p2p_get_group_iface(wpa_s, 0, 0); 36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) 37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 37018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group != wpa_s) { 37028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(group->p2p_pin, wpa_s->p2p_pin, 37038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(group->p2p_pin)); 37048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->p2p_wps_method = wpa_s->p2p_wps_method; 37054b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt } else { 37064b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt /* 37074b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * Need to mark the current interface for p2p_group_formation 37084b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * when a separate group interface is not used. This is needed 37094b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * to allow p2p_cancel stop a pending p2p_connect-join. 37104b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * wpas_p2p_init_group_interface() addresses this for the case 37114b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * where a separate group interface is used. 37124b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt */ 37134b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt wpa_s->global->p2p_group_formation = wpa_s; 37148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group->p2p_in_provisioning = 1; 371704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt group->p2p_fallback_to_go_neg = wpa_s->p2p_fallback_to_go_neg; 37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&res, 0, sizeof(res)); 37208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr, 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res.wps_method = wpa_s->pending_join_wps_method; 3723444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->pending_join_iface_addr); 372404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss) { 372504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res.freq = bss->freq; 372604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res.ssid_len = bss->ssid_len; 372704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(res.ssid, bss->ssid, bss->ssid_len); 372804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 372904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3730c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { 3731c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel prior to " 3732c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "starting client"); 3733c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_drv_cancel_remain_on_channel(wpa_s); 3734c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->off_channel_freq = 0; 3735c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->roc_waiting_drv_freq = 0; 3736c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_enrollee(group, &res); 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Allow a longer timeout for join-a-running-group than normal 15 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * second group formation timeout since the GO may not have authorized 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * our connection yet. 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); 37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(60, 0, wpas_p2p_group_formation_timeout, 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s, NULL); 37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37527a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtstatic int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq, 37537a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int *force_freq, int *pref_freq, 37547a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int *oper_freq) 37557a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt{ 37567a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (freq > 0) { 37577a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!p2p_supported_freq(wpa_s->global->p2p, freq)) { 37587a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The forced channel " 37597a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "(%u MHz) is not supported for P2P uses", 37607a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq); 37617a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return -3; 37627a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 37637a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 37647a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (*oper_freq > 0 && freq != *oper_freq && 37657a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt !(wpa_s->drv_flags & 37667a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { 37677a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group " 37687a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "on %u MHz while connected on another " 37697a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "channel (%u MHz)", freq, *oper_freq); 37707a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return -2; 37717a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 37727a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the " 37737a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "requested channel (%u MHz)", freq); 37747a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt *force_freq = freq; 37757a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else if (*oper_freq > 0 && 37767a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt !p2p_supported_freq(wpa_s->global->p2p, *oper_freq)) { 37777a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!(wpa_s->drv_flags & 37787a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { 37797a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group " 37807a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "while connected on non-P2P supported " 37817a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "channel (%u MHz)", *oper_freq); 37827a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return -2; 37837a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 37847a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Current operating channel " 37857a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "(%u MHz) not available for P2P - try to use " 37867a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "another channel", *oper_freq); 37877a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt *force_freq = 0; 37887a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else if (*oper_freq > 0 && *pref_freq == 0 && 37897a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt (wpa_s->drv_flags & 37907a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { 37917a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to prefer the channel we " 37927a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "are already using (%u MHz) on another interface", 37937a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt *oper_freq); 37947a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt *pref_freq = *oper_freq; 37957a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else if (*oper_freq > 0) { 37967a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the " 37977a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "channel we are already using (%u MHz) on another " 37987a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "interface", *oper_freq); 37997a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt *force_freq = *oper_freq; 38007a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 38017a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 38027a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 0; 38037a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt} 38047a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 38057a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_connect - Request P2P Group Formation to be started 38088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @peer_addr: Address of the peer P2P Device 38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pin: PIN to use during provisioning or %NULL to indicate PBC mode 38118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @persistent_group: Whether to create a persistent group 381204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @auto_join: Whether to select join vs. GO Negotiation automatically 38138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @join: Whether to join an existing group (as a client) instead of starting 38148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Group Owner negotiation; @peer_addr is BSSID in that case 38158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @auth: Whether to only authorize the connection instead of doing that and 38168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initiating Group Owner negotiation 38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @go_intent: GO Intent or -1 to use default 38188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency for the group or 0 for auto-selection 381904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @persistent_id: Persistent group credentials to use for forcing GO 382004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * parameters or -1 to generate new values (SSID/passphrase) 382104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @pd: Whether to send Provision Discovery prior to GO Negotiation as an 382204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * interoperability workaround when initiating group formation 382361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @ht40: Start GO with 40 MHz channel width 38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified 38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure, -2 on failure due to channel not currently available, 38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * -3 if forced channel is not supported 38278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 38288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 38298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pin, enum p2p_wps_method wps_method, 383004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int persistent_group, int auto_join, int join, int auth, 383161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int go_intent, int freq, int persistent_id, int pd, 383261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int ht40) 38338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3834d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int force_freq = 0, pref_freq = 0, oper_freq = 0; 38358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 bssid[ETH_ALEN]; 38367a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int ret = 0, res; 38378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_driver_if_type iftype; 38381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *if_addr; 383904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = NULL; 38408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 38428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 38438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 384404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (persistent_id >= 0) { 384504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, persistent_id); 384604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid == NULL || ssid->disabled != 2 || 384704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->mode != WPAS_MODE_P2P_GO) 384804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 384904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 385004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go_intent < 0) 38528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_intent = wpa_s->conf->p2p_go_intent; 38538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auth) 38558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 38568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_wps_method = wps_method; 385804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_group = !!persistent_group; 385904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id = persistent_id; 386004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_go_intent = go_intent; 386104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_connect_freq = freq; 386204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 0; 386304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_pd_before_go_neg = !!pd; 386461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40 = !!ht40; 38658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pin) 38678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin)); 38688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wps_method == WPS_PIN_DISPLAY) { 38698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = wps_generate_pin(); 38708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(wpa_s->p2p_pin, sizeof(wpa_s->p2p_pin), "%08d", 38718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret); 38728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Randomly generated PIN: %s", 38738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_pin); 38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 38758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_pin[0] = '\0'; 38768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 387704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (join || auto_join) { 38788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN]; 38798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth) { 38808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to " 38818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connect a running group from " MACSTR, 38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr)); 38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); 38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 38858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(dev_addr, peer_addr, ETH_ALEN); 38878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr, 38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface_addr) < 0) { 38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(iface_addr, peer_addr, ETH_ALEN); 38908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_get_dev_addr(wpa_s->global->p2p, peer_addr, 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr); 38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 389304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (auto_join) { 389404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_get_time(&wpa_s->p2p_auto_started); 389504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Auto join started at " 389604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "%ld.%06ld", 389704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.sec, 389804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.usec); 389904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 3900d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->user_initiated_pd = 1; 390104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method, 390204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt auto_join) < 0) 39038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 39058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid) == 0 && 39087a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->assoc_freq) { 39098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oper_freq = wpa_s->assoc_freq; 39107a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else { 39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oper_freq = wpa_drv_shared_freq(wpa_s); 39128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oper_freq < 0) 39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oper_freq = 0; 39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39167a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq, 39177a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt &oper_freq); 39187a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (res) 39197a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return res; 3920700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, oper_freq); 39218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s); 39238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->create_p2p_iface) { 39251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Prepare to add a new interface for the group */ 39261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt iftype = WPA_IF_P2P_GROUP; 39271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (go_intent == 15) 39281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt iftype = WPA_IF_P2P_GO; 39291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) { 39301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new " 39311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "interface for the group"); 39328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 39348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if_addr = wpa_s->pending_interface_addr; 39361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else 39371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if_addr = wpa_s->own_addr; 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth) { 39408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method, 39411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt go_intent, if_addr, 3942d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt force_freq, persistent_group, ssid, 3943d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt pref_freq) < 0) 39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 39481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method, 39491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt go_intent, if_addr, force_freq, 3950d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt persistent_group, ssid, pref_freq) < 0) { 39511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->create_p2p_iface) 39521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 39568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 39608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_remain_on_channel_cb - Indication of remain-on-channel start 39618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 39628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency of the channel in MHz 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @duration: Duration of the stay on the channel in milliseconds 39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 39658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is called when the driver indicates that it has started the 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requested remain-on-channel duration. 39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int freq, unsigned int duration) 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->off_channel_freq == wpa_s->pending_listen_freq) { 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_listen_cb(wpa_s->global->p2p, wpa_s->pending_listen_freq, 39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_duration); 39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_listen_freq = 0; 39778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, 39828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int timeout) 39838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Limit maximum Listen state time based on driver limitation. */ 39858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout > wpa_s->max_remain_on_chan) 39868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = wpa_s->max_remain_on_chan; 39878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 39898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_listen(wpa_s, timeout); 39908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_listen(wpa_s->global->p2p, timeout); 39928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 39968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_cancel_remain_on_channel_cb - Remain-on-channel timeout 39978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 39988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency of the channel in MHz 39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This callback is called when the driver indicates that a remain-on-channel 40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * operation has been completed, i.e., the duration on the requested channel 40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has timed out. 40038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 40048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int freq) 40068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback " 40088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(p2p_long_listen=%d ms pending_action_tx=%p)", 4009a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->p2p_long_listen, offchannel_pending_action_tx(wpa_s)); 40108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 40118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_listen_end(wpa_s->global->p2p, freq) > 0) 40138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* P2P module started a new operation */ 4014a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (offchannel_pending_action_tx(wpa_s)) 40158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 40168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_long_listen > 0) 40178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen -= wpa_s->max_remain_on_chan; 40188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_long_listen > 0) { 40198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state"); 40208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_listen_start(wpa_s, wpa_s->p2p_long_listen); 40218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 40268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_group_remove - Remove a P2P group 40278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 40288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ifname: Network interface name of the group interface or "*" to remove all 40298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * groups 40308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 40318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 40328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to remove a P2P group. This can be used to disconnect 40338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from a group in which the local end is a P2P Client or to end a P2P Group in 40348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case the local end is the Group Owner. If a virtual network interface was 40358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * created for this group, that interface will be removed. Otherwise, only the 40368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured P2P group network will be removed from the interface. 40378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 40388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname) 40398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global = wpa_s->global; 40418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(ifname, "*") == 0) { 40438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *prev; 40448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = global->ifaces; 40458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (wpa_s) { 40468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = wpa_s; 40478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpa_s->next; 40488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_disconnect(prev); 40498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 40518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 40548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(wpa_s->ifname, ifname) == 0) 40558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 40568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpas_p2p_disconnect(wpa_s); 40598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40627a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtstatic int freq_included(const struct p2p_channels *channels, unsigned int freq) 40637a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt{ 40647a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (channels == NULL) 40657a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 1; /* Assume no restrictions */ 40667a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return p2p_channels_includes_freq(channels, freq); 40677a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt} 40687a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 40697a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 40701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, 40711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_go_neg_results *params, 40727a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int freq, int ht40, 40737a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt const struct p2p_channels *channels) 40748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 bssid[ETH_ALEN]; 40768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 40778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(params, 0, sizeof(*params)); 40798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->role_go = 1; 408061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params->ht40 = ht40; 40818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq) { 40827a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!freq_included(channels, freq)) { 40837a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not " 40847a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "accepted", freq); 40857a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return -1; 40867a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 40878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced " 40888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frequency %d MHz", freq); 40898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = freq; 40908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_reg_class == 81 && 40918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_oper_channel >= 1 && 40927a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_channel <= 11 && 40937a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, 40947a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 2407 + 5 * wpa_s->conf->p2p_oper_channel)) { 40958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = 2407 + 5 * wpa_s->conf->p2p_oper_channel; 40968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured " 40978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frequency %d MHz", params->freq); 40987a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else if ((wpa_s->conf->p2p_oper_reg_class == 115 || 40997a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 116 || 41007a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 117 || 41017a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 124 || 41027a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 126 || 41037a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->conf->p2p_oper_reg_class == 127) && 41047a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, 41057a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 5000 + 5 * wpa_s->conf->p2p_oper_channel)) { 41068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel; 41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured " 41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frequency %d MHz", params->freq); 41098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_channel == 0 && 41108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_overall_freq > 0 && 41118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 41127a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->best_overall_freq) && 41137a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, wpa_s->best_overall_freq)) { 41148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = wpa_s->best_overall_freq; 41158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best overall " 41168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %d MHz", params->freq); 41178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_channel == 0 && 41188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_24_freq > 0 && 41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 41207a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->best_24_freq) && 41217a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, wpa_s->best_24_freq)) { 41228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = wpa_s->best_24_freq; 41238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 2.4 GHz " 41248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %d MHz", params->freq); 41258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->p2p_oper_channel == 0 && 41268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_5_freq > 0 && 41278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 41287a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->best_5_freq) && 41297a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, wpa_s->best_5_freq)) { 41308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = wpa_s->best_5_freq; 41318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz " 41328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel %d MHz", params->freq); 41338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 413404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int chan; 413504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (chan = 0; chan < 11; chan++) { 413604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params->freq = 2412 + chan * 5; 413704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_p2p_disallowed_freq(wpa_s->global, 41387a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt params->freq) && 41397a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt freq_included(channels, params->freq)) 414004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 414104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 414204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (chan == 11) { 414304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No 2.4 GHz channel " 414404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "allowed"); 414504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 414604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 41478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference " 41488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "known)", params->freq); 41498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid) == 0 && 41528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->assoc_freq && !freq) { 4153700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (!p2p_supported_freq(wpa_s->global->p2p, wpa_s->assoc_freq) 4154700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt || !freq_included(channels, wpa_s->assoc_freq)) { 4155700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->drv_flags & 4156700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) { 4157700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on " 4158700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "the channel we are already using " 4159700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "(%u MHz) - allow multi-channel " 4160700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "concurrency", wpa_s->assoc_freq); 4161700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } else { 4162700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on " 4163700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "the channel we are already using " 4164700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "(%u MHz)", wpa_s->assoc_freq); 4165700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return -1; 4166700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 4167700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } else { 4168700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Force GO on the channel we " 4169700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "are already using (%u MHz)", 4170700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->assoc_freq); 4171700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt params->freq = wpa_s->assoc_freq; 41727a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 41738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_drv_shared_freq(wpa_s); 4176700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (res > 0 && !freq && 4177700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt (!p2p_supported_freq(wpa_s->global->p2p, res) || 4178700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt !freq_included(channels, res))) { 4179700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt if (wpa_s->drv_flags & 4180700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) { 4181700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on the " 4182700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "channel we are already using on a shared " 4183700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "interface (%u MHz) - allow multi-channel " 4184700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "concurrency", res); 4185700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } else { 4186700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on the " 4187700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "channel we are already using on a shared " 4188700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt "interface (%u MHz)", res); 4189700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt return -1; 4190700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } 4191700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt } else if (res > 0 && !freq) { 41928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Force GO on the channel we are " 41938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "already using on a shared interface"); 41948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->freq = res; 41957a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (!freq_included(channels, params->freq)) { 41967a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not " 41977a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt "accepted", params->freq); 41987a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return -1; 41997a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 42001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (res > 0 && freq != res && 42011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !(wpa_s->drv_flags & 42021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { 42031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz " 42041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "while connected on another channel (%u MHz)", 42051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq, res); 42061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 42078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * 42148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, 42158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go) 42168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *group_wpa_s; 42188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4219aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (!wpas_p2p_create_iface(wpa_s)) { 4220aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use same interface for group " 4221aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "operations"); 42228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_s; 4223aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 42248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO : 4226aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt WPA_IF_P2P_CLIENT) < 0) { 4227aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_msg(wpa_s, MSG_ERROR, "P2P: Failed to add group interface"); 42288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4229aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 42308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group_wpa_s = wpas_p2p_init_group_interface(wpa_s, go); 42318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group_wpa_s == NULL) { 4232aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_msg(wpa_s, MSG_ERROR, "P2P: Failed to initialize group " 4233aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "interface"); 42348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 42358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 42368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4238aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s", 4239aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt group_wpa_s->ifname); 42408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group_wpa_s; 42418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 42458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_group_add - Add a new P2P group with local end as Group Owner 42468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() 42478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @persistent_group: Whether to create a persistent group 42488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @freq: Frequency for the group or 0 to indicate no hardcoding 42498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 42508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 42518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function creates a new P2P group with the local end as the Group Owner, 42528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * i.e., without using Group Owner Negotiation. 42538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 42548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, 425561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int freq, int ht40) 42568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results params; 42588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int r; 42598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 42618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4263dca3979ccdf869f140f096b83df322a0efc84f22Dmitry Shmidt /* Make sure we are not running find during connection establishment */ 42641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND"); 4265d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_stop_find_oper(wpa_s); 4266dca3979ccdf869f140f096b83df322a0efc84f22Dmitry Shmidt 42678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2) { 42688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 2.4 GHz " 42698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 42708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->best_24_freq > 0 && 42718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 42728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_24_freq)) { 42738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = wpa_s->best_24_freq; 42748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use best 2.4 GHz band " 42758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel: %d MHz", freq); 42768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 42778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 42788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = 2412 + (r % 3) * 25; 42798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use random 2.4 GHz band " 42808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel: %d MHz", freq); 42818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 5) { 42858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 5 GHz " 42868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "band"); 42878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->best_5_freq > 0 && 42888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_supported_freq(wpa_s->global->p2p, 42898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->best_5_freq)) { 42908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = wpa_s->best_5_freq; 42918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use best 5 GHz band " 42928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel: %d MHz", freq); 42938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 42948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 42958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = 5180 + (r % 4) * 20; 42968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p2p_supported_freq(wpa_s->global->p2p, freq)) { 42978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Could not select " 42988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "5 GHz channel for P2P group"); 42998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use random 5 GHz band " 43028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel: %d MHz", freq); 43038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq > 0 && !p2p_supported_freq(wpa_s->global->p2p, freq)) { 43078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The forced channel for GO " 43088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%u MHz) is not supported for P2P uses", 43098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq); 43108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43137a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, NULL)) 43141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 431504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (params.freq && 431604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt !p2p_supported_freq(wpa_s->global->p2p, params.freq)) { 431704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: The selected channel for GO " 431804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "(%u MHz) is not supported for P2P uses", 431904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.freq); 432004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 432104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 43228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_go_params(wpa_s->global->p2p, ¶ms); 43238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.persistent_group = persistent_group; 43248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpas_p2p_get_group_iface(wpa_s, 0, 1); 43268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 43278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(wpa_s, ¶ms, 0); 43298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 43318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_start_p2p_client(struct wpa_supplicant *wpa_s, 43358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *params, int addr_allocated) 43368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 43378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 43388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0); 43408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 43418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_deinit(wpa_s); 43448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_config_add_network(wpa_s->conf); 43468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) 43478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_set_network_defaults(ssid); 43498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->temporary = 1; 43508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->proto = WPA_PROTO_RSN; 43518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->pairwise_cipher = WPA_CIPHER_CCMP; 43528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->group_cipher = WPA_CIPHER_CCMP; 43538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->key_mgmt = WPA_KEY_MGMT_PSK; 43548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid = os_malloc(params->ssid_len); 43558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->ssid == NULL) { 43568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_remove_network(wpa_s->conf, ssid->id); 43578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid->ssid, params->ssid, params->ssid_len); 43608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len = params->ssid_len; 43618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->p2p_group = 1; 43628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->export_keys = 1; 43638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->psk_set) { 43648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid->psk, params->psk, 32); 43658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->psk_set = 1; 43668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->passphrase) 43688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->passphrase = os_strdup(params->passphrase); 43698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_select_network(wpa_s, ssid); 43718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 1; 43738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 43758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 43768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, 43798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid, int addr_allocated, 43807a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int freq, int ht40, 43817a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt const struct p2p_channels *channels) 43828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 43838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_go_neg_results params; 43848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int go = 0; 43858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->disabled != 2 || ssid->ssid == NULL) 43878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go) && 43908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go == (ssid->mode == WPAS_MODE_P2P_GO)) { 43918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Requested persistent group is " 43928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "already running"); 43938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 43948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we are not running find during connection establishment */ 4397d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_p2p_stop_find_oper(wpa_s); 43988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 439904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 0; 440004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 44018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_INFRA) 44028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpas_start_p2p_client(wpa_s, ssid, addr_allocated); 44038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GO) 44058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 44068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44077a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, channels)) 44081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 44098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.role_go = 1; 4411d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.psk_set = ssid->psk_set; 4412d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (params.psk_set) 4413d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memcpy(params.psk, ssid->psk, sizeof(params.psk)); 4414a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (ssid->passphrase) { 4415a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) { 4416a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Invalid passphrase in " 4417a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "persistent group"); 4418a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 4419a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 4420a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_strlcpy(params.passphrase, ssid->passphrase, 4421a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(params.passphrase)); 44228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(params.ssid, ssid->ssid, ssid->ssid_len); 44248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = ssid->ssid_len; 44258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.persistent_group = 1; 44268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 1); 44288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 44298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 44308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_start_wps_go(wpa_s, ¶ms, 0); 44328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 44348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 44358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_ie_update(void *ctx, struct wpabuf *beacon_ies, 44388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *proberesp_ies) 44398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 44408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 44418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface) { 44428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = wpa_s->ap_iface->bss[0]; 44431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!(hapd->conf->p2p & P2P_GROUP_OWNER)) { 44441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(beacon_ies); 44451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(proberesp_ies); 44461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 44471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 44488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (beacon_ies) { 44498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_beacon_ie); 44508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_beacon_ie = beacon_ies; 44518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_probe_resp_ie); 44538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_probe_resp_ie = proberesp_ies; 44548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 44558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(beacon_ies); 44568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(proberesp_ies); 44578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ap_update_beacon(wpa_s); 44598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 44608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_idle_update(void *ctx, int idle) 44638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 44648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 44658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->ap_iface) 44668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 44678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO - group %sidle", idle ? "" : "not "); 446804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (idle) 44698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 44708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 44718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL); 44728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 44738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s, 447604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid) 44778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 44788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group *group; 44798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_config *cfg; 44808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 44828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 44838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 44848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 44858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg = os_zalloc(sizeof(*cfg)); 44878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cfg == NULL) 44888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 44898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 449004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid->p2p_persistent_group && wpa_s->conf->persistent_reconnect) 44911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cfg->persistent_group = 2; 449204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else if (ssid->p2p_persistent_group) 44931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cfg->persistent_group = 1; 44948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN); 44958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->max_stations && 44968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->max_stations < wpa_s->conf->max_num_sta) 44978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->max_clients = wpa_s->max_stations; 44988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 44998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->max_clients = wpa_s->conf->max_num_sta; 450004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(cfg->ssid, ssid->ssid, ssid->ssid_len); 450104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cfg->ssid_len = ssid->ssid_len; 45028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->cb_ctx = wpa_s; 45038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->ie_update = wpas_p2p_ie_update; 45048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cfg->idle_update = wpas_p2p_idle_update; 45058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = p2p_group_init(wpa_s->global->p2p, cfg); 45078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (group == NULL) 45088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(cfg); 450904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) 45108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_notif_formation_done(group); 45118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group = group; 45128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return group; 45138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 45178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int registrar) 45188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 451904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 452004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 45218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->p2p_in_provisioning) { 45228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore WPS success event - P2P " 45238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "provisioning not in progress"); 45248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 45258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 452704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_INFRA) { 452804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 452904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(go_dev_addr, wpa_s->bssid, ETH_ALEN); 453004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid, 453104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->ssid_len); 453204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Clear any stored provisioning info */ 453304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_clear_provisioning_info(wpa_s->global->p2p, go_dev_addr); 453404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 45351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 45368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent, 45378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 453804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid && ssid->mode == WPAS_MODE_INFRA) { 453904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 454004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Use a separate timeout for initial data connection to 454104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * complete to allow the group to be removed automatically if 454204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * something goes wrong in this step before the P2P group idle 454304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * timeout mechanism is taken into use. 454404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 454504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0, 454604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_group_formation_timeout, 454704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->parent, NULL); 454804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 45498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 45508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_wps_success_cb(wpa_s->global->p2p, peer_addr); 45518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 45528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_wps_success_cb(wpa_s, peer_addr); 45538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_group_formation_completed(wpa_s, 1); 45548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 455775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s, 455875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen struct wps_event_fail *fail) 455975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 456075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!wpa_s->p2p_in_provisioning) { 456175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_DEBUG, "P2P: Ignore WPS fail event - P2P " 456275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "provisioning not in progress"); 456375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 456475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 45651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 45661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->go_params) { 45671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_clear_provisioning_info( 45681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->global->p2p, 456904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->go_params->peer_device_addr); 45701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 45711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 457275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_wps_failed(wpa_s, fail); 457375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 457475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 457575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 45768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 457704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *config_method, 457804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum wpas_p2p_prov_disc_use use) 45798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 config_methods; 45818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_fallback_to_go_neg = 0; 458304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_use = NORMAL_PD; 45841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_strncmp(config_method, "display", 7) == 0) 45858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config_methods = WPS_CONFIG_DISPLAY; 45861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strncmp(config_method, "keypad", 6) == 0) 45878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config_methods = WPS_CONFIG_KEYPAD; 45881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (os_strncmp(config_method, "pbc", 3) == 0 || 45891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_strncmp(config_method, "pushbutton", 10) == 0) 45908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config_methods = WPS_CONFIG_PUSHBUTTON; 45911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else { 45921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unknown config method"); 45938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 45941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 45958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 459604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (use == WPAS_P2P_PD_AUTO) { 459704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(wpa_s->pending_join_dev_addr, peer_addr, ETH_ALEN); 459804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_config_methods = config_methods; 459904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_pd = 1; 460004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_join = 0; 460104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->pending_pd_before_join = 0; 460204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->auto_pd_scan_retry = 0; 460304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_stop_find(wpa_s); 460404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_join_scan_count = 0; 460504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_get_time(&wpa_s->p2p_auto_started); 460604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Auto PD started at %ld.%06ld", 460704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.sec, 460804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_auto_started.usec); 460904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_join_scan(wpa_s, NULL); 461004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 461104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 461204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 46138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 46148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_prov_disc_req(wpa_s, peer_addr, 461504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt config_methods, 461604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt use == WPAS_P2P_PD_FOR_JOIN); 46178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) 46208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 46218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr, 462304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt config_methods, use == WPAS_P2P_PD_FOR_JOIN, 4624d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 0, 1); 46258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, 46298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end) 46308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_scan_result_text(ies, ies_len, buf, end); 46328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s) 46368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4637a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!offchannel_pending_action_tx(wpa_s)) 46388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 46398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new " 46418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operation request"); 4642a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt offchannel_clear_pending_action_tx(wpa_s); 46438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout, 46478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_discovery_type type, 4648c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt unsigned int num_req_dev_types, const u8 *req_dev_types, 464961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *dev_id, unsigned int search_delay) 46508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clear_pending_action_tx(wpa_s); 46528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 46538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 46558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_find(wpa_s, timeout, type); 46568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 465704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL || 465804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_in_provisioning) 46598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 46608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4661c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 4662c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 46638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_find(wpa_s->global->p2p, timeout, type, 466461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt num_req_dev_types, req_dev_types, dev_id, 466561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt search_delay); 46668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4669d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s) 46708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clear_pending_action_tx(wpa_s); 46728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 46738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 46748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); 4675dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen wpa_s->global->p2p_cb_on_scan_complete = 0; 46768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { 46788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_p2p_stop_find(wpa_s); 4679d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 46808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 46818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 46838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_stop_find(wpa_s->global->p2p); 46848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4685d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 4686d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 4687d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4688d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4689d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid wpas_p2p_stop_find(struct wpa_supplicant *wpa_s) 4690d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 4691d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpas_p2p_stop_find_oper(wpa_s) > 0) 4692d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 46938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_remove_pending_group_interface(wpa_s); 46948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx) 46988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 46998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 47008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 47018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout) 47058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 47068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 47078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 47098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 47108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4711c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 47128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_clear_pending_action_tx(wpa_s); 47138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout == 0) { 47158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 47168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is a request for unlimited Listen state. However, at 47178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * least for now, this is mapped to a Listen state for one 47188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hour. 47198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 47208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = 3600; 47218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 47228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); 47238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 47248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 47261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Stop previous find/listen operation to avoid trying to request a new 47271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * remain-on-channel operation while the driver is still running the 47281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * previous one. 47291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 47301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->global->p2p) 47311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt p2p_stop_find(wpa_s->global->p2p); 47321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 47338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpas_p2p_listen_start(wpa_s, timeout * 1000); 47348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) { 47358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = timeout * 1000; 47368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, 47378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_long_listen_timeout, 47388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s, NULL); 47398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 47408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 47428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, 47468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len, int p2p_group) 47478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 47488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_ie; 47498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 47508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 47528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 47538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 47548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 47558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) 47568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 47578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE); 47598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len, 47608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group, p2p_ie); 47618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_ie); 47628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 47648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, 47681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *dst, const u8 *bssid, 476904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *ie, size_t ie_len, int ssi_signal) 47708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 47718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 47728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 47738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 47748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 47758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 477604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid, 477704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie, ie_len)) { 477804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_NOT_P2P: 477904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len, 478004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssi_signal); 478104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* fall through */ 478204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_MALFORMED: 478304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_NOT_LISTEN: 478404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_NOT_PROCESSED: 478504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt default: /* make gcc happy */ 478604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 478704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case P2P_PREQ_PROCESSED: 478804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 478904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 47908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 47918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da, 47948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *sa, const u8 *bssid, 47958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 category, const u8 *data, size_t len, int freq) 47968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 47978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 47988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 47998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 48008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 48018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len, 48038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq); 48048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies) 48088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled) 48108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 48118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p == NULL) 48128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 48138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4814c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p_scan_ie(wpa_s->global->p2p, ies, NULL); 48158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s) 48198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_deinit(wpa_s->p2p_group); 48218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_group = NULL; 48221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 48231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ap_configured_cb = NULL; 48241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ap_configured_cb_ctx = NULL; 48251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ap_configured_cb_data = NULL; 48261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->connect_without_scan = NULL; 48278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr) 48318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->p2p_long_listen = 0; 48338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 48358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_reject(wpa_s, addr); 48368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 48388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_reject(wpa_s->global->p2p, addr); 48418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 48428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Invite to reinvoke a persistent group */ 48458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, 484631be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, 48477a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int ht40, int pref_freq) 48488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 48498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_invite_role role; 48507a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt u8 *bssid = NULL, bssid_buf[ETH_ALEN]; 4851af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff int force_freq = 0, oper_freq = 0; 48527a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int res; 48537a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 4854700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->global->p2p_invite_group = NULL; 48557a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (peer_addr) 48567a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); 48577a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt else 48587a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 48598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 486031be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_persistent_go_freq = freq; 486131be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_go_ht40 = !!ht40; 48628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 48638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_GO; 48648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer_addr == NULL) { 48658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Missing peer " 48668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "address in invitation command"); 48678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 48698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_create_iface(wpa_s)) { 48708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_add_group_interface(wpa_s, 48718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_IF_P2P_GO) < 0) { 48728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to " 48738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "allocate a new interface for the " 48748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "group"); 48758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 48768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 48778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->pending_interface_addr; 48788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 48798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->own_addr; 48808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 48818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_CLIENT; 48828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer_addr = ssid->bssid; 48838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 48848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->pending_invite_ssid_id = ssid->id; 48858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48867a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid_buf) == 0 && 48877a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->assoc_freq) { 4888af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff oper_freq = wpa_s->assoc_freq; 48897a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (bssid == NULL) 48907a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt bssid = bssid_buf; 48917a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else { 4892af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff oper_freq = wpa_drv_shared_freq(wpa_s); 4893af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff if (oper_freq < 0) 4894af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff oper_freq = 0; 4895af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff } 4896af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff 48977a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq, 48987a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt &oper_freq); 48997a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (res) 49007a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return res; 4901af84a575044f6556994fcc124a955fc0ac0a6736Irfan Sheriff 49028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 49038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_invite(wpa_s, peer_addr, role, bssid, 49048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid, ssid->ssid_len, 49058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_dev_addr, 1); 49068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 49088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, 49117a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr, 49127a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 1, pref_freq); 49138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 49148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Invite to join an active group */ 49178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, 49188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer_addr, const u8 *go_dev_addr) 49198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global = wpa_s->global; 49218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_invite_role role; 49227a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt u8 *bssid = NULL, bssid_buf[ETH_ALEN]; 49238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 4924c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt int persistent; 49257a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int force_freq = 0, oper_freq = 0, pref_freq = 0; 49267a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt int res; 49278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 492831be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_persistent_go_freq = 0; 492931be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen wpa_s->p2p_go_ht40 = 0; 493031be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen 49318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 49328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(wpa_s->ifname, ifname) == 0) 49338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 49348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) { 49368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Interface '%s' not found", ifname); 49378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 49418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 49428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No current SSID to use for " 49438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invitation"); 49448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4947700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpa_s->global->p2p_invite_group = wpa_s; 4948c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt persistent = ssid->p2p_persistent_group && 4949c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpas_p2p_get_persistent(wpa_s->parent, peer_addr, 4950c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt ssid->ssid, ssid->ssid_len); 4951c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 49528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->mode == WPAS_MODE_P2P_GO) { 49538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_ACTIVE_GO; 49548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->own_addr; 49558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go_dev_addr == NULL) 49561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt go_dev_addr = wpa_s->global->p2p_dev_addr; 49578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 49588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt role = P2P_INVITE_ROLE_CLIENT; 49598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state < WPA_ASSOCIATED) { 49608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Not associated - cannot " 49618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invite to current group"); 49628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid = wpa_s->bssid; 49658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go_dev_addr == NULL && 49668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(wpa_s->go_dev_addr)) 49678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go_dev_addr = wpa_s->go_dev_addr; 49688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 49698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent->pending_invite_ssid_id = -1; 49708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 49728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_drv_p2p_invite(wpa_s, peer_addr, role, bssid, 49738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid, ssid->ssid_len, 4974c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt go_dev_addr, persistent); 49758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 49778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 49788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 49797a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid_buf) == 0 && 49807a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt wpa_s->assoc_freq) { 49817a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt oper_freq = wpa_s->assoc_freq; 49827a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (bssid == NULL) 49837a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt bssid = bssid_buf; 49847a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } else { 49857a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt oper_freq = wpa_drv_shared_freq(wpa_s); 49867a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (oper_freq < 0) 49877a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt oper_freq = 0; 49887a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 49897a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 49907a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt res = wpas_p2p_setup_freqs(wpa_s, 0, &force_freq, &pref_freq, 49917a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt &oper_freq); 49927a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt if (res) 49937a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return res; 4994700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt wpas_p2p_set_own_freq_preference(wpa_s, oper_freq); 49957a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 49968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, 49977a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt ssid->ssid, ssid->ssid_len, force_freq, 49987a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt go_dev_addr, persistent, pref_freq); 49998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_completed(struct wpa_supplicant *wpa_s) 50038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 50058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ssid_txt; 50068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 500775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int network_id = -1; 50088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int persistent; 50091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int freq; 50108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 501104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) { 501204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 501304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->parent, NULL); 501404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 501504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 50168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->show_group_started || !ssid) 501761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto done; 50188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->show_group_started = 0; 50208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len); 50228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(go_dev_addr, 0, ETH_ALEN); 50238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->bssid_set) 50248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(go_dev_addr, ssid->bssid, ETH_ALEN); 50258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent = wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid, 50268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len); 50278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->go_dev_addr, go_dev_addr, ETH_ALEN); 50288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_group_formation == wpa_s) 50308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->p2p_group_formation = NULL; 50318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = wpa_s->current_bss ? wpa_s->current_bss->freq : 50331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (int) wpa_s->assoc_freq; 50348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->passphrase == NULL && ssid->psk_set) { 50358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char psk[65]; 50368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32); 50378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 50388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s client ssid=\"%s\" freq=%d psk=%s go_dev_addr=" 50398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR "%s", 50401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ifname, ssid_txt, freq, psk, 50418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_dev_addr), 50428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent ? " [PERSISTENT]" : ""); 50438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 50448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED 50458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s client ssid=\"%s\" freq=%d passphrase=\"%s\" " 50468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "go_dev_addr=" MACSTR "%s", 50471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->ifname, ssid_txt, freq, 50488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->passphrase ? ssid->passphrase : "", 50498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(go_dev_addr), 50508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt persistent ? " [PERSISTENT]" : ""); 50518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 50528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (persistent) 505475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = wpas_p2p_store_persistent_group(wpa_s->parent, 505575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ssid, go_dev_addr); 505675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (network_id < 0) 505775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen network_id = ssid->id; 505875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 1); 505961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 506061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtdone: 506137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpas_p2p_continue_after_scan(wpa_s); 50628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1, 50668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 interval1, u32 duration2, u32 interval2) 50678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 50698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 50708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 50718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 50728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state < WPA_ASSOCIATED || 50748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid == NULL || 50758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->mode != WPAS_MODE_INFRA) 50768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 50778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid, 50798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->own_addr, wpa_s->assoc_freq, 50808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt duration1, interval1, duration2, interval2); 50818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period, 50858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int interval) 50868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 50878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 50888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 50898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 50918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 50928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_ext_listen(wpa_s->global->p2p, period, interval); 50948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 50958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_p2p_is_client(struct wpa_supplicant *wpa_s) 50981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 5099d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->current_ssid == NULL) { 5100d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 5101d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * current_ssid can be cleared when P2P client interface gets 5102d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * disconnected, so assume this interface was used as P2P 5103d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * client. 5104d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 5105d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 5106d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 5107d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return wpa_s->current_ssid->p2p_group && 51081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->current_ssid->mode == WPAS_MODE_INFRA; 51091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 51101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 51111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 51128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx) 51138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 51148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 51158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) { 51178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - " 51188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "disabled"); 51198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 51208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 51218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 512204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Group idle timeout reached - terminate " 512304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "group"); 512461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_IDLE_TIMEOUT); 51258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 51268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s) 51298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 513004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int timeout; 513104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 513204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0) 513304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout"); 51341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 51351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group) 51368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 51378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout = wpa_s->conf->p2p_group_idle; 51391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA && 51401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE)) 51411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout = P2P_MAX_CLIENT_IDLE; 51421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 51431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (timeout == 0) 51448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 51458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 514604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (timeout < 0) { 514704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA) 514804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt timeout = 0; /* special client mode no-timeout */ 514904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 515004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 515104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 515204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 515304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_in_provisioning) { 515404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 515504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Use the normal group formation timeout during the 515604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * provisioning phase to avoid terminating this process too 515704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * early due to group idle timeout. 515804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 515904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout " 516004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "during provisioning"); 516104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 516204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5163ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt#ifndef ANDROID_P2P 516404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->show_group_started) { 516504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 516604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Use the normal group formation timeout between the end of 516704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * the provisioning phase and completion of 4-way handshake to 516804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * avoid terminating this process too early due to group idle 516904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * timeout. 517004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 517104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout " 517204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "while waiting for initial 4-way handshake to " 517304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "complete"); 517404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 517504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5176ad266fb3da6083126e7619e525153839b918aa44Dmitry Shmidt#endif 517704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 51788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds", 51791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt timeout); 51801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout, 51811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL); 51828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 51838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 51852b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen/* Returns 1 if the interface was removed */ 51862b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenint wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, 51872b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen u16 reason_code, const u8 *ie, size_t ie_len, 51882b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen int locally_generated) 51898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 51908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 51912b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 0; 51928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 51932b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 0; 51948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 519504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!locally_generated) 519604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie, 519704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie_len); 519804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 519904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (reason_code == WLAN_REASON_DEAUTH_LEAVING && !locally_generated && 520004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid && 520104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid->p2p_group && 520204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid->mode == WPAS_MODE_INFRA) { 520304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group " 520404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "session is ending"); 52052b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen if (wpas_p2p_group_delete(wpa_s, 52062b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen P2P_GROUP_REMOVAL_GO_ENDING_SESSION) 52072b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen > 0) 52082b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 1; 520904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 52102b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen 52112b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return 0; 52128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 52138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid, 521604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 reason_code, const u8 *ie, size_t ie_len, 521704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int locally_generated) 52188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 52198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 52208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 52218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 52228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 52238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 522404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!locally_generated) 522504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie, 522604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie_len); 52278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 52288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_config(struct wpa_supplicant *wpa_s) 52318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 52328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 52338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL) 52358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 52368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)) 52388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 52398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME) 52418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_dev_name(p2p, wpa_s->conf->device_name); 52428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) 52448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type); 52458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wps && 52478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS)) 52488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_config_methods(p2p, wpa_s->wps->config_methods); 52498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wps && (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID)) 52518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_uuid(p2p, wpa_s->wps->uuid); 52528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_WPS_STRING) { 52548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_manufacturer(p2p, wpa_s->conf->manufacturer); 52558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_model_name(p2p, wpa_s->conf->model_name); 52568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_model_number(p2p, wpa_s->conf->model_number); 52578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_serial_number(p2p, wpa_s->conf->serial_number); 52588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) 52618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_sec_dev_types(p2p, 52628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (void *) wpa_s->conf->sec_device_type, 52638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->num_sec_device_types); 52648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION) { 52668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 52678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_remove_wps_vendor_extensions(p2p); 52688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) { 52698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->wps_vendor_ext[i] == NULL) 52708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 52718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_add_wps_vendor_extension( 52728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p, wpa_s->conf->wps_vendor_ext[i]); 52738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) && 52778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->country[0] && wpa_s->conf->country[1]) { 52788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char country[3]; 52798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[0] = wpa_s->conf->country[0]; 52808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[1] = wpa_s->conf->country[1]; 52818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[2] = 0x04; 52828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_country(p2p, country); 52838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_SSID_POSTFIX) { 52868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_ssid_postfix(p2p, (u8 *) wpa_s->conf->p2p_ssid_postfix, 52878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->p2p_ssid_postfix ? 52888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(wpa_s->conf->p2p_ssid_postfix) : 52898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0); 52908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_INTRA_BSS) 52938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_intra_bss_dist(p2p, wpa_s->conf->p2p_intra_bss); 529475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 529575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_LISTEN_CHANNEL) { 529675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen u8 reg_class, channel; 529775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int ret; 529875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen unsigned int r; 529975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->p2p_listen_reg_class && 530075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->conf->p2p_listen_channel) { 530175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen reg_class = wpa_s->conf->p2p_listen_reg_class; 530275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen channel = wpa_s->conf->p2p_listen_channel; 530375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 530475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen reg_class = 81; 530575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 530675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Pick one of the social channels randomly as the 530775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * listen channel. 530875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 530975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_get_random((u8 *) &r, sizeof(r)); 531075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen channel = 1 + (r % 3) * 5; 531175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 531275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ret = p2p_set_listen_channel(p2p, reg_class, channel); 531375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ret) 531475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_ERROR, "P2P: Own listen channel update " 531575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "failed: %d", ret); 531675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 531775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_OPER_CHANNEL) { 531875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen u8 op_reg_class, op_channel, cfg_op_channel; 531975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen int ret = 0; 532075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen unsigned int r; 532175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (wpa_s->conf->p2p_oper_reg_class && 532275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->conf->p2p_oper_channel) { 532375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_reg_class = wpa_s->conf->p2p_oper_reg_class; 532475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_channel = wpa_s->conf->p2p_oper_channel; 532575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen cfg_op_channel = 1; 532675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } else { 532775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_reg_class = 81; 532875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 532975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Use random operation channel from (1, 6, 11) 533075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *if no other preference is indicated. 533175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 533275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_get_random((u8 *) &r, sizeof(r)); 533375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen op_channel = 1 + (r % 3) * 5; 533475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen cfg_op_channel = 0; 533575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 533675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen ret = p2p_set_oper_channel(p2p, op_reg_class, op_channel, 533775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen cfg_op_channel); 533875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ret) 533975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_ERROR, "P2P: Own oper channel update " 534075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "failed: %d", ret); 534175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 534204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 534304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PREF_CHAN) { 534404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_set_pref_chan(p2p, wpa_s->conf->num_p2p_pref_chan, 534504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->conf->p2p_pref_chan) < 0) { 534604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Preferred channel list " 534704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "update failed"); 534804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 534904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 53508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 53518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start, 53548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int duration) 53558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 53568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->ap_iface) 53578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 53588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start, 53598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt duration); 53608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 53618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled) 53648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 53658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 53668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 53678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) 53688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 53698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->global->cross_connection = enabled; 53718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_cross_connect(wpa_s->global->p2p, enabled); 53728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!enabled) { 53748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 53758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) 53778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 53788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->cross_connect_enabled == 0) 53798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 53808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_enabled = 0; 53828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_in_use = 0; 53838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(iface->parent, MSG_INFO, 53848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s", 53858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->ifname, iface->cross_connect_uplink); 53868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 53878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 53888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 53908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 53918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink) 53948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 53958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 53968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!uplink->global->cross_connection) 53988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 53998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = uplink->global->ifaces; iface; iface = iface->next) { 54018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface->cross_connect_enabled) 54028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) != 54048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 54058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->ap_iface == NULL) 54078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->cross_connect_in_use) 54098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_in_use = 1; 54128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(iface->parent, MSG_INFO, 54138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s", 54148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->ifname, iface->cross_connect_uplink); 54158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 54168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 54178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink) 54208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 54218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 54228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = uplink->global->ifaces; iface; iface = iface->next) { 54248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface->cross_connect_enabled) 54258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) != 54278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 54288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface->cross_connect_in_use) 54308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(iface->parent, MSG_INFO, 54338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s", 54348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->ifname, iface->cross_connect_uplink); 54358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_in_use = 0; 54368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 54378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 54388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s) 54418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 54428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ap_iface || wpa_s->current_ssid == NULL || 54438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->mode != WPAS_MODE_INFRA || 54448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_disallowed) 54458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_disable_cross_connect(wpa_s); 54468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 54478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_enable_cross_connect(wpa_s); 544804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->ap_iface && 544904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0) 545004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout"); 54518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 54528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s) 54558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 54568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_disable_cross_connect(wpa_s); 54571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->ap_iface && 54581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !eloop_is_timeout_registered(wpas_p2p_group_idle_timeout, 54591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL)) 54608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_set_group_idle_timeout(wpa_s); 54618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 54628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s) 54658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 54668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *iface; 54678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_s->global->cross_connection) 54698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 54708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { 54728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface == wpa_s) 54738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->drv_flags & 54758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE) 54768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) 54788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 54798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_enabled = 1; 54818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname, 54828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->cross_connect_uplink)); 54838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from " 54848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s to %s whenever uplink is available", 54858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname, wpa_s->cross_connect_uplink); 54868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->ap_iface || iface->current_ssid == NULL || 54888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->current_ssid->mode != WPAS_MODE_INFRA || 54898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->cross_connect_disallowed || 54908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->wpa_state != WPA_COMPLETED) 54918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 54928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->cross_connect_in_use = 1; 54948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s->parent, MSG_INFO, 54958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s", 54968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname, wpa_s->cross_connect_uplink); 54978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 54988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 54998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 55008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s) 55038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 55048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT && 55058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !wpa_s->p2p_in_provisioning) 55068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* not P2P client operation */ 55078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Terminate connection due to WPS PBC " 55098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "session overlap"); 55108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s != wpa_s->parent) 55118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_ctrl(wpa_s->parent, MSG_INFO, WPS_EVENT_OVERLAP); 55128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) 55148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_formation_failed(wpa_s->global->p2p); 55158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 55178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent, NULL); 55188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_group_formation_completed(wpa_s, 0); 55208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 55218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 55228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s) 55258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 55268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels chan; 55278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global == NULL || wpa_s->global->p2p == NULL) 55298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 55308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&chan, 0, sizeof(chan)); 55328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_p2p_setup_channels(wpa_s, &chan)) { 55338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "P2P: Failed to update supported " 55348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel list"); 55358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 55368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 55378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_update_channel_list(wpa_s->global->p2p, &chan); 55398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 55408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5542a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void wpas_p2p_scan_res_ignore(struct wpa_supplicant *wpa_s, 5543a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt struct wpa_scan_results *scan_res) 5544a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 5545a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Ignore scan results"); 5546a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 5547a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 5548a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 55498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_cancel(struct wpa_supplicant *wpa_s) 55508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 55518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_global *global = wpa_s->global; 55528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int found = 0; 55538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *peer; 55548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->p2p == NULL) 55568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 55578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Request to cancel group formation"); 55598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->pending_interface_name[0] && 55618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !is_zero_ether_addr(wpa_s->pending_interface_addr)) 55628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 55638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer = p2p_get_go_neg_peer(global->p2p); 55658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer) { 55668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Unauthorize pending GO Neg peer " 55678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(peer)); 55688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_unauthorize(global->p2p, peer); 556904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt found = 1; 55708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 55718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5572a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->scan_res_handler == wpas_p2p_scan_res_join) { 5573a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Stop pending scan for join"); 5574a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore; 5575a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt found = 1; 5576a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 5577a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 5578a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->pending_pd_before_join) { 5579a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Stop pending PD before join"); 5580a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->pending_pd_before_join = 0; 5581a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt found = 1; 5582a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 5583a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 55848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_p2p_stop_find(wpa_s); 55858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 55878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == global->p2p_group_formation && 55888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpa_s->p2p_in_provisioning || 55898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent->pending_interface_type == 55908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_IF_P2P_CLIENT)) { 55918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Interface %s in group " 55928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "formation found - cancelling", 55938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ifname); 55948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 55958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 55968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->parent, NULL); 5597adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen if (wpa_s->p2p_in_provisioning) { 5598adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen wpas_group_formation_completed(wpa_s, 0); 5599adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen break; 5600adddfc48d2d7bfa2b1a2405ab8f404b6383ec236Jouni Malinen } 560161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, 560261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_GROUP_REMOVAL_REQUESTED); 56038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 56048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 56088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No ongoing group formation found"); 56098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 56108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 56118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 56138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s) 56178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group) 56198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 56208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not " 56228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "being available anymore"); 562361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_UNAVAILABLE); 56248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s, 56288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq_24, int freq_5, int freq_overall) 56298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 56318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)) 56328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 56338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_set_best_channels(p2p, freq_24, freq_5, freq_overall); 56348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr) 56388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 peer[ETH_ALEN]; 56408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 56418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p == NULL || (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)) 56438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 56448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(addr, peer)) 56468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 56478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_unauthorize(p2p, peer); 56498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 56538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_p2p_disconnect - Disconnect from a P2P Group 56548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 56558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 56568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 56578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This can be used to disconnect from a group in which the local end is a P2P 56588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Client or to end a P2P Group in case the local end is the Group Owner. If a 56598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * virtual network interface was created for this group, that interface will be 56608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * removed. Otherwise, only the configured P2P group network will be removed 56618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from the interface. 56628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 56638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_p2p_disconnect(struct wpa_supplicant *wpa_s) 56648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 56658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s == NULL) 56678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 56688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56692b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED) < 0 ? 56702b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen -1 : 0; 56718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 56721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 56731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 56741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpas_p2p_in_progress(struct wpa_supplicant *wpa_s) 56751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 5676f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt int ret; 5677f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 56781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 56791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 56801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5681f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt ret = p2p_in_progress(wpa_s->global->p2p); 5682f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (ret == 0) { 5683f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 5684f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Check whether there is an ongoing WPS provisioning step (or 5685f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * other parts of group formation) on another interface since 5686f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * p2p_in_progress() does not report this to avoid issues for 5687f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * scans during such provisioning step. 5688f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 5689f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (wpa_s->global->p2p_group_formation && 5690f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_s->global->p2p_group_formation != wpa_s) { 5691f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Another interface (%s) " 5692f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "in group formation", 5693f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_s->global->p2p_group_formation->ifname); 5694f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt ret = 1; 5695f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 5696f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 5697f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 5698f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return ret; 56991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 57001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpas_p2p_network_removed(struct wpa_supplicant *wpa_s, 57031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *ssid) 57041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 57051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->p2p_in_provisioning && ssid->p2p_group && 57061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(wpas_p2p_group_formation_timeout, 57071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->parent, NULL) > 0) { 570804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /** 570904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Remove the network by scheduling the group formation 571004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * timeout to happen immediately. The teardown code 571104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * needs to be scheduled to run asynch later so that we 571204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * don't delete data from under ourselves unexpectedly. 571304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Calling wpas_p2p_group_formation_timeout directly 571404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * causes a series of crashes in WPS failure scenarios. 571504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 57161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to " 57171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P group network getting removed"); 571804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout, 571904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->parent, NULL); 57201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 57211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 57221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s, 5725c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt const u8 *addr, const u8 *ssid, 5726c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt size_t ssid_len) 57271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 57281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *s; 57291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t i; 57301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (s = wpa_s->conf->ssid; s; s = s->next) { 57321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->disabled != 2) 57331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 5734c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid && 5735c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt (ssid_len != s->ssid_len || 5736c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memcmp(ssid, s->ssid, ssid_len) != 0)) 5737c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt continue; 57381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0) 57391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return s; /* peer is GO in the persistent group */ 57401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL) 57411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 57421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; i < s->num_p2p_clients; i++) { 57431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, 57441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt addr, ETH_ALEN) == 0) 57451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return s; /* peer is P2P client in persistent 57461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * group */ 57471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 57481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 57491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 57511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 57521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 57541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s, 57551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *addr) 57561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 57571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (addr == NULL) 57581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 57591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_add_persistent_group_client(wpa_s, addr); 57601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 5761c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 576204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 576304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s, 576404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int group_added) 576504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 576604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *group = wpa_s; 576704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->global->p2p_group_formation) 576804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt group = wpa_s->global->p2p_group_formation; 576904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s = wpa_s->parent; 577004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt offchannel_send_action_done(wpa_s); 577104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (group_added) 577261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(group, P2P_GROUP_REMOVAL_SILENT); 577304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Fall back to GO Negotiation"); 577404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin, 577504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0, 577604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq, 577704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_persistent_id, 577861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_pd_before_go_neg, 577961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->p2p_go_ht40); 578004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 578104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 578204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 578304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s) 578404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 578504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->p2p_fallback_to_go_neg || 578604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->p2p_in_provisioning <= 5) 578704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 578804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 578904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr) > 0) 579004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; /* peer operating as a GO */ 579104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 579204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: GO not found for p2p_connect-auto - " 579304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "fallback to GO Negotiation"); 579404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_p2p_fallback_to_go_neg(wpa_s, 1); 579504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 579604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 579704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 579804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 579961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 580061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtunsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s) 580161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 580261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *rn, *rn2; 580361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpa_supplicant *ifs; 580461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 580561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->wpa_state > WPA_SCANNING) { 580661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search delay due to " 580761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "concurrent operation", 580861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_CONCURRENT_SEARCH_DELAY); 580961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return P2P_CONCURRENT_SEARCH_DELAY; 581061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 581161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 581261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!wpa_s->driver->get_radio_name) 581361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 581461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv); 581561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (rn == NULL || rn[0] == '\0') 581661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 581761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 581861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { 581961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ifs == wpa_s || !ifs->driver->get_radio_name) 582061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 582161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 582261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt rn2 = ifs->driver->get_radio_name(ifs->drv_priv); 582361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!rn2 || os_strcmp(rn, rn2) != 0) 582461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 582561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ifs->wpa_state > WPA_SCANNING) { 582661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search " 582761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "delay due to concurrent operation on " 582861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "interface %s", 582961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt P2P_CONCURRENT_SEARCH_DELAY, ifs->ifname); 583061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return P2P_CONCURRENT_SEARCH_DELAY; 583161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 583261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 583361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 583461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 583561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 583661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 583737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 583837d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidtvoid wpas_p2p_continue_after_scan(struct wpa_supplicant *wpa_s) 583937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt{ 584037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Station mode scan operation not " 584137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt "pending anymore (sta_scan_pending=%d " 584237d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt "p2p_cb_on_scan_complete=%d)", wpa_s->sta_scan_pending, 584337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_s->global->p2p_cb_on_scan_complete); 584437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_s->sta_scan_pending = 0; 584537d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 584637d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt if (!wpa_s->global->p2p_cb_on_scan_complete) 584737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt return; 584837d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_s->global->p2p_cb_on_scan_complete = 0; 584937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 585037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) 585137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt return; 585237d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 585337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) { 585437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation " 585537d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt "continued after successful connection"); 585637d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt p2p_increase_search_delay(wpa_s->global->p2p, 585737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpas_p2p_search_delay(wpa_s)); 585837d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt } 585937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt} 586037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 5861c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef ANDROID_P2P 5862d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq, 5863d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ssid *ssid) 5864c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{ 5865c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct wpa_supplicant *iface = NULL; 5866c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct p2p_data *p2p = wpa_s->global->p2p; 5867c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 5868c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { 586912b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson if ((iface->current_ssid) && 587012b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson (iface->current_ssid->frequency != freq) && 587112b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson ((iface->p2p_group_interface) || 587212b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson (iface->current_ssid->p2p_group))) { 587312b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson 587412b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson if ((iface->p2p_group_interface == P2P_GROUP_INTERFACE_GO) || 587512b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson (iface->current_ssid->mode == WPAS_MODE_P2P_GO)) { 587612b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson /* Try to see whether we can move the GO. If it 587712b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson * is not possible, remove the GO interface 587812b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson */ 587912b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson if (wpa_drv_switch_channel(iface, freq) == 0) { 588012b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson wpa_printf(MSG_ERROR, "P2P: GO Moved to freq(%d)", freq); 588112b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson iface->current_ssid->frequency = freq; 588212b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson continue; 588312b1cd9e151d1e5c4d35aa38531f38b4ef5cc805Jeff Johnson } 5884c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 5885c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 5886c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* If GO cannot be moved or if the conflicting interface is a 5887c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * P2P Client, remove the interface depending up on the connection 5888c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * priority */ 5889d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if(!wpas_is_p2p_prioritized(iface)) { 5890f4f5db315918f3f048324ea43dc37a3b0fb31eccDmitry Shmidt /* STA connection has priority over existing 5891c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * P2P connection. So remove the interface */ 5892d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Removing P2P connection due to Single channel" 5893687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt "concurrent mode frequency conflict"); 589461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_group_delete(iface, P2P_GROUP_REMOVAL_FREQ_CONFLICT); 5895d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* If connection in progress is p2p connection, do not proceed for the connection */ 5896d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s == iface) 5897d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 5898d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else 5899d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* If connection in progress is STA connection, proceed for the connection */ 5900d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 5901c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else { 5902d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* P2p connection has priority, disable the STA network*/ 5903d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_supplicant_disable_network(wpa_s->global->ifaces, ssid); 5904d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_msg(wpa_s->global->ifaces, MSG_INFO, WPA_EVENT_FREQ_CONFLICT 5905d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt " id=%d", ssid->id); 5906d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_memset(wpa_s->global->ifaces->pending_bssid, 0, ETH_ALEN); 5907d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s == iface) { 5908d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* p2p connection is in progress, continue connecting...*/ 5909d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 5910d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 5911d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else { 5912d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* STA connection is in progress, do not allow to continue */ 5913d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 5914d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 5915c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 5916c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 5917c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 5918c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt return 0; 5919c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 5920c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif 5921