events.c revision 4dd28dc25895165566a1c8a9cac7bcd755ff8fe3
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - Driver event processing
3807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
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 "eapol_supp/eapol_supp_sm.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/wpa.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "l2_packet/l2_packet.h"
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pcsc_funcs.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/preauth.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/pmksa_cache.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h"
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_peer/eap.h"
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/hostapd.h"
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h"
2661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "wnm_sta.h"
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h"
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h"
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h"
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "blacklist.h"
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpas_glue.h"
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h"
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ibss_rsn.h"
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sme.h"
361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "gas_query.h"
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h"
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bgscan.h"
3904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "autoscan.h"
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap.h"
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h"
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h"
431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "offchannel.h"
4461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "interworking.h"
456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "mesh.h"
466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "mesh_mpm.h"
476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "wmm_ac.h"
4861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
4961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
5034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifndef CONFIG_NO_SCAN_PROCESSING
518da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidtstatic int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
52e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt					      int new_scan, int own_request);
5334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
544b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
554b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
5661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int wpas_temp_disabled(struct wpa_supplicant *wpa_s,
5761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			      struct wpa_ssid *ssid)
5861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
59fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct os_reltime now;
6061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
6161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid == NULL || ssid->disabled_until.sec == 0)
6261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return 0;
6361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
64fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_get_reltime(&now);
6561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid->disabled_until.sec > now.sec)
6661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return ssid->disabled_until.sec - now.sec;
6761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
6861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpas_clear_temp_disabled(wpa_s, ssid, 0);
6961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
7061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
7161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
74cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic struct wpa_bss * wpa_supplicant_get_new_bss(
75cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_supplicant *wpa_s, const u8 *bssid)
76cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
77cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_bss *bss = NULL;
78cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
79cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
80cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (ssid->ssid_len > 0)
81cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len);
82cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (!bss)
83cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		bss = wpa_bss_get_bssid(wpa_s, bssid);
84cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
85cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return bss;
86cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
87cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
88cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
895c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinenstatic void wpa_supplicant_update_current_bss(struct wpa_supplicant *wpa_s)
905c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen{
915c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, wpa_s->bssid);
925c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
935c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	if (!bss) {
945c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		wpa_supplicant_update_scan_results(wpa_s);
955c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
965c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		/* Get the BSS from the new scan results */
975c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		bss = wpa_supplicant_get_new_bss(wpa_s, wpa_s->bssid);
985c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	}
995c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
1005c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	if (bss)
1015c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		wpa_s->current_bss = bss;
1025c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen}
1035c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
1045c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid, *old_ssid;
10861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int res;
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1105c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid) {
1115c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		wpa_supplicant_update_current_bss(wpa_s);
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1135c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	}
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Select network based on association "
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"information");
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_supplicant_get_ssid(wpa_s);
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO,
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"No network configuration found for the current AP");
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpas_network_disabled(wpa_s, ssid)) {
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is disabled");
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
129d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (disallowed_bssid(wpa_s, wpa_s->bssid) ||
130d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	    disallowed_ssid(wpa_s, ssid->ssid, ssid->ssid_len)) {
131d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS is disallowed");
132d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return -1;
133d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
134d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	res = wpas_temp_disabled(wpa_s, ssid);
13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (res > 0) {
13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is temporarily "
13861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			"disabled for %d second(s)", res);
13961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
14061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
14161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Network configuration found for the "
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"current AP");
1441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 wpa_ie[80];
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		size_t wpa_ie_len = sizeof(wpa_ie);
147a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
148a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt					      wpa_ie, &wpa_ie_len) < 0)
149a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Could not set WPA suites");
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid && wpa_s->current_ssid != ssid)
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_invalidate_cached_session(wpa_s->eapol);
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ssid = wpa_s->current_ssid;
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_ssid = ssid;
158cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1595c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	wpa_supplicant_update_current_bss(wpa_s);
160cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_initiate_eapol(wpa_s);
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ssid != wpa_s->current_ssid)
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_changed(wpa_s);
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx)
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->countermeasures) {
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->countermeasures = 0;
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_countermeasures(wpa_s, 0);
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped");
1787f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
1797f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		/*
1807f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * It is possible that the device is sched scanning, which means
1817f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * that a connection attempt will be done only when we receive
1827f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * scan results. However, in this case, it would be preferable
1837f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * to scan and connect immediately, so cancel the sched_scan and
1847f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * issue a regular scan flow.
1857f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 */
1867f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_supplicant_cancel_sched_scan(wpa_s);
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int bssid_changed;
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wnm_bss_keep_alive_deinit(wpa_s);
19704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ibss_rsn_deinit(wpa_s->ibss_rsn);
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ibss_rsn = NULL;
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
203c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt#ifdef CONFIG_AP
204c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	wpa_supplicant_ap_deinit(wpa_s);
205c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt#endif /* CONFIG_AP */
206c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(wpa_s->bssid, 0, ETH_ALEN);
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	sme_clear_on_disassoc(wpa_s);
215c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_P2P
216c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
217c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_P2P */
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_bss = NULL;
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->assoc_freq = 0;
220c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bssid_changed)
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_bssid_changed(wpa_s);
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ap_ies_from_associnfo = 0;
22961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->current_ssid = NULL;
230b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
23161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->key_mgmt = 0;
2326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
2336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpas_rrm_reset(wpa_s);
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ie_data ie;
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pmksa_set = -1;
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ie.pmkid == NULL)
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < ie.num_pmkid; i++) {
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pmksa_set = pmksa_cache_set_current(wpa_s->wpa,
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    ie.pmkid + i * PMKID_LEN,
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    NULL, NULL, 0);
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pmksa_set == 0) {
252216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID from assoc IE %sfound from "
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"PMKSA cache", pmksa_set == 0 ? "" : "not ");
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s,
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 union wpa_event_data *data)
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL) {
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: No data in PMKID candidate "
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"event");
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		" index=%d preauth=%d",
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(data->pmkid_candidate.bssid),
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		data->pmkid_candidate.index,
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		data->pmkid_candidate.preauth);
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid,
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->pmkid_candidate.index,
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->pmkid_candidate.preauth);
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid &&
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !(wpa_s->current_ssid->eapol_flags &
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	      (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) {
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* IEEE 802.1X, but not using dynamic WEP keys (i.e., either
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * plaintext or static WEP keys). */
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 1;
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_scard_init - Initialize SIM/USIM access with PC/SC
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: pointer to wpa_supplicant data
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: Configuration data for the network
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when starting authentication with a network that is
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured to use PC/SC for SIM/USIM access (EAP-SIM or EAP-AKA).
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      struct wpa_ssid *ssid)
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
3171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef PCSC_FUNCS
318391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	int aka = 0, sim = 0;
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
320df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	if ((ssid != NULL && ssid->eap.pcsc == NULL) ||
321df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	    wpa_s->scard != NULL || wpa_s->conf->external_sim)
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
324df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	if (ssid == NULL || ssid->eap.eap_methods == NULL) {
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sim = 1;
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		aka = 1;
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct eap_method_type *eap = ssid->eap.eap_methods;
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (eap->vendor != EAP_VENDOR_IETF ||
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       eap->method != EAP_TYPE_NONE) {
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (eap->vendor == EAP_VENDOR_IETF) {
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (eap->method == EAP_TYPE_SIM)
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					sim = 1;
33404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				else if (eap->method == EAP_TYPE_AKA ||
33504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 eap->method == EAP_TYPE_AKA_PRIME)
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					aka = 1;
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eap++;
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL)
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sim = 0;
34404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL &&
34504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME) ==
34604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    NULL)
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		aka = 0;
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!sim && !aka) {
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to "
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"use SIM, but neither EAP-SIM nor EAP-AKA are "
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"enabled");
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to use SIM "
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"(sim=%d aka=%d) - initialize PCSC", sim, aka);
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3592271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt	wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->scard == NULL) {
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "Failed to initialize SIM "
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"(pcsc-lite)");
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* PCSC_FUNCS */
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_SCAN_PROCESSING
375b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
376b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidtstatic int has_wep_key(struct wpa_ssid *ssid)
377b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt{
378b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	int i;
379b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
380b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
381b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		if (ssid->wep_key_len[i])
382b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			return 1;
383b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	}
384b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
385b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	return 0;
386b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt}
387b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
388b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
3899bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidtstatic int wpa_supplicant_match_privacy(struct wpa_bss *bss,
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					struct wpa_ssid *ssid)
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
392b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	int privacy = 0;
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mixed_cell)
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
402b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	if (has_wep_key(ssid))
403b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		privacy = 1;
404b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 EAPOL_FLAG_REQUIRE_KEY_BROADCAST))
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		privacy = 1;
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
41275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_key_mgmt_wpa(ssid->key_mgmt))
41375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		privacy = 1;
41475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
415f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if (ssid->key_mgmt & WPA_KEY_MGMT_OSEN)
416f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		privacy = 1;
417f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->caps & IEEE80211_CAP_PRIVACY)
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return privacy;
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return !privacy;
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_ssid *ssid,
4269bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt					 struct wpa_bss *bss)
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ie_data ie;
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int proto_match = 0;
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *rsn_ie, *wpa_ie;
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wep_ok;
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret >= 0)
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ret;
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Allow TSN if local configuration accepts WEP use without WPA/WPA2 */
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wep_ok = !wpa_key_mgmt_wpa(ssid->key_mgmt) &&
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		(((ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  ssid->wep_key_len[ssid->wep_tx_keyidx] > 0) ||
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA));
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4449bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		proto_match++;
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - parse "
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"failed");
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wep_ok &&
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on TSN "
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"in RSN IE");
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.proto & ssid->proto)) {
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - proto "
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - PTK "
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"cipher mismatch");
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.group_cipher & ssid->group_cipher)) {
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - GTK "
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"cipher mismatch");
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.key_mgmt & ssid->key_mgmt)) {
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - key mgmt "
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
488807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt		    wpas_get_ssid_pmf(wpa_s, ssid) ==
489d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		    MGMT_FRAME_PROTECTION_REQUIRED) {
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - no mgmt "
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"frame protection");
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on RSN IE");
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5009bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		proto_match++;
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_parse_wpa_ie(wpa_ie, 2 + wpa_ie[1], &ie)) {
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - parse "
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"failed");
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wep_ok &&
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on TSN "
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"in WPA IE");
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.proto & ssid->proto)) {
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - proto "
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - PTK "
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"cipher mismatch");
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.group_cipher & ssid->group_cipher)) {
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - GTK "
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"cipher mismatch");
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.key_mgmt & ssid->key_mgmt)) {
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - key mgmt "
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on WPA IE");
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
54661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && !wpa_ie &&
54761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    !rsn_ie) {
54861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   allow for non-WPA IEEE 802.1X");
54961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return 1;
55061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
55161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((ssid->proto & (WPA_PROTO_WPA | WPA_PROTO_RSN)) &&
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_key_mgmt_wpa(ssid->key_mgmt) && proto_match == 0) {
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no WPA/RSN proto match");
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
558f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) &&
559f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE)) {
560f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   allow in OSEN");
561f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		return 1;
562f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	}
563f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_key_mgmt_wpa(ssid->key_mgmt)) {
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   allow in non-WPA/WPA2");
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "   reject due to mismatch with "
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"WPA/WPA2");
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int freq_allowed(int *freqs, int freq)
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freqs == NULL)
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; freqs[i]; i++)
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (freqs[i] == freq)
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5909bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidtstatic int rate_match(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
5911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
5921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	const struct hostapd_hw_modes *mode = NULL, *modes;
5931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	const u8 scan_ie[2] = { WLAN_EID_SUPP_RATES, WLAN_EID_EXT_SUPP_RATES };
5941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	const u8 *rate_ie;
5951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int i, j, k;
5961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
5971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (bss->freq == 0)
5981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 1; /* Cannot do matching without knowing band */
5991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	modes = wpa_s->hw.modes;
6011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (modes == NULL) {
6021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/*
6031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * The driver does not provide any additional information
6041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * about the utilized hardware, so allow the connection attempt
6051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * to continue.
6061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 */
6071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 1;
6081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
6091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; i < wpa_s->hw.num_modes; i++) {
6111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		for (j = 0; j < modes[i].num_channels; j++) {
6121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			int freq = modes[i].channels[j].freq;
6131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (freq == bss->freq) {
6141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				if (mode &&
6151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				    mode->mode == HOSTAPD_MODE_IEEE80211G)
6161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					break; /* do not allow 802.11b replace
6171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						* 802.11g */
6181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				mode = &modes[i];
6191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				break;
6201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
6211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
6221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
6231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (mode == NULL)
6251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
6261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; i < (int) sizeof(scan_ie); i++) {
6289bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		rate_ie = wpa_bss_get_ie(bss, scan_ie[i]);
6291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (rate_ie == NULL)
6301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
6311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		for (j = 2; j < rate_ie[1] + 2; j++) {
6331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			int flagged = !!(rate_ie[j] & 0x80);
6341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			int r = (rate_ie[j] & 0x7f) * 5;
6351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/*
6371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * IEEE Std 802.11n-2009 7.3.2.2:
6381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * The new BSS Membership selector value is encoded
6391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * like a legacy basic rate, but it is not a rate and
6401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * only indicates if the BSS members are required to
6411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * support the mandatory features of Clause 20 [HT PHY]
6421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * in order to join the BSS.
6431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 */
6441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (flagged && ((rate_ie[j] & 0x7f) ==
6451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					BSS_MEMBERSHIP_SELECTOR_HT_PHY)) {
6461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				if (!ht_supported(mode)) {
6471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					wpa_dbg(wpa_s, MSG_DEBUG,
6481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						"   hardware does not support "
6491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						"HT PHY");
6501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					return 0;
6511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				}
6521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				continue;
6531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
6541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
655c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			/* There's also a VHT selector for 802.11ac */
656c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			if (flagged && ((rate_ie[j] & 0x7f) ==
657c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					BSS_MEMBERSHIP_SELECTOR_VHT_PHY)) {
658c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				if (!vht_supported(mode)) {
659c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					wpa_dbg(wpa_s, MSG_DEBUG,
660c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt						"   hardware does not support "
661c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt						"VHT PHY");
662c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					return 0;
663c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				}
664c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				continue;
665c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			}
666c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
6671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (!flagged)
6681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				continue;
6691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/* check for legacy basic rates */
6711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			for (k = 0; k < mode->num_rates; k++) {
6721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				if (mode->rates[k] == r)
6731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					break;
6741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
6751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (k == mode->num_rates) {
6761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				/*
6771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 * IEEE Std 802.11-2007 7.3.2.2 demands that in
6781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 * order to join a BSS all required rates
6791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 * have to be supported by the hardware.
6801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 */
6814dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG,
6824dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt					"   hardware does not support required rate %d.%d Mbps (freq=%d mode==%d num_rates=%d)",
6834dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt					r / 10, r % 10,
6844dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt					bss->freq, mode->mode, mode->num_rates);
6851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				return 0;
6861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
6871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
6881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
6891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 1;
6911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
6921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
694f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt/*
695f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Test whether BSS is in an ESS.
696f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * This is done differently in DMG (60 GHz) and non-DMG bands
697f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */
698f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstatic int bss_is_ess(struct wpa_bss *bss)
699f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
700f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	if (bss_is_dmg(bss)) {
701f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		return (bss->caps & IEEE80211_CAP_DMG_MASK) ==
702f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			IEEE80211_CAP_DMG_AP;
703f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	}
704f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
705f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	return ((bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
706f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		IEEE80211_CAP_ESS);
707f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
708f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
709f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
710ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int match_mac_mask(const u8 *addr_a, const u8 *addr_b, const u8 *mask)
711ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{
712ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	size_t i;
713ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
714ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	for (i = 0; i < ETH_ALEN; i++) {
715ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if ((addr_a[i] & mask[i]) != (addr_b[i] & mask[i]))
716ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			return 0;
717ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	}
718ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	return 1;
719ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt}
720ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
721ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
722ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int addr_in_list(const u8 *addr, const u8 *list, size_t num)
723ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{
724ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	size_t i;
725ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
726ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	for (i = 0; i < num; i++) {
727ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		const u8 *a = list + i * ETH_ALEN * 2;
728ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		const u8 *m = a + ETH_ALEN;
729ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
730ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if (match_mac_mask(a, addr, m))
731ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			return 1;
732ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	}
733ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	return 0;
734ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt}
735ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
736ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
7389bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt					    int i, struct wpa_bss *bss,
739f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt					    struct wpa_ssid *group,
740f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt					    int only_first_ssid)
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7429bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	u8 wpa_ie_len, rsn_ie_len;
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wpa;
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_blacklist *e;
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *ie;
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
747f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	int osen;
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7499bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_ie_len = ie ? ie[1] : 0;
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7529bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rsn_ie_len = ie ? ie[1] : 0;
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
755f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
756f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	osen = ie != NULL;
757f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
759f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		"wpa_ie_len=%u rsn_ie_len=%u caps=0x%x level=%d%s%s%s",
7609bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		i, MAC2STR(bss->bssid), wpa_ssid_txt(bss->ssid, bss->ssid_len),
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_ie_len, rsn_ie_len, bss->caps, bss->level,
7629657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE) ? " wps" : "",
7639657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		(wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) ||
7649657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		 wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) ?
765f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		" p2p" : "",
766f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		osen ? " osen=1" : "");
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	e = wpa_blacklist_get(wpa_s, bss->bssid);
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (e) {
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int limit = 1;
77104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_supplicant_enabled_networks(wpa_s) == 1) {
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * When only a single network is enabled, we can
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * trigger blacklisting on the first failure. This
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * should not be done with multiple enabled networks to
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * avoid getting forced to move into a worse ESS on
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * single error if there are no other BSSes of the
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * current ESS.
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			limit = 0;
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (e->count > limit) {
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - blacklisted "
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"(count=%d limit=%d)", e->count, limit);
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return NULL;
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7899bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (bss->ssid_len == 0) {
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID not known");
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
794d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (disallowed_bssid(wpa_s, bss->bssid)) {
795d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   skip - BSSID disallowed");
796d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return NULL;
797d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
798d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
799d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) {
800d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID disallowed");
801d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return NULL;
802d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
803d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa = wpa_ie_len > 0 || rsn_ie_len > 0;
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
806f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	for (ssid = group; ssid; ssid = only_first_ssid ? NULL : ssid->pnext) {
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int check_ssid = wpa ? 1 : (ssid->ssid_len != 0);
80861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		int res;
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
81004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpas_network_disabled(wpa_s, ssid)) {
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - disabled");
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
81561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		res = wpas_temp_disabled(wpa_s, ssid);
81661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (res > 0) {
81761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - disabled "
81861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				"temporarily for %d second(s)", res);
81961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			continue;
82061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
82161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && e && e->count > 0) {
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - blacklisted "
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"(WPS)");
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa && ssid->ssid_len == 0 &&
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			check_ssid = 0;
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Only allow wildcard SSID match if an AP
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * advertises active WPS operation that matches
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * with our mode. */
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			check_ssid = 1;
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ssid->ssid_len == 0 &&
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				check_ssid = 0;
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (ssid->bssid_set && ssid->ssid_len == 0 &&
8451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) == 0)
8461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			check_ssid = 0;
8471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (check_ssid &&
8499bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		    (bss->ssid_len != ssid->ssid_len ||
8509bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		     os_memcmp(bss->ssid, ssid->ssid, bss->ssid_len) != 0)) {
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID mismatch");
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->bssid_set &&
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) {
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - BSSID mismatch");
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
861ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		/* check blacklist */
862ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if (ssid->num_bssid_blacklist &&
863ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		    addr_in_list(bss->bssid, ssid->bssid_blacklist,
864ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				 ssid->num_bssid_blacklist)) {
865ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
866ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				"   skip - BSSID blacklisted");
867ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			continue;
868ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		}
869ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
870ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		/* if there is a whitelist, only accept those APs */
871ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if (ssid->num_bssid_whitelist &&
872ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		    !addr_in_list(bss->bssid, ssid->bssid_whitelist,
873ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				  ssid->num_bssid_whitelist)) {
874ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
875ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				"   skip - BSSID not in whitelist");
876ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			continue;
877ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		}
878ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
882f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		if (!osen && !wpa &&
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) {
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - non-WPA network "
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"not allowed");
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
891b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		if (wpa && !wpa_key_mgmt_wpa(ssid->key_mgmt) &&
892b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		    has_wep_key(ssid)) {
893b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - ignore WPA/WPA2 AP for WEP network block");
894b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			continue;
895b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		}
896b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
897f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) && !osen) {
898f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - non-OSEN network "
899f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt				"not allowed");
900f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			continue;
901f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		}
902f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
90375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_supplicant_match_privacy(bss, ssid)) {
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - privacy "
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
909f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		if (!bss_is_ess(bss)) {
910f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - not ESS network");
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!freq_allowed(ssid->freq_list, bss->freq)) {
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - frequency not "
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"allowed");
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!rate_match(wpa_s, bss)) {
9211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - rate sets do "
9221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				"not match");
9231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
9241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
9251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
9279657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		if (ssid->p2p_group &&
9289657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		    !wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
9299657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		    !wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
9309657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no P2P IE seen");
9319657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt			continue;
9329657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		}
9339657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt
9345460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt		if (!is_zero_ether_addr(ssid->go_p2p_dev_addr)) {
9355460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			struct wpabuf *p2p_ie;
9365460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			u8 dev_addr[ETH_ALEN];
9375460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
9385460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			ie = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
9395460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			if (ie == NULL) {
9405460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no P2P element");
9415460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				continue;
9425460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			}
9435460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			p2p_ie = wpa_bss_get_vendor_ie_multi(
9445460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				bss, P2P_IE_VENDOR_TYPE);
9455460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			if (p2p_ie == NULL) {
9465460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "   skip - could not fetch P2P element");
9475460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				continue;
9485460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			}
9495460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
9505460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			if (p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr) < 0
9515460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			    || os_memcmp(dev_addr, ssid->go_p2p_dev_addr,
9525460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt					 ETH_ALEN) != 0) {
9535460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no matching GO P2P Device Address in P2P element");
9545460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				wpabuf_free(p2p_ie);
9555460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				continue;
9565460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			}
9575460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			wpabuf_free(p2p_ie);
9585460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt		}
9595460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * TODO: skip the AP if its P2P IE has Group Formation
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * bit set in the P2P Group Capability Bitmap and we
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * are not in Group Formation with that device.
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Matching configuration found */
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ssid;
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* No matching configuration found */
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_bss *
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  struct wpa_ssid *group,
979f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			  struct wpa_ssid **selected_ssid,
980f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			  int only_first_ssid)
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9829bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	unsigned int i;
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
984f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if (only_first_ssid)
985f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Try to find BSS matching pre-selected network id=%d",
986f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			group->id);
987f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	else
988f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d",
989f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			group->priority);
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9919bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	for (i = 0; i < wpa_s->last_scan_res_used; i++) {
9929bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		struct wpa_bss *bss = wpa_s->last_scan_res[i];
993f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		*selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group,
994f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt						    only_first_ssid);
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!*selected_ssid)
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   selected BSS " MACSTR
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" ssid='%s'",
9999bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt			MAC2STR(bss->bssid),
10009bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt			wpa_ssid_txt(bss->ssid, bss->ssid_len));
10019bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		return bss;
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1008444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtstruct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
1009444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt					     struct wpa_ssid **selected_ssid)
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *selected = NULL;
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int prio;
10134582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt	struct wpa_ssid *next_ssid = NULL;
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10159bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (wpa_s->last_scan_res == NULL ||
10169bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	    wpa_s->last_scan_res_used == 0)
10179bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		return NULL; /* no scan results from last update */
10189bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
10194582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt	if (wpa_s->next_ssid) {
10204582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		struct wpa_ssid *ssid;
1021f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
10224582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		/* check that next_ssid is still valid */
10234582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
10244582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt			if (ssid == wpa_s->next_ssid)
10254582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt				break;
10264582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		}
10274582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		next_ssid = ssid;
10284582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		wpa_s->next_ssid = NULL;
10294582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt	}
1030f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
10314582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt	while (selected == NULL) {
10324582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
10334582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt			if (next_ssid && next_ssid->priority ==
10344582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt			    wpa_s->conf->pssid[prio]->priority) {
1035f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt				selected = wpa_supplicant_select_bss(
10364582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt					wpa_s, next_ssid, selected_ssid, 1);
1037f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt				if (selected)
1038f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt					break;
1039f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			}
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			selected = wpa_supplicant_select_bss(
10419bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt				wpa_s, wpa_s->conf->pssid[prio],
1042f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt				selected_ssid, 0);
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (selected)
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (selected == NULL && wpa_s->blacklist &&
10481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    !wpa_s->countermeasures) {
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "No APs found - clear "
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"blacklist and try again");
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_blacklist_clear(wpa_s);
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->blacklist_cleared++;
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (selected == NULL)
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return selected;
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					int timeout_sec, int timeout_usec)
10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
106404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_supplicant_enabled_networks(wpa_s)) {
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * No networks are enabled; short-circuit request so
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * we don't wait timeout seconds before transitioning
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * to INACTIVE state.
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
1070aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Short-circuit new scan request "
1071aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt			"since there are no enabled networks");
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1075d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
1076d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->scan_for_connection = 1;
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
108144da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidtint wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
10821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   struct wpa_bss *selected,
10831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   struct wpa_ssid *ssid)
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"PBC session overlap");
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
1089df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt		if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
1090df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt		    wpa_s->p2p_in_provisioning) {
1091df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt			eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb,
1092df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt					       wpa_s, NULL);
109344da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt			return -1;
1094df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt		}
10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_wps_cancel(wpa_s);
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
110044da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt		return -1;
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1103f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG,
1104f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		"Considering connect request: reassociate: %d  selected: "
1105f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		MACSTR "  bssid: " MACSTR "  pending: " MACSTR
1106f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		"  wpa_state: %s  ssid=%p  current_ssid=%p",
1107f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		wpa_s->reassociate, MAC2STR(selected->bssid),
1108f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1109f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		wpa_supplicant_state_txt(wpa_s->wpa_state),
1110f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		ssid, wpa_s->current_ssid);
1111f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt
11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Do not trigger new association unless the BSSID has changed or if
11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * reassociation is requested. If we are in process of associating with
11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * the selected BSSID, do not trigger new attempt.
11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
11171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->reassociate ||
11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     ((wpa_s->wpa_state != WPA_ASSOCIATING &&
11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       wpa_s->wpa_state != WPA_AUTHENTICATING) ||
1121f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	      (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1122f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	       os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) !=
1123f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	       0) ||
1124f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	      (is_zero_ether_addr(wpa_s->pending_bssid) &&
1125f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	       ssid != wpa_s->current_ssid)))) {
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_scard_init(wpa_s, ssid)) {
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_req_new_scan(wpa_s, 10, 0);
112844da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt			return 0;
11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1130f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		wpa_msg(wpa_s, MSG_DEBUG, "Request association with " MACSTR,
1131f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			MAC2STR(selected->bssid));
11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_associate(wpa_s, selected, ssid);
11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
1134f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Already associated or trying to "
1135f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			"connect with the selected AP");
11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
113844da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt	return 0;
11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_ssid *
11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int prio;
11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (ssid = wpa_s->conf->pssid[prio]; ssid; ssid = ssid->pnext)
11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
115104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (wpas_network_disabled(wpa_s, ssid))
11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue;
11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ssid->mode == IEEE80211_MODE_IBSS ||
11546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			    ssid->mode == IEEE80211_MODE_AP ||
11556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			    ssid->mode == IEEE80211_MODE_MESH)
11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return ssid;
11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based
11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * on BSS added and BSS changed events */
11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_rsn_preauth_scan_results(
116687fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	struct wpa_supplicant *wpa_s)
11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
116887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	struct wpa_bss *bss;
11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
117387fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *ssid, *rsn;
11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
117687fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		ssid = wpa_bss_get_ie(bss, WLAN_EID_SSID);
11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid == NULL)
11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (rsn == NULL)
11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118487fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		rsn_preauth_scan_result(wpa_s->wpa, bss->bssid, ssid, rsn);
11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       struct wpa_bss *selected,
11929bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt				       struct wpa_ssid *ssid)
11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11949bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	struct wpa_bss *current_bss = NULL;
11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int min_diff;
11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->reassociate)
11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* explicit request to reassociate */
11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state < WPA_ASSOCIATED)
12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* we are not associated; continue */
12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid == NULL)
12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* unknown current SSID */
12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid != ssid)
12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* different network block */
12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpas_driver_bss_selection(wpa_s))
12071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0; /* Driver-based roaming */
12081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12099bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (wpa_s->current_ssid->ssid)
12109bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		current_bss = wpa_bss_get(wpa_s, wpa_s->bssid,
12119bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt					  wpa_s->current_ssid->ssid,
12129bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt					  wpa_s->current_ssid->ssid_len);
12139bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (!current_bss)
12149bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		current_bss = wpa_bss_get_bssid(wpa_s, wpa_s->bssid);
12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!current_bss)
12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* current BSS not seen in scan results */
12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12199bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (current_bss == selected)
12209bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		return 0;
12219bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
12229bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (selected->last_update_idx > current_bss->last_update_idx)
12239bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		return 1; /* current BSS not seen in the last scan */
12249bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
12259e07767d5d76159ef38a241da00eb0d9f3bc6420Dmitry Shmidt#ifndef CONFIG_NO_ROAMING
12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Considering within-ESS reassociation");
12277f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Current BSS: " MACSTR
12287f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		" level=%d snr=%d est_throughput=%u",
12297f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		MAC2STR(current_bss->bssid), current_bss->level,
12307f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		current_bss->snr, current_bss->est_throughput);
12317f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS: " MACSTR
12327f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		" level=%d snr=%d est_throughput=%u",
12337f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		MAC2STR(selected->bssid), selected->level,
12347f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		selected->snr, selected->est_throughput);
12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid->bssid_set &&
12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    os_memcmp(selected->bssid, wpa_s->current_ssid->bssid, ETH_ALEN) ==
12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    0) {
12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Allow reassociation - selected BSS "
12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"has preferred BSSID");
12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12447f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	if (selected->est_throughput > current_bss->est_throughput + 5000) {
12457f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
12467f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			"Allow reassociation - selected BSS has better estimated throughput");
12477f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		return 1;
12487f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	}
12497f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
1250d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (current_bss->level < 0 && current_bss->level > selected->level) {
1251d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
1252d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			"signal level");
1253d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return 0;
1254d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
1255d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	min_diff = 2;
12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (current_bss->level < 0) {
12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (current_bss->level < -85)
12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 1;
12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (current_bss->level < -80)
12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 2;
12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (current_bss->level < -75)
12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 3;
12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (current_bss->level < -70)
12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 4;
12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 5;
12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (abs(current_bss->level - selected->level) < min_diff) {
12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - too small difference "
12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"in signal level");
12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 1;
127604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#else /* CONFIG_NO_ROAMING */
1277efdec2efdda2f534d84b32f2737ca3d8a00fdf02Dmitry Shmidt	return 0;
127804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_NO_ROAMING */
12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1281c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
128289ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen/* Return != 0 if no scan results could be fetched or if scan results should not
128304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * be shared with other virtual interfaces. */
1284f6c92c4dd33d21c040e51bcb30beac24173a62b9Dmitry Shmidtstatic int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
128537d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt					      union wpa_event_data *data,
128637d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt					      int own_request)
12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1288fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_scan_results *scan_res = NULL;
1289fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int ret = 0;
12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ap = 0;
12914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifndef CONFIG_NO_RANDOM_POOL
12924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt	size_t i, num;
12934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_NO_RANDOM_POOL */
12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface)
12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ap = 1;
12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_notify_scanning(wpa_s, 0);
13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	scan_res = wpa_supplicant_get_scan_results(wpa_s,
13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   data ? &data->scan_info :
13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   NULL, 1);
13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (scan_res == NULL) {
13064b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		if (wpa_s->conf->ap_scan == 2 || ap ||
13074b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		    wpa_s->scan_res_handler == scan_only_handler)
13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
130937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt		if (!own_request)
131037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt			return -1;
13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results - try "
13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"scanning again");
13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_new_scan(wpa_s, 1, 0);
1314fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		ret = -1;
1315fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RANDOM_POOL
13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	num = scan_res->num;
13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (num > 10)
13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		num = 10;
13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < num; i++) {
13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 buf[5];
13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_scan_res *res = scan_res->res[i];
13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[0] = res->bssid[5];
13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[1] = res->qual & 0xff;
13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[2] = res->noise & 0xff;
13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[3] = res->level & 0xff;
13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[4] = res->tsf & 0xff;
13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		random_add_randomness(buf, sizeof(buf));
13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RANDOM_POOL */
13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1334fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (own_request && wpa_s->scan_res_handler &&
13352f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt	    (wpa_s->own_scan_running || !wpa_s->radio->external_scan_running)) {
13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_scan_results *scan_res);
13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		scan_res_handler = wpa_s->scan_res_handler;
13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->scan_res_handler = NULL;
13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		scan_res_handler(wpa_s, scan_res);
1342fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		ret = -2;
1343fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ap) {
13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Ignore scan results in AP mode");
13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface->scan_cb)
13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->ap_iface->scan_cb(wpa_s->ap_iface);
13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
1352fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
135437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt
1355fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "New scan results available (own=%u ext=%u)",
13562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt		wpa_s->own_scan_running, wpa_s->radio->external_scan_running);
1357fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
1358fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    wpa_s->manual_scan_use_id && wpa_s->own_scan_running) {
1359fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u",
1360fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			     wpa_s->manual_scan_id);
1361fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->manual_scan_use_id = 0;
1362fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	} else {
1363fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
1364fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
136504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpas_notify_scan_results(wpa_s);
13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_scan_done(wpa_s, 1);
13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt	if (!wpa_s->own_scan_running && wpa_s->radio->external_scan_running) {
1370fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Do not use results from externally requested scan operation for network selection");
137104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_scan_results_free(scan_res);
137204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
137304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
137404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
13756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wnm_scan_process(wpa_s, 1) > 0)
13766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		goto scan_work_done;
13776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
1378fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (sme_proc_obss_scan(wpa_s) > 0)
1379fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1381fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)))
1382fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
1383fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1384fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (autoscan_notify_scan(wpa_s, scan_res))
1385fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
138604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->disconnected) {
13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1389fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpas_driver_bss_selection(wpa_s) &&
1393fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    bgscan_notify_scan(wpa_s, scan_res) == 1)
1394fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
139661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpas_wps_update_ap_info(wpa_s, scan_res);
139761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
13989bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	wpa_scan_results_free(scan_res);
13999bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
1400fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->scan_work) {
1401fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct wpa_radio_work *work = wpa_s->scan_work;
1402fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->scan_work = NULL;
1403fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_done(work);
1404fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1405fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1406e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	return wpas_select_network_from_last_scan(wpa_s, 1, own_request);
1407fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1408fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtscan_work_done:
1409fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_scan_results_free(scan_res);
1410fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->scan_work) {
1411fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct wpa_radio_work *work = wpa_s->scan_work;
1412fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->scan_work = NULL;
1413fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_done(work);
1414fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1415fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return ret;
14169bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt}
14179bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
14189bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
14198da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidtstatic int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
1420e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt					      int new_scan, int own_request)
14219bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt{
14229bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	struct wpa_bss *selected;
14239bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	struct wpa_ssid *ssid = NULL;
14249bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
1425203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	if (wpa_s->p2p_mgmt)
1426203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		return 0; /* no normal connection on p2p_mgmt interface */
1427203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt
14289bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	selected = wpa_supplicant_pick_network(wpa_s, &ssid);
14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (selected) {
14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int skip;
14329bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid);
14331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (skip) {
14348da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt			if (new_scan)
14358da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt				wpa_supplicant_rsn_preauth_scan_results(wpa_s);
14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
14371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
14381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
143944da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt		if (wpa_supplicant_connect(wpa_s, selected, ssid) < 0) {
14401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Connect failed");
144144da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt			return -1;
144244da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt		}
14438da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt		if (new_scan)
14448da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt			wpa_supplicant_rsn_preauth_scan_results(wpa_s);
144589ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		/*
144689ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * Do not notify other virtual radios of scan results since we do not
144789ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * want them to start other associations at the same time.
144889ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 */
144989ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		return 1;
14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
14516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH
14526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (wpa_s->ifmsh) {
14536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_msg(wpa_s, MSG_INFO,
14546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				"Avoiding join because we already joined a mesh group");
14556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			return 0;
14566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		}
14576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */
14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "No suitable network found");
14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = wpa_supplicant_pick_new_network(wpa_s);
14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid) {
14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Setup a new network");
14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_associate(wpa_s, NULL, ssid);
14638da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt			if (new_scan)
14648da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt				wpa_supplicant_rsn_preauth_scan_results(wpa_s);
1465e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt		} else if (own_request) {
1466e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			/*
1467e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			 * No SSID found. If SCAN results are as a result of
1468e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			 * own scan request and not due to a scan request on
1469e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			 * another shared interface, try another scan.
1470e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			 */
14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int timeout_sec = wpa_s->scan_interval;
14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int timeout_usec = 0;
14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
14747f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			int res;
14757f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
14767f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			res = wpas_p2p_scan_no_go_seen(wpa_s);
14777f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			if (res == 2)
14787f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt				return 2;
14797f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			if (res == 1)
148004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return 0;
148104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1482fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			if (wpa_s->p2p_in_provisioning ||
148315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt			    wpa_s->show_group_started ||
148415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt			    wpa_s->p2p_in_invitation) {
14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				/*
14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 * Use shorter wait during P2P Provisioning
1487fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt				 * state and during P2P join-a-group operation
1488fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt				 * to speed up group formation.
14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 */
14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				timeout_sec = 0;
14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				timeout_usec = 250000;
14921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
14931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							    timeout_usec);
14941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				return 0;
14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
149761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_INTERWORKING
149861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (wpa_s->conf->auto_interworking &&
149961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    wpa_s->conf->interworking &&
150061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    wpa_s->conf->cred) {
150161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: "
150261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"start ANQP fetch since no matching "
150361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"networks found");
150461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_s->network_select = 1;
150561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_s->auto_network_select = 1;
150661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				interworking_start_fetch_anqp(wpa_s);
150789ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen				return 1;
150861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
150961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
1510fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_WPS
1511fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			if (wpa_s->after_wps > 0 || wpas_wps_searching(wpa_s)) {
1512fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "Use shorter wait during WPS processing");
1513fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				timeout_sec = 0;
1514fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				timeout_usec = 500000;
1515fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
1516fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt							    timeout_usec);
1517fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				return 0;
1518fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			}
1519fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_WPS */
15201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (wpa_supplicant_req_sched_scan(wpa_s))
15211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
15221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							    timeout_usec);
15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15297f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidtstatic int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
15307f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt					     union wpa_event_data *data)
15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *ifs;
15337f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	int res;
153437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt
15357f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	res = _wpa_supplicant_event_scan_results(wpa_s, data, 1);
15367f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	if (res == 2) {
15377f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		/*
15387f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * Interface may have been removed, so must not dereference
15397f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * wpa_s after this.
15407f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 */
15417f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		return 1;
15427f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	}
15437f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	if (res != 0) {
15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * If no scan results could be fetched, then no need to
15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * notify those interfaces that did not actually request
154789ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * this scan. Similarly, if scan results started a new operation on this
154889ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * interface, do not notify other interfaces to avoid concurrent
154989ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * operations during a connection attempt.
15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
15517f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		return 0;
15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
155501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt	 * Check other interfaces to see if they share the same radio. If
15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * so, they get updated with this same scan info.
15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
155801904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
155901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 radio_list) {
156001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		if (ifs != wpa_s) {
15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "%s: Updating scan results from "
15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "sibling", ifs->ifname);
156337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt			_wpa_supplicant_event_scan_results(ifs, data, 0);
15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15667f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
15677f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	return 0;
15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15734b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidtint wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s)
15744b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt{
15754b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt#ifdef CONFIG_NO_SCAN_PROCESSING
15764b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	return -1;
15774b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt#else /* CONFIG_NO_SCAN_PROCESSING */
1578fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct os_reltime now;
15794b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
15804b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	if (wpa_s->last_scan_res_used <= 0)
15814b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		return -1;
15824b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
1583fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_get_reltime(&now);
1584fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (os_reltime_expired(&now, &wpa_s->last_scan, 5)) {
15854b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		wpa_printf(MSG_DEBUG, "Fast associate: Old scan results");
15864b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		return -1;
15874b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	}
15884b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
1589e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	return wpas_select_network_from_last_scan(wpa_s, 0, 1);
15904b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
15914b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt}
15924b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
159304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WNM
159404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
159504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wnm_bss_keep_alive(void *eloop_ctx, void *sock_ctx)
159604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
159704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
159804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
159904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->wpa_state < WPA_ASSOCIATED)
160004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
160104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1602a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (!wpa_s->no_keep_alive) {
1603a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		wpa_printf(MSG_DEBUG, "WNM: Send keep-alive to AP " MACSTR,
1604a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			   MAC2STR(wpa_s->bssid));
1605a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* TODO: could skip this if normal data traffic has been sent */
1606a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* TODO: Consider using some more appropriate data frame for
1607a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		 * this */
1608a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (wpa_s->l2)
1609a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			l2_packet_send(wpa_s->l2, wpa_s->bssid, 0x0800,
1610a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt				       (u8 *) "", 0);
1611a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
161204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
161304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_SME
161404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->sme.bss_max_idle_period) {
161504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		unsigned int msec;
161604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		msec = wpa_s->sme.bss_max_idle_period * 1024; /* times 1000 */
161704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (msec > 100)
161804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			msec -= 100;
161904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eloop_register_timeout(msec / 1000, msec % 1000 * 1000,
162004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				       wnm_bss_keep_alive, wpa_s, NULL);
162104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
162204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_SME */
162304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
162404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
162504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
162604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wnm_process_assoc_resp(struct wpa_supplicant *wpa_s,
162704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   const u8 *ies, size_t ies_len)
162804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
162904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct ieee802_11_elems elems;
163004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
163104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ies == NULL)
163204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
163304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
163404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
163504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
163604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
163704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_SME
163804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (elems.bss_max_idle_period) {
163904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		unsigned int msec;
164004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->sme.bss_max_idle_period =
164104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			WPA_GET_LE16(elems.bss_max_idle_period);
164204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "WNM: BSS Max Idle Period: %u (* 1000 "
164304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "TU)%s", wpa_s->sme.bss_max_idle_period,
164404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   (elems.bss_max_idle_period[2] & 0x01) ?
164504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   " (protected keep-live required)" : "");
164604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->sme.bss_max_idle_period == 0)
164704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->sme.bss_max_idle_period = 1;
164804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
164904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL);
165004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 /* msec times 1000 */
165104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			msec = wpa_s->sme.bss_max_idle_period * 1024;
165204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (msec > 100)
165304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				msec -= 100;
165404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			eloop_register_timeout(msec / 1000, msec % 1000 * 1000,
165504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       wnm_bss_keep_alive, wpa_s,
165604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       NULL);
165704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
165804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
165904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_SME */
166004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
166104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
166204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WNM */
166304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
166404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
166504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s)
166604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
166704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WNM
166804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL);
166904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WNM */
167004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
167104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
167204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1673051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef CONFIG_INTERWORKING
1674051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1675051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtstatic int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map,
1676051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			    size_t len)
1677051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
1678051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	int res;
1679051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1680051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	wpa_hexdump(MSG_DEBUG, "Interworking: QoS Map Set", qos_map, len);
1681051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	res = wpa_drv_set_qos_map(wpa_s, qos_map, len);
1682051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (res) {
1683051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Interworking: Failed to configure QoS Map Set to the driver");
1684051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	}
1685051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1686051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	return res;
1687051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
1688051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1689051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1690051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtstatic void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s,
1691051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt					    const u8 *ies, size_t ies_len)
1692051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
1693051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	struct ieee802_11_elems elems;
1694051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1695051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (ies == NULL)
1696051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return;
1697051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1698051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
1699051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return;
1700051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1701051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (elems.qos_map_set) {
1702051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		wpas_qos_map_set(wpa_s, elems.qos_map_set,
1703051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				 elems.qos_map_set_len);
1704051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	}
1705051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
1706051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1707051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
1708051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1709051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  union wpa_event_data *data)
17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int l, len, found = 0, wpa_found, rsn_found;
17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *p;
1715700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#ifdef CONFIG_IEEE80211R
1716700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	u8 bssid[ETH_ALEN];
1717700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data->assoc_info.req_ies)
17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->assoc_info.req_ies_len);
17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data->assoc_info.resp_ies) {
17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies,
17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->assoc_info.resp_ies_len);
17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_tdls_assoc_resp_ies(wpa_s->wpa, data->assoc_info.resp_ies,
17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->assoc_info.resp_ies_len);
17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
173004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WNM
173104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
173204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				       data->assoc_info.resp_ies_len);
173304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WNM */
1734051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef CONFIG_INTERWORKING
1735051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
1736051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt						data->assoc_info.resp_ies_len);
1737051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data->assoc_info.beacon_ies)
17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_DEBUG, "beacon_ies",
17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->assoc_info.beacon_ies,
17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->assoc_info.beacon_ies_len);
17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data->assoc_info.freq)
17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "freq=%u MHz",
17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->assoc_info.freq);
17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p = data->assoc_info.req_ies;
17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l = data->assoc_info.req_ies_len;
17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Go through the IEs and make a copy of the WPA/RSN IE, if present. */
17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (p && l >= 2) {
17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = p[1] + 2;
17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len > l) {
17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    p, l);
17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (p[0] == WLAN_EID_RSN && p[1] >= 2)) {
17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			found = 1;
17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_find_assoc_pmkid(wpa_s);
17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l -= len;
17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p += len;
17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!found && data->assoc_info.req_ies)
17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SME
17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpa_ft_validate_reassoc_resp(wpa_s->wpa,
17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 data->assoc_info.resp_ies,
17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 data->assoc_info.resp_ies_len,
17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 bssid) < 0) {
17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of "
17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"Reassociation Response failed");
17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_deauthenticate(
17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_INVALID_IE);
17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p = data->assoc_info.resp_ies;
17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l = data->assoc_info.resp_ies_len;
17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_STRICT
17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p && wpa_s->current_ssid &&
17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpabuf *wps;
17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wps = ieee802_11_vendor_ie_concat(p, l, WPS_IE_VENDOR_TYPE);
17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps == NULL) {
17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "WPS-STRICT: AP did not "
17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"include WPS IE in (Re)Association Response");
18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps_validate_assoc_resp(wps) < 0) {
18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpabuf_free(wps);
18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_deauthenticate(
18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_INVALID_IE);
18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wps);
18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_STRICT */
18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Go through the IEs and make a copy of the MDIE, if present. */
18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (p && l >= 2) {
18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = p[1] + 2;
18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len > l) {
18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    p, l);
18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p[0] == WLAN_EID_MOBILITY_DOMAIN &&
18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    p[1] >= MOBILITY_DOMAIN_ID_LEN) {
18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->sme.ft_used = 1;
18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_s->sme.mobility_domain, p + 2,
18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  MOBILITY_DOMAIN_ID_LEN);
18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l -= len;
18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p += len;
18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SME */
18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1833700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	/* Process FT when SME is in the driver */
1834700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1835700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	    wpa_ft_is_completed(wpa_s->wpa)) {
1836700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
1837700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		    wpa_ft_validate_reassoc_resp(wpa_s->wpa,
1838700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt						 data->assoc_info.resp_ies,
1839700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt						 data->assoc_info.resp_ies_len,
1840700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt						 bssid) < 0) {
1841700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of "
1842700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				"Reassociation Response failed");
1843700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			wpa_supplicant_deauthenticate(
1844700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				wpa_s, WLAN_REASON_INVALID_IE);
1845700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			return -1;
1846700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		}
1847700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done");
1848700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	}
1849700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     data->assoc_info.resp_ies_len);
18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* WPA/RSN IE from Beacon/ProbeResp */
18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p = data->assoc_info.beacon_ies;
18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l = data->assoc_info.beacon_ies_len;
18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Go through the IEs and make a copy of the WPA/RSN IEs, if present.
18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_found = rsn_found = 0;
18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (p && l >= 2) {
18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = p[1] + 2;
18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len > l) {
18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_hexdump(MSG_DEBUG, "Truncated IE in beacon_ies",
18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    p, l);
18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_found &&
18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_found = 1;
18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len);
18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!rsn_found &&
18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    p[0] == WLAN_EID_RSN && p[1] >= 2) {
18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			rsn_found = 1;
18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l -= len;
18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p += len;
18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_found && data->assoc_info.beacon_ies)
18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!rsn_found && data->assoc_info.beacon_ies)
18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_found || rsn_found)
18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ap_ies_from_associnfo = 1;
18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
189287fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	if (wpa_s->assoc_freq && data->assoc_info.freq &&
189387fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	    wpa_s->assoc_freq != data->assoc_info.freq) {
189487fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		wpa_printf(MSG_DEBUG, "Operating frequency changed from "
189587fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen			   "%u to %u MHz",
189687fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen			   wpa_s->assoc_freq, data->assoc_info.freq);
189787fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		wpa_supplicant_update_scan_results(wpa_s);
189887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	}
189987fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen
19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->assoc_freq = data->assoc_info.freq;
19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1906c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s)
1907c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
1908c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const u8 *bss_wpa = NULL, *bss_rsn = NULL;
1909c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1910c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpa_s->current_bss || !wpa_s->current_ssid)
1911c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return -1;
1912c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1913c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpa_key_mgmt_wpa_any(wpa_s->current_ssid->key_mgmt))
1914c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
1915c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1916c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	bss_wpa = wpa_bss_get_vendor_ie(wpa_s->current_bss,
1917c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					WPA_IE_VENDOR_TYPE);
1918c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	bss_rsn = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSN);
1919c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1920c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1921c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1922c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	    wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1923c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 bss_rsn ? 2 + bss_rsn[1] : 0))
1924c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return -1;
1925c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1926c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
1927c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
1928c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1929c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       union wpa_event_data *data)
19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN];
19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ft_completed;
19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface) {
193809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt		if (!data)
193909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt			return;
19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hostapd_notif_assoc(wpa_s->ap_iface->bss[0],
19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->assoc_info.addr,
19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->assoc_info.req_ies,
19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->assoc_info.req_ies_len,
19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->assoc_info.reassoc);
19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ft_completed = wpa_ft_is_completed(wpa_s->wpa);
19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0)
19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
195361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
195461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_dbg(wpa_s, MSG_ERROR, "Failed to get BSSID");
1955d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_supplicant_deauthenticate(
195661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
195761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
195861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
195961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
196161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MACSTR, MAC2STR(bssid));
19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		random_add_randomness(bssid, ETH_ALEN);
19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
196761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_notify_bssid_changed(wpa_s);
19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) {
19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_clear_keys(wpa_s, bssid);
19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_select_config(wpa_s) < 0) {
1973d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			wpa_supplicant_deauthenticate(
19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1977c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
19781e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt#ifdef ANDROID
19791e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt		if (wpa_s->conf->ap_scan == 1) {
19801e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt#else
1981c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (wpa_s->conf->ap_scan == 1 &&
1982c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		    wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION) {
19831e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt#endif
1984c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			if (wpa_supplicant_assoc_update_ie(wpa_s) < 0)
1985c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				wpa_msg(wpa_s, MSG_WARNING,
1986c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					"WPA/RSN IEs not updated");
1987c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		}
19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SME
19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN);
19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->sme.prev_bssid_set = 1;
19930c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt	wpa_s->sme.last_unprot_disconnect.sec = 0;
19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SME */
19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid) {
19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* When using scanning (ap_scan=1), SIM PC/SC interface can be
19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * initialized before association, but for other modes,
20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * initialize PC/SC here, if the current configuration needs
20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * smartcard or SIM/USIM. */
20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid);
20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_notify_assoc(wpa_s->wpa, bssid);
20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->l2)
20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l2_packet_notify_auth_start(wpa_s->l2);
20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Set portEnabled first to FALSE in order to get EAP state machine out
20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE
20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * state machine may transit to AUTHENTICATING state based on obsolete
20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to
20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * AUTHENTICATED without ever giving chance to EAP state machine to
20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * reset the state.
20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!ft_completed) {
20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed)
20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* 802.1X::portControl = Auto */
20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->eapol_received = 0;
20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE ||
20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (wpa_s->current_ssid &&
20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS)) {
202909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt		if (wpa_s->current_ssid &&
203009f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt		    wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE &&
203151b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt		    (wpa_s->drv_flags &
203251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt		     WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) {
203351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			/*
203451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			 * Set the key after having received joined-IBSS event
203551b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			 * from the driver.
203651b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			 */
203751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			wpa_supplicant_set_wpa_none_key(wpa_s,
203851b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt							wpa_s->current_ssid);
203951b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt		}
20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (!ft_completed) {
20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Timeout for receiving the first EAPOL packet */
20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cancel_scan(wpa_s);
20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * We are done; the driver will take care of RSN 4-way
20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * handshake.
20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * The driver will take care of RSN 4-way handshake, so we need
20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * to allow EAPOL supplicant to complete its work without
20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * waiting for WPA supplicant.
20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (ft_completed) {
20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * FT protocol completed - make sure EAPOL state machine ends
20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * up in authenticated.
20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2077a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen	wpa_s->last_eapol_matches_bssid = 0;
2078a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen
20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->pending_eapol_rx) {
2080fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct os_reltime now, age;
2081fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_get_reltime(&now);
2082fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_reltime_sub(&now, &wpa_s->pending_eapol_rx_time, &age);
20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (age.sec == 0 && age.usec < 100000 &&
20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) ==
20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    0) {
20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Process pending EAPOL "
20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"frame that was received just before "
20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"association notification");
20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_rx_eapol(
20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, wpa_s->pending_eapol_rx_src,
20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpabuf_head(wpa_s->pending_eapol_rx),
20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpabuf_len(wpa_s->pending_eapol_rx));
20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wpa_s->pending_eapol_rx);
20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pending_eapol_rx = NULL;
20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
210051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt	    wpa_s->current_ssid &&
210151b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) {
21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Set static WEP keys again */
21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_set_wep_keys(wpa_s, wpa_s->current_ssid);
21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid &&
21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE &&
21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->ibss_rsn == NULL) {
21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ibss_rsn = ibss_rsn_init(wpa_s);
21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_s->ibss_rsn) {
21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "Failed to init IBSS RSN");
21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_deauthenticate(
21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ibss_rsn_set_psk(wpa_s->ibss_rsn, wpa_s->current_ssid->psk);
21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
212361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
212461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpas_wps_notify_assoc(wpa_s, bssid);
21256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
21266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (data) {
21276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wmm_ac_notify_assoc(wpa_s, data->assoc_info.resp_ies,
21286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				    data->assoc_info.resp_ies_len,
21296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				    &data->assoc_info.wmm_params);
21306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
21316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (wpa_s->reassoc_same_bss)
21326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wmm_ac_restore_tspecs(wpa_s);
21336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int disconnect_reason_recoverable(u16 reason_code)
21381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
21391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY ||
21401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA ||
21411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA;
21421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
21431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
2146c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					  u16 reason_code,
2147c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					  int locally_generated)
21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *bssid;
21502b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
21512b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
21522b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		/*
21532b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		 * At least Host AP driver and a Prism3 card seemed to be
21542b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		 * generating streams of disconnected events when configuring
21552b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		 * IBSS for WPA-None. Ignore them for now.
21562b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		 */
21572b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		return;
21582b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	}
21592b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
21602b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	bssid = wpa_s->bssid;
21612b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	if (is_zero_ether_addr(bssid))
21622b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		bssid = wpa_s->pending_bssid;
21632b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
21642b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	if (!is_zero_ether_addr(bssid) ||
21652b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	    wpa_s->wpa_state >= WPA_AUTHENTICATING) {
21662b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
21672b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen			" reason=%d%s",
21682b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen			MAC2STR(bssid), reason_code,
21692b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen			locally_generated ? " locally_generated=1" : "");
21702b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	}
21712b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen}
21722b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
21732b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
2174d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int could_be_psk_mismatch(struct wpa_supplicant *wpa_s, u16 reason_code,
2175d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				 int locally_generated)
2176d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{
2177d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (wpa_s->wpa_state != WPA_4WAY_HANDSHAKE ||
2178d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	    !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
2179d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return 0; /* Not in 4-way handshake with PSK */
2180d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2181d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	/*
2182d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 * It looks like connection was lost while trying to go through PSK
2183d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 * 4-way handshake. Filter out known disconnection cases that are caused
2184d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 * by something else than PSK mismatch to avoid confusing reports.
2185d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 */
2186d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2187d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (locally_generated) {
2188d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		if (reason_code == WLAN_REASON_IE_IN_4WAY_DIFFERS)
2189d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			return 0;
2190d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
2191d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2192d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	return 1;
2193d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt}
2194d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2195d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
21962b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenstatic void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
21972b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen						 u16 reason_code,
21982b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen						 int locally_generated)
21992b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen{
22002b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	const u8 *bssid;
22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int authenticating;
22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 prev_pending_bssid[ETH_ALEN];
22031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_bss *fast_reconnect = NULL;
22041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_ssid *fast_reconnect_ssid = NULL;
2205f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen	struct wpa_ssid *last_ssid;
22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * At least Host AP driver and a Prism3 card seemed to be
22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * generating streams of disconnected events when configuring
22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * IBSS for WPA-None. Ignore them for now.
22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - ignore in "
22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"IBSS/WPA-None mode");
22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2221d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) {
22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"pre-shared key may be incorrect");
2224391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (wpas_p2p_4way_hs_failed(wpa_s) > 0)
2225391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			return; /* P2P group removed */
22266dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		wpas_auth_failed(wpa_s, "WRONG_KEY");
22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2228ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt	if (!wpa_s->disconnected &&
2229ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt	    (!wpa_s->auto_reconnect_disabled ||
2230661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	     wpa_s->key_mgmt == WPA_KEY_MGMT_WPS ||
2231661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	     wpas_wps_searching(wpa_s))) {
22321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect enabled: try to "
2233661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			"reconnect (wps=%d/%d wpa_state=%d)",
22341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s->key_mgmt == WPA_KEY_MGMT_WPS,
2235661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			wpas_wps_searching(wpa_s),
22361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s->wpa_state);
22371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_s->wpa_state == WPA_COMPLETED &&
22381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    wpa_s->current_ssid &&
22391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
2240c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		    !locally_generated &&
22411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    disconnect_reason_recoverable(reason_code)) {
22421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/*
22431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * It looks like the AP has dropped association with
22441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * us, but could allow us to get back in. Try to
22451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * reconnect to the same BSS without full scan to save
22461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * time for some common cases.
22471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 */
22481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			fast_reconnect = wpa_s->current_bss;
22491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			fast_reconnect_ssid = wpa_s->current_ssid;
22501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (wpa_s->wpa_state >= WPA_ASSOCIATING)
2251c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 100000);
22521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		else
22531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Do not request new "
22541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				"immediate scan");
22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
22561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect disabled: do not "
22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"try to re-connect");
22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->reassociate = 0;
22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->disconnected = 1;
2260c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_supplicant_cancel_sched_scan(wpa_s);
22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bssid = wpa_s->bssid;
22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (is_zero_ether_addr(bssid))
22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid = wpa_s->pending_bssid;
22651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
22661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpas_connection_failed(wpa_s, bssid);
22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_notify_disassoc(wpa_s->wpa);
226804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (locally_generated)
226904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->disconnect_reason = -reason_code;
227004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
227104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->disconnect_reason = reason_code;
227204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpas_notify_disconnect_reason(wpa_s);
22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_dynamic_keys(wpa_s)) {
22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - remove keys");
22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_clear_keys(wpa_s, wpa_s->bssid);
22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2277f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen	last_ssid = wpa_s->current_ssid;
22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_mark_disassoc(wpa_s);
22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2280f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen	if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) {
22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sme_disassoc_while_authenticating(wpa_s, prev_pending_bssid);
2282f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen		wpa_s->current_ssid = last_ssid;
2283f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen	}
22841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2285f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if (fast_reconnect &&
2286f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    !wpas_network_disabled(wpa_s, fast_reconnect_ssid) &&
2287f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    !disallowed_bssid(wpa_s, fast_reconnect->bssid) &&
2288f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    !disallowed_ssid(wpa_s, fast_reconnect->ssid,
2289f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			     fast_reconnect->ssid_len) &&
2290f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    !wpas_temp_disabled(wpa_s, fast_reconnect_ssid)) {
22911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_SCAN_PROCESSING
22921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Try to reconnect to the same BSS");
22931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_supplicant_connect(wpa_s, fast_reconnect,
22941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   fast_reconnect_ssid) < 0) {
22951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/* Recover through full scan */
22961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 100000);
22971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
22981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
2299f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	} else if (fast_reconnect) {
2300f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		/*
2301f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 * Could not reconnect to the same BSS due to network being
2302f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 * disabled. Use a new scan to match the alternative behavior
2303f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 * above, i.e., to continue automatic reconnection attempt in a
2304f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 * way that enforces disabled network rules.
2305f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 */
2306f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 100000);
23071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
23121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpa_supplicant_delayed_mic_error_report(void *eloop_ctx, void *sock_ctx)
23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->pending_mic_error_report)
23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Sending pending MIC error report");
23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_key_request(wpa_s->wpa, 1, wpa_s->pending_mic_error_pairwise);
23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pending_mic_error_report = 0;
23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 union wpa_event_data *data)
23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pairwise;
2331fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct os_reltime t;
23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pairwise = (data && data->michael_mic_failure.unicast);
2335fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_get_reltime(&t);
2336fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if ((wpa_s->last_michael_mic_error.sec &&
2337fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	     !os_reltime_expired(&t, &wpa_s->last_michael_mic_error, 60)) ||
23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->pending_mic_error_report) {
23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->pending_mic_error_report) {
23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * Send the pending MIC error report immediately since
23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * we are going to start countermeasures and AP better
23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * do the same.
23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_sm_key_request(wpa_s->wpa, 1,
23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   wpa_s->pending_mic_error_pairwise);
23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Send the new MIC error report immediately since we are going
23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * to start countermeasures and AP better do the same.
23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* initialize countermeasures */
23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->countermeasures = 1;
23561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
23571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_blacklist_add(wpa_s, wpa_s->bssid);
23581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Need to wait for completion of request frame. We do not get
23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * any callback for the message completion, so just wait a
23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * short while and hope for the best. */
23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_sleep(0, 10000);
23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_countermeasures(wpa_s, 1);
23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deauthenticate(wpa_s,
23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      WLAN_REASON_MICHAEL_MIC_FAILURE);
23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_cancel_timeout(wpa_supplicant_stop_countermeasures,
23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     wpa_s, NULL);
23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_register_timeout(60, 0,
23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       wpa_supplicant_stop_countermeasures,
23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       wpa_s, NULL);
23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* TODO: mark the AP rejected for 60 second. STA is
23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * allowed to associate with another AP.. */
23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->mic_errors_seen) {
23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * Reduce the effectiveness of Michael MIC error
23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * reports as a means for attacking against TKIP if
23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * more than one MIC failure is noticed with the same
23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * PTK. We delay the transmission of the reports by a
23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * random time between 0 and 60 seconds in order to
23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * force the attacker wait 60 seconds before getting
23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * the information on whether a frame resulted in a MIC
23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * failure.
23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 rval[4];
23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int sec;
23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_get_random(rval, sizeof(rval)) < 0)
23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				sec = os_random() % 60;
23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				sec = WPA_GET_BE32(rval) % 60;
23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Delay MIC error "
23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"report %d seconds", sec);
23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->pending_mic_error_report = 1;
24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->pending_mic_error_pairwise = pairwise;
24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop_cancel_timeout(
24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_delayed_mic_error_report,
24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, NULL);
24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop_register_timeout(
24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				sec, os_random() % 1000000,
24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_delayed_mic_error_report,
24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, NULL);
24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_DELAYED_MIC_ERROR_REPORT */
24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2415fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->last_michael_mic_error = t;
24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->mic_errors_seen++;
24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TERMINATE_ONLASTIF
24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int any_interfaces(struct wpa_supplicant *head)
24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = head; wpa_s != NULL; wpa_s = wpa_s->next)
24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_s->interface_removed)
24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TERMINATE_ONLASTIF */
24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      union wpa_event_data *data)
24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (data->interface_status.ievent) {
24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_ADDED:
24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_s->interface_removed)
24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->interface_removed = 0;
24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was added");
24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_driver_init(wpa_s) < 0) {
24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "Failed to initialize the "
24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"driver after interface was added");
24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_REMOVED:
24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was removed");
24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->interface_removed = 1;
24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_mark_disassoc(wpa_s);
245504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l2_packet_deinit(wpa_s->l2);
24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->l2 = NULL;
24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TERMINATE_ONLASTIF
24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* check if last interface */
24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!any_interfaces(wpa_s->global->ifaces))
24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop_terminate();
24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TERMINATE_ONLASTIF */
24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY
24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_event_stkstart(struct wpa_supplicant *wpa_s,
24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      union wpa_event_data *data)
24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL)
24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_stkstart(wpa_s->wpa, data->stkstart.peer);
24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */
24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_tdls(struct wpa_supplicant *wpa_s,
24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      union wpa_event_data *data)
24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL)
24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (data->tdls.oper) {
24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TDLS_REQUEST_SETUP:
24884b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		wpa_tdls_remove(wpa_s->wpa, data->tdls.peer);
24894b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		if (wpa_tdls_is_external_setup(wpa_s->wpa))
24904b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			wpa_tdls_start(wpa_s->wpa, data->tdls.peer);
24914b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		else
24924b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, data->tdls.peer);
24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TDLS_REQUEST_TEARDOWN:
24956a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt		if (wpa_tdls_is_external_setup(wpa_s->wpa))
24966a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt			wpa_tdls_teardown_link(wpa_s->wpa, data->tdls.peer,
24976a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt					       data->tdls.reason_code);
24986a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt		else
24996a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt			wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN,
25006a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt					  data->tdls.peer);
25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
25024dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt	case TDLS_REQUEST_DISCOVER:
25034dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt			wpa_tdls_send_discovery_request(wpa_s->wpa,
25044dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt							data->tdls.peer);
25054dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt		break;
25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2511a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_WNM
251261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void wpa_supplicant_event_wnm(struct wpa_supplicant *wpa_s,
251361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				     union wpa_event_data *data)
251461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
251561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (data == NULL)
251661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
251761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	switch (data->wnm.oper) {
251861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	case WNM_OPER_SLEEP:
251961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Start sending WNM-Sleep Request "
252061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "(action=%d, intval=%d)",
252161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   data->wnm.sleep_action, data->wnm.sleep_intval);
252261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ieee802_11_send_wnmsleep_req(wpa_s, data->wnm.sleep_action,
2523a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt					     data->wnm.sleep_intval, NULL);
252461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		break;
252561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
252661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
2527a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_WNM */
252861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
252961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s,
25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 union wpa_event_data *data)
25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL)
25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_ft_process_response(wpa_s->wpa, data->ft_ies.ies,
25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.ies_len,
25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.ft_action,
25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.target_ap,
25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.ric_ies,
25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.ric_ies_len) < 0) {
25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* TODO: prevent MLME/driver from trying to associate? */
25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s,
25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						union wpa_event_data *data)
25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state < WPA_ASSOCIATED)
25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL)
25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_s->current_ssid;
25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL)
25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt))
25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer);
25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2567c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2568c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2569c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic void wpa_supplicant_event_ibss_auth(struct wpa_supplicant *wpa_s,
2570c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					   union wpa_event_data *data)
2571c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
2572c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
2573c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2574c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (ssid == NULL)
2575c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2576c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2577c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	/* check if the ssid is correctly configured as IBSS/RSN */
2578c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt))
2579c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2580c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2581c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	ibss_rsn_handle_auth(wpa_s->ibss_rsn, data->rx_mgmt.frame,
2582c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			     data->rx_mgmt.frame_len);
2583c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ft_rx_action(struct wpa_supplicant *wpa_s, const u8 *data,
25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 size_t len)
25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *sta_addr, *target_ap_addr;
25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 status;
25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump(MSG_MSGDUMP, "FT: RX Action", data, len);
25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return; /* only SME case supported for now */
25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len < 1 + 2 * ETH_ALEN + 2)
25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data[0] != 2)
26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return; /* Only FT Action Response is supported for now */
26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sta_addr = data + 1;
26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	target_ap_addr = data + 1 + ETH_ALEN;
26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	status = WPA_GET_LE16(data + 1 + 2 * ETH_ALEN);
26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "FT: Received FT Action Response: STA "
26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MACSTR " TargetAP " MACSTR " status %u",
26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(sta_addr), MAC2STR(target_ap_addr), status);
26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) {
26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "FT: Foreign STA Address " MACSTR
26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" in FT Action Response", MAC2STR(sta_addr));
26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (status) {
26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "FT: FT Action Response indicates "
26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"failure (status code %d)", status);
26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* TODO: report error to FT code(?) */
26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_ft_process_response(wpa_s->wpa, data + 1 + 2 * ETH_ALEN + 2,
26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    len - (1 + 2 * ETH_ALEN + 2), 1,
26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    target_ap_addr, NULL, 0) < 0)
26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SME
26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	{
26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_bss *bss;
26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss = wpa_bss_get_bssid(wpa_s, target_ap_addr);
26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss)
26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->sme.freq = bss->freq;
26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->sme.auth_alg = WPA_AUTH_ALG_FT;
26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sme_associate(wpa_s, WPAS_MODE_INFRA, target_ap_addr,
26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      WLAN_AUTH_FT);
26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SME */
26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_unprot_deauth(struct wpa_supplicant *wpa_s,
26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       struct unprot_deauth *e)
26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Unprotected Deauthentication frame "
26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "dropped: " MACSTR " -> " MACSTR
26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   " (reason code %u)",
26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_unprot_disassoc(struct wpa_supplicant *wpa_s,
26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 struct unprot_disassoc *e)
26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Unprotected Disassociation frame "
26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "dropped: " MACSTR " -> " MACSTR
26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   " (reason code %u)",
26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2667c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic void wpas_event_disconnect(struct wpa_supplicant *wpa_s, const u8 *addr,
2668c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				  u16 reason_code, int locally_generated,
2669c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				  const u8 *ie, size_t ie_len, int deauth)
2670c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
2671c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_AP
2672c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->ap_iface && addr) {
2673c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], addr);
2674c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2675c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2676c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2677c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->ap_iface) {
2678c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Ignore deauth event in AP mode");
2679c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2680c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2681c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
2682c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2683203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	if (!locally_generated)
2684203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		wpa_s->own_disconnect_req = 0;
2685203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt
2686c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_supplicant_event_disassoc(wpa_s, reason_code, locally_generated);
2687c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2688344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	if (((reason_code == WLAN_REASON_IEEE_802_1X_AUTH_FAILED ||
2689344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	      ((wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2690344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		(wpa_s->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) &&
2691344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	       eapol_sm_failed(wpa_s->eapol))) &&
2692344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	     !wpa_s->eap_expected_failure))
26936dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		wpas_auth_failed(wpa_s, "AUTH_FAILED");
2694c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2695c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_P2P
2696391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (deauth && reason_code > 0) {
2697c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		if (wpas_p2p_deauth_notif(wpa_s, addr, reason_code, ie, ie_len,
2698c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					  locally_generated) > 0) {
2699c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			/*
2700c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			 * The interface was removed, so cannot continue
2701c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			 * processing any additional operations after this.
2702c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			 */
2703c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			return;
2704c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		}
2705c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2706c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_P2P */
2707c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2708c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_supplicant_event_disassoc_finish(wpa_s, reason_code,
2709c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					     locally_generated);
2710c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
2711c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2712c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2713c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic void wpas_event_disassoc(struct wpa_supplicant *wpa_s,
2714c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				struct disassoc_info *info)
2715c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
2716c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	u16 reason_code = 0;
2717c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	int locally_generated = 0;
2718c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	const u8 *addr = NULL;
2719c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	const u8 *ie = NULL;
2720c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	size_t ie_len = 0;
2721c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2722c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Disassociation notification");
2723c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2724c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (info) {
2725c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		addr = info->addr;
2726c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		ie = info->ie;
2727c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		ie_len = info->ie_len;
2728c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		reason_code = info->reason_code;
2729c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		locally_generated = info->locally_generated;
2730c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s", reason_code,
2731c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			locally_generated ? " (locally generated)" : "");
2732c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		if (addr)
2733c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
2734c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				MAC2STR(addr));
2735c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_hexdump(MSG_DEBUG, "Disassociation frame IE(s)",
2736c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			    ie, ie_len);
2737c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2738c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2739c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_AP
2740c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->ap_iface && info && info->addr) {
2741c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], info->addr);
2742c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2743c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2744c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2745c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->ap_iface) {
2746c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Ignore disassoc event in AP mode");
2747c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2748c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2749c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
2750c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2751c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_P2P
2752c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (info) {
2753c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpas_p2p_disassoc_notif(
2754c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			wpa_s, info->addr, reason_code, info->ie, info->ie_len,
2755c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			locally_generated);
2756c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2757c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_P2P */
2758c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2759c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
2760c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		sme_event_disassoc(wpa_s, info);
2761c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2762c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpas_event_disconnect(wpa_s, addr, reason_code, locally_generated,
2763c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			      ie, ie_len, 0);
2764c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
2765c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2766c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2767c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic void wpas_event_deauth(struct wpa_supplicant *wpa_s,
2768c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			      struct deauth_info *info)
2769c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
2770c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	u16 reason_code = 0;
2771c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	int locally_generated = 0;
2772c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	const u8 *addr = NULL;
2773c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	const u8 *ie = NULL;
2774c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	size_t ie_len = 0;
2775c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2776c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Deauthentication notification");
2777c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2778c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (info) {
2779c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		addr = info->addr;
2780c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		ie = info->ie;
2781c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		ie_len = info->ie_len;
2782c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		reason_code = info->reason_code;
2783c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		locally_generated = info->locally_generated;
2784c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s",
2785c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			reason_code,
2786c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			locally_generated ? " (locally generated)" : "");
2787c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		if (addr) {
2788c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
2789c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				MAC2STR(addr));
2790c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		}
2791c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_hexdump(MSG_DEBUG, "Deauthentication frame IE(s)",
2792c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			    ie, ie_len);
2793c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2794c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2795c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_reset_ft_completed(wpa_s->wpa);
2796c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2797c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpas_event_disconnect(wpa_s, addr, reason_code,
2798c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			      locally_generated, ie, ie_len, 1);
2799c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
2800c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2801c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
28027dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtstatic const char * reg_init_str(enum reg_change_initiator init)
28037dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt{
28047dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	switch (init) {
28057dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_SET_BY_CORE:
28067dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "CORE";
28077dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_SET_BY_USER:
28087dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "USER";
28097dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_SET_BY_DRIVER:
28107dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "DRIVER";
28117dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_SET_BY_COUNTRY_IE:
28127dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "COUNTRY_IE";
28137dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_BEACON_HINT:
28147dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "BEACON_HINT";
28157dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	}
28167dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	return "?";
28177dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt}
28187dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
28197dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
28207dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtstatic const char * reg_type_str(enum reg_type type)
28217dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt{
28227dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	switch (type) {
28237dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_UNKNOWN:
28247dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "UNKNOWN";
28257dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_COUNTRY:
28267dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "COUNTRY";
28277dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_WORLD:
28287dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "WORLD";
28297dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_CUSTOM_WORLD:
28307dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "CUSTOM_WORLD";
28317dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_INTERSECTION:
28327dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "INTERSECTION";
28337dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	}
28347dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	return "?";
28357dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt}
28367dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
28377dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
28387dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtstatic void wpa_supplicant_update_channel_list(
28397dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	struct wpa_supplicant *wpa_s, struct channel_list_changed *info)
2840cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{
2841cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	struct wpa_supplicant *ifs;
2842cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
28437dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s",
2844c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt		reg_init_str(info->initiator), reg_type_str(info->type),
28457dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		info->alpha2[0] ? " alpha2=" : "",
28467dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		info->alpha2[0] ? info->alpha2 : "");
28477dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
2848cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (wpa_s->drv_priv == NULL)
2849cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		return; /* Ignore event during drv initialization */
2850cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
2851cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	free_hw_features(wpa_s);
2852cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	wpa_s->hw.modes = wpa_drv_get_hw_feature_data(
2853cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		wpa_s, &wpa_s->hw.num_modes, &wpa_s->hw.flags);
2854cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
2855cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	wpas_p2p_update_channel_list(wpa_s);
2856cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
2857cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	/*
285801904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt	 * Check other interfaces to see if they share the same radio. If
2859cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 * so, they get updated with this same hw mode info.
2860cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 */
286101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
286201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 radio_list) {
286301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		if (ifs != wpa_s) {
2864cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			wpa_printf(MSG_DEBUG, "%s: Updating hw mode",
2865cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				   ifs->ifname);
2866cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			free_hw_features(ifs);
2867cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			ifs->hw.modes = wpa_drv_get_hw_feature_data(
2868cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				ifs, &ifs->hw.num_modes, &ifs->hw.flags);
2869cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		}
2870cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	}
2871cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt}
2872cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
2873cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
2874fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
28756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				      const u8 *frame, size_t len, int freq,
28766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				      int rssi)
2877fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
2878623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt	const struct ieee80211_mgmt *mgmt;
2879fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	const u8 *payload;
2880fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	size_t plen;
2881fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	u8 category;
2882fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2883fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (len < IEEE80211_HDRLEN + 2)
2884fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2885fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2886623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt	mgmt = (const struct ieee80211_mgmt *) frame;
2887623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt	payload = frame + IEEE80211_HDRLEN;
2888fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	category = *payload++;
2889623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt	plen = len - IEEE80211_HDRLEN - 1;
2890fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2891fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Received Action frame: SA=" MACSTR
2892fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		" Category=%u DataLen=%d freq=%d MHz",
2893fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		MAC2STR(mgmt->sa), category, (int) plen, freq);
2894fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
28956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (category == WLAN_ACTION_WMM) {
28966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wmm_ac_rx_action(wpa_s, mgmt->da, mgmt->sa, payload, plen);
28976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return;
28986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
28996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
2900fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_IEEE80211R
2901fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (category == WLAN_ACTION_FT) {
2902fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		ft_rx_action(wpa_s, payload, plen);
2903fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2904fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
2905fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
2906fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2907fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_IEEE80211W
2908fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_SME
2909fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (category == WLAN_ACTION_SA_QUERY) {
2910fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		sme_sa_query_rx(wpa_s, mgmt->sa, payload, plen);
2911fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2912fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
2913fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_SME */
2914fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
2915fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2916fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_WNM
2917fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (mgmt->u.action.category == WLAN_ACTION_WNM) {
2918fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		ieee802_11_rx_wnm_action(wpa_s, mgmt, len);
2919fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2920fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
2921fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_WNM */
2922fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2923fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_GAS
29241846323989242844f0e857458a8939fa5836429cDmitry Shmidt	if ((mgmt->u.action.category == WLAN_ACTION_PUBLIC ||
29251846323989242844f0e857458a8939fa5836429cDmitry Shmidt	     mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) &&
2926fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    gas_query_rx(wpa_s->gas, mgmt->da, mgmt->sa, mgmt->bssid,
29271846323989242844f0e857458a8939fa5836429cDmitry Shmidt			 mgmt->u.action.category,
2928fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			 payload, plen, freq) == 0)
2929fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2930fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_GAS */
2931fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2932fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_TDLS
2933fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (category == WLAN_ACTION_PUBLIC && plen >= 4 &&
2934fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    payload[0] == WLAN_TDLS_DISCOVERY_RESPONSE) {
2935fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
2936fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			"TDLS: Received Discovery Response from " MACSTR,
2937fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			MAC2STR(mgmt->sa));
2938fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2939fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
2940fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_TDLS */
2941fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2942fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_INTERWORKING
2943fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (category == WLAN_ACTION_QOS && plen >= 1 &&
2944fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    payload[0] == QOS_QOS_MAP_CONFIG) {
2945fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		const u8 *pos = payload + 1;
2946fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		size_t qlen = plen - 1;
2947fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: Received QoS Map Configure frame from "
2948fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			MACSTR, MAC2STR(mgmt->sa));
2949fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) == 0 &&
2950fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		    qlen > 2 && pos[0] == WLAN_EID_QOS_MAP_SET &&
2951fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		    pos[1] <= qlen - 2 && pos[1] >= 16)
2952fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpas_qos_map_set(wpa_s, pos + 2, pos[1]);
2953fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
2954fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
2955fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
2956fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
29576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
29586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	    payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) {
29596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpas_rrm_process_neighbor_rep(wpa_s, payload + 1, plen - 1);
29606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return;
29616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
29626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
29636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
29646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	    payload[0] == WLAN_RRM_LINK_MEASUREMENT_REQUEST) {
29656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpas_rrm_handle_link_measurement_request(wpa_s, mgmt->sa,
29666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt							 payload + 1, plen - 1,
29676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt							 rssi);
29686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return;
29696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
29706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
2971fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
2972fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			   category, payload, plen, freq);
29736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_s->ifmsh)
29746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		mesh_mpm_action_rx(wpa_s, mgmt, len);
2975fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
2976fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2977fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
2978cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic void wpa_supplicant_notify_avoid_freq(struct wpa_supplicant *wpa_s,
2979cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					     union wpa_event_data *event)
2980cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
2981cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P
2982cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_supplicant *ifs;
2983cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */
2984cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_freq_range_list *list;
2985cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	char *str = NULL;
2986cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
2987cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	list = &event->freq_range;
2988cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
2989cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (list->num)
2990cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		str = freq_range_list_str(list);
2991cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AVOID_FREQ "ranges=%s",
2992cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		str ? str : "");
2993cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
2994cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P
2995cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (freq_range_list_parse(&wpa_s->global->p2p_go_avoid_freq, str)) {
2996cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_dbg(wpa_s, MSG_ERROR, "%s: Failed to parse freq range",
2997cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			__func__);
2998cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else {
2999cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Update channel list based on frequency avoid event");
3000cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpas_p2p_update_channel_list(wpa_s);
3001cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
3002cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3003cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
3004cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		int freq;
3005cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (!ifs->current_ssid ||
3006cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    !ifs->current_ssid->p2p_group ||
3007cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    (ifs->current_ssid->mode != WPAS_MODE_P2P_GO &&
3008cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		     ifs->current_ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION))
3009cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			continue;
3010cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3011cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		freq = ifs->current_ssid->frequency;
3012cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (!freq_range_list_includes(list, freq)) {
3013cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_dbg(ifs, MSG_DEBUG, "P2P GO operating frequency %d MHz in safe range",
3014cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				freq);
3015cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			continue;
3016cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
3017cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3018cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_dbg(ifs, MSG_DEBUG, "P2P GO operating in unsafe frequency %d MHz",
3019cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			freq);
3020cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		/* TODO: Consider using CSA or removing the group within
3021cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		 * wpa_supplicant */
3022cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_msg(ifs, MSG_INFO, P2P_EVENT_REMOVE_AND_REFORM_GROUP);
3023cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
3024cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */
3025cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3026cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	os_free(str);
3027cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
3028cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3029cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
30306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpa_supplicant_event_assoc_auth(struct wpa_supplicant *wpa_s,
30316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					    union wpa_event_data *data)
30326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
30336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG,
30346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		"Connection authorized by device, previous state %d",
30356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_s->wpa_state);
30366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_s->wpa_state == WPA_ASSOCIATED) {
30376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
30386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
30396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
30406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
30416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
30426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_sm_set_rx_replay_ctr(wpa_s->wpa, data->assoc_info.key_replay_ctr);
30436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_sm_set_ptk_kck_kek(wpa_s->wpa, data->assoc_info.ptk_kck,
3044807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt			       data->assoc_info.ptk_kck_len,
3045807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt			       data->assoc_info.ptk_kek,
3046807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt			       data->assoc_info.ptk_kek_len);
30476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
30486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
30496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_event(void *ctx, enum wpa_event_type event,
30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  union wpa_event_data *data)
30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    event != EVENT_INTERFACE_ENABLED &&
30571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    event != EVENT_INTERFACE_STATUS &&
30581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    event != EVENT_SCHED_SCAN_STOPPED) {
30591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
30601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			"Ignore event %s (%d) while interface is disabled",
30611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			event_to_string(event), event);
30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG
30661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
30671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int level = MSG_DEBUG;
30681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
306904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (event == EVENT_RX_MGMT && data->rx_mgmt.frame_len >= 24) {
30701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		const struct ieee80211_hdr *hdr;
30711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		u16 fc;
30721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
30731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		fc = le_to_host16(hdr->frame_control);
30741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
30751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
30761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			level = MSG_EXCESSIVE;
30771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
30781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
30791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_dbg(wpa_s, level, "Event %s (%d) received",
30801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		event_to_string(event), event);
30811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
30821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */
30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (event) {
30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_AUTH:
30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sme_event_auth(wpa_s, data);
30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_ASSOC:
30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_assoc(wpa_s, data);
30906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (data && data->assoc_info.authorized)
30916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_supplicant_event_assoc_auth(wpa_s, data);
30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_DISASSOC:
3094c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpas_event_disassoc(wpa_s,
3095c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				    data ? &data->disassoc_info : NULL);
3096c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		break;
30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_DEAUTH:
3098c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpas_event_deauth(wpa_s,
3099c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				  data ? &data->deauth_info : NULL);
31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_MICHAEL_MIC_FAILURE:
31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_michael_mic_failure(wpa_s, data);
31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_SCAN_PROCESSING
3105fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	case EVENT_SCAN_STARTED:
3106fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_get_reltime(&wpa_s->scan_start_time);
3107fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (wpa_s->own_scan_requested) {
3108fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			struct os_reltime diff;
3109fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3110fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			os_reltime_sub(&wpa_s->scan_start_time,
3111fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				       &wpa_s->scan_trigger_time, &diff);
3112fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Own scan request started a scan in %ld.%06ld seconds",
3113fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				diff.sec, diff.usec);
3114fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_s->own_scan_requested = 0;
3115fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_s->own_scan_running = 1;
3116fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
3117fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			    wpa_s->manual_scan_use_id) {
3118661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				wpa_msg_ctrl(wpa_s, MSG_INFO,
3119661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					     WPA_EVENT_SCAN_STARTED "id=%u",
3120661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					     wpa_s->manual_scan_id);
3121fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			} else {
3122661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				wpa_msg_ctrl(wpa_s, MSG_INFO,
3123661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					     WPA_EVENT_SCAN_STARTED);
3124fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			}
3125fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		} else {
3126fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "External program started a scan");
31272f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt			wpa_s->radio->external_scan_running = 1;
3128661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_STARTED);
3129fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		}
3130fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		break;
31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_SCAN_RESULTS:
3132fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (os_reltime_initialized(&wpa_s->scan_start_time)) {
3133fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			struct os_reltime now, diff;
3134fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			os_get_reltime(&now);
3135fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			os_reltime_sub(&now, &wpa_s->scan_start_time, &diff);
3136fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_s->scan_start_time.sec = 0;
3137fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_s->scan_start_time.usec = 0;
3138fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Scan completed in %ld.%06ld seconds",
3139fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				diff.sec, diff.usec);
3140fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		}
31417f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		if (wpa_supplicant_event_scan_results(wpa_s, data))
31427f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			break; /* interface may have been removed */
3143fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->own_scan_running = 0;
31442f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt		wpa_s->radio->external_scan_running = 0;
3145fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_check_next(wpa_s);
31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_ASSOCINFO:
31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_associnfo(wpa_s, data);
31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_STATUS:
31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_interface_status(wpa_s, data);
31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_PMKID_CANDIDATE:
31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_pmkid_candidate(wpa_s, data);
31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY
31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_STKSTART:
31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_stkstart(wpa_s, data);
31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */
31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_TDLS:
31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_tdls(wpa_s, data);
31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
3167a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_WNM
316861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	case EVENT_WNM:
316961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_supplicant_event_wnm(wpa_s, data);
317061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		break;
3171a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_WNM */
31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_FT_RESPONSE:
31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_ft_response(wpa_s, data);
31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_IBSS_RSN_START:
31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_ibss_rsn_start(wpa_s, data);
31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_ASSOC_REJECT:
31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (data->assoc_reject.bssid)
31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"bssid=" MACSTR	" status_code=%u",
31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				MAC2STR(data->assoc_reject.bssid),
31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->assoc_reject.status_code);
31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"status_code=%u",
31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->assoc_reject.status_code);
31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			sme_event_assoc_reject(wpa_s, data);
3194b485b188f853a4ec5342c2ea49705b545b2caf3dJeff Johnson		else {
3195d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			const u8 *bssid = data->assoc_reject.bssid;
3196d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			if (bssid == NULL || is_zero_ether_addr(bssid))
3197d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				bssid = wpa_s->pending_bssid;
3198d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			wpas_connection_failed(wpa_s, bssid);
3199d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			wpa_supplicant_mark_disassoc(wpa_s);
3200d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		}
32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_AUTH_TIMED_OUT:
32036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		/* It is possible to get this event from earlier connection */
32046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (wpa_s->current_ssid &&
32056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		    wpa_s->current_ssid->mode == WPAS_MODE_MESH) {
32066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
32076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				"Ignore AUTH_TIMED_OUT in mesh configuration");
32086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			break;
32096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		}
32108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			sme_event_auth_timed_out(wpa_s, data);
32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_ASSOC_TIMED_OUT:
32146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		/* It is possible to get this event from earlier connection */
32156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (wpa_s->current_ssid &&
32166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		    wpa_s->current_ssid->mode == WPAS_MODE_MESH) {
32176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
32186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				"Ignore ASSOC_TIMED_OUT in mesh configuration");
32196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			break;
32206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		}
32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			sme_event_assoc_timed_out(wpa_s, data);
32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_TX_STATUS:
32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS dst=" MACSTR
32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" type=%d stype=%d",
32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(data->tx_status.dst),
32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->tx_status.type, data->tx_status.stype);
32291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_AP
32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface == NULL) {
32311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->tx_status.stype == WLAN_FC_STYPE_ACTION)
32341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				offchannel_send_action_tx_status(
32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_s, data->tx_status.dst,
32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->tx_status.data,
32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->tx_status.data_len,
32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->tx_status.ack ?
32391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					OFFCHANNEL_SEND_ACTION_SUCCESS :
32401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					OFFCHANNEL_SEND_ACTION_NO_ACK);
32411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
32441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_AP */
32451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS pending_dst="
32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MACSTR, MAC2STR(wpa_s->parent->pending_action_dst));
32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Catch TX status events for Action frames we sent via group
32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * interface in GO mode.
32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    data->tx_status.stype == WLAN_FC_STYPE_ACTION &&
32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(wpa_s->parent->pending_action_dst,
32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      data->tx_status.dst, ETH_ALEN) == 0) {
32561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			offchannel_send_action_tx_status(
32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->parent, data->tx_status.dst,
32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->tx_status.data,
32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->tx_status.data_len,
32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->tx_status.ack ?
32611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				OFFCHANNEL_SEND_ACTION_SUCCESS :
32621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				OFFCHANNEL_SEND_ACTION_NO_ACK);
32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
32651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
32661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_AP
32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		switch (data->tx_status.type) {
32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case WLAN_FC_TYPE_MGMT:
32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ap_mgmt_tx_cb(wpa_s, data->tx_status.data,
32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      data->tx_status.data_len,
32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      data->tx_status.stype,
32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      data->tx_status.ack);
32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case WLAN_FC_TYPE_DATA:
32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ap_tx_status(wpa_s, data->tx_status.dst,
32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     data->tx_status.data,
32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     data->tx_status.data_len,
32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     data->tx_status.ack);
32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
32811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_AP */
32821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
32831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_AP
32841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_EAPOL_TX_STATUS:
32851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ap_eapol_tx_status(wpa_s, data->eapol_tx_status.dst,
32861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   data->eapol_tx_status.data,
32871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   data->eapol_tx_status.data_len,
32881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   data->eapol_tx_status.ack);
32891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
32901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_DRIVER_CLIENT_POLL_OK:
32911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ap_client_poll_ok(wpa_s, data->client_poll.addr);
32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_RX_FROM_UNKNOWN:
32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface == NULL)
32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
32961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.addr,
32971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       data->rx_from_unknown.wds);
32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
329904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case EVENT_CH_SWITCH:
330004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!data)
330104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
330204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpa_s->ap_iface) {
330304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "AP: Ignore channel switch "
330404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				"event in non-AP mode");
330504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
330604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
330704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
330804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_ap_ch_switch(wpa_s, data->ch_switch.freq,
330904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  data->ch_switch.ht_enabled,
331004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				  data->ch_switch.ch_offset,
331104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				  data->ch_switch.ch_width,
331204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				  data->ch_switch.cf1,
331304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				  data->ch_switch.cf2);
331404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
3315203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef NEED_AP_MLME
3316203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_RADAR_DETECTED:
3317203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3318203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_radar_detected(wpa_s, &data->dfs_event);
3319203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3320203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_CAC_STARTED:
3321203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3322203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_cac_started(wpa_s, &data->dfs_event);
3323203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3324203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_CAC_FINISHED:
3325203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3326203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_cac_finished(wpa_s, &data->dfs_event);
3327203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3328203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_CAC_ABORTED:
3329203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3330203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_cac_aborted(wpa_s, &data->dfs_event);
3331203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3332203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_NOP_FINISHED:
3333203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3334203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_cac_nop_finished(wpa_s,
3335203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt							&data->dfs_event);
3336203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3337203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* NEED_AP_MLME */
3338c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
333904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case EVENT_RX_MGMT: {
334004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		u16 fc, stype;
334104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		const struct ieee80211_mgmt *mgmt;
334204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3343818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS
3344818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		if (wpa_s->ext_mgmt_frame_handling) {
3345818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			struct rx_mgmt *rx = &data->rx_mgmt;
3346818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			size_t hex_len = 2 * rx->frame_len + 1;
3347818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			char *hex = os_malloc(hex_len);
3348818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			if (hex) {
3349818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt				wpa_snprintf_hex(hex, hex_len,
3350818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt						 rx->frame, rx->frame_len);
3351818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt				wpa_msg(wpa_s, MSG_INFO, "MGMT-RX freq=%d datarate=%u ssi_signal=%d %s",
3352818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt					rx->freq, rx->datarate, rx->ssi_signal,
3353818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt					hex);
3354818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt				os_free(hex);
3355818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			}
3356818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			break;
3357818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		}
3358818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */
3359818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
336004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		mgmt = (const struct ieee80211_mgmt *)
336104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			data->rx_mgmt.frame;
336204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		fc = le_to_host16(mgmt->frame_control);
336304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		stype = WLAN_FC_GET_STYPE(fc);
336404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3365c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_AP
33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface == NULL) {
3367c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (stype == WLAN_FC_STYPE_PROBE_REQ &&
33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->rx_mgmt.frame_len > 24) {
33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				const u8 *src = mgmt->sa;
33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				const u8 *ie = mgmt->u.probe_req.variable;
33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				size_t ie_len = data->rx_mgmt.frame_len -
33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					(mgmt->u.probe_req.variable -
33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 data->rx_mgmt.frame);
337604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpas_p2p_probe_req_rx(
337704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					wpa_s, src, mgmt->da,
337804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					mgmt->bssid, ie, ie_len,
337904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					data->rx_mgmt.ssi_signal);
33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
33818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
3383c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_IBSS_RSN
33846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (wpa_s->current_ssid &&
33856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			    wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
33866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			    stype == WLAN_FC_STYPE_AUTH &&
3387c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			    data->rx_mgmt.frame_len >= 30) {
3388c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				wpa_supplicant_event_ibss_auth(wpa_s, data);
3389c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				break;
3390c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			}
3391c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_IBSS_RSN */
3392fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3393fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			if (stype == WLAN_FC_STYPE_ACTION) {
3394fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				wpas_event_rx_mgmt_action(
3395623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt					wpa_s, data->rx_mgmt.frame,
3396623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt					data->rx_mgmt.frame_len,
33976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					data->rx_mgmt.freq,
33986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					data->rx_mgmt.ssi_signal);
33996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				break;
34006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			}
34016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
34026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (wpa_s->ifmsh) {
34036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				mesh_mpm_mgmt_rx(wpa_s, &data->rx_mgmt);
3404fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				break;
3405fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			}
3406fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "AP: ignore received "
34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"management frame in non-AP mode");
34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3410c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_AP
34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
341204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
341304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (stype == WLAN_FC_STYPE_PROBE_REQ &&
341404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		    data->rx_mgmt.frame_len > 24) {
341504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			const u8 *ie = mgmt->u.probe_req.variable;
341604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			size_t ie_len = data->rx_mgmt.frame_len -
341704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				(mgmt->u.probe_req.variable -
341804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 data->rx_mgmt.frame);
341904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
342004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpas_notify_preq(wpa_s, mgmt->sa, mgmt->da,
342104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 mgmt->bssid, ie, ie_len,
342204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 data->rx_mgmt.ssi_signal);
342304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
342404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ap_mgmt_rx(wpa_s, &data->rx_mgmt);
3426c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
342804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_RX_PROBE_REQ:
34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (data->rx_probe_req.sa == NULL ||
34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    data->rx_probe_req.ie == NULL)
34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface) {
34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			hostapd_probe_req_rx(wpa_s->ap_iface->bss[0],
34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     data->rx_probe_req.sa,
34371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					     data->rx_probe_req.da,
34381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					     data->rx_probe_req.bssid,
34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     data->rx_probe_req.ie,
344004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					     data->rx_probe_req.ie_len,
344104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					     data->rx_probe_req.ssi_signal);
34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_probe_req_rx(wpa_s, data->rx_probe_req.sa,
34461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      data->rx_probe_req.da,
34471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      data->rx_probe_req.bssid,
34488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      data->rx_probe_req.ie,
344904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				      data->rx_probe_req.ie_len,
345004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				      data->rx_probe_req.ssi_signal);
34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_REMAIN_ON_CHANNEL:
34531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
34541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		offchannel_remain_on_channel_cb(
34551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s, data->remain_on_channel.freq,
34561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			data->remain_on_channel.duration);
34571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_remain_on_channel_cb(
34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, data->remain_on_channel.freq,
34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->remain_on_channel.duration);
34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_CANCEL_REMAIN_ON_CHANNEL:
34631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
34641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		offchannel_cancel_remain_on_channel_cb(
34651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s, data->remain_on_channel.freq);
34661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_cancel_remain_on_channel_cb(
34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, data->remain_on_channel.freq);
34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
34708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_EAPOL_RX:
34718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
34728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->eapol_rx.data,
34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->eapol_rx.data_len);
34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
34758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_SIGNAL_CHANGE:
34767dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
34777dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			"above=%d signal=%d noise=%d txrate=%d",
34787dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			data->signal_change.above_threshold,
34797dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			data->signal_change.current_signal,
34807dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			data->signal_change.current_noise,
34817dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			data->signal_change.current_txrate);
34827f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_bss_update_level(wpa_s->current_bss,
34837f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt				     data->signal_change.current_signal);
34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bgscan_notify_signal_change(
34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, data->signal_change.above_threshold,
34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->signal_change.current_signal,
34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->signal_change.current_noise,
34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->signal_change.current_txrate);
34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_ENABLED:
34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled");
34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
34931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_supplicant_update_mac_addr(wpa_s);
3494df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt			if (wpa_s->p2p_mgmt) {
3495df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt				wpa_supplicant_set_state(wpa_s,
3496df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt							 WPA_DISCONNECTED);
3497df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt				break;
3498df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt			}
3499df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt
35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_s->ap_iface) {
35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_set_state(wpa_s,
35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							 WPA_DISCONNECTED);
3504ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				wpa_s->scan_req = NORMAL_SCAN_REQ;
35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_req_scan(wpa_s, 0, 0);
35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else
35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_set_state(wpa_s,
35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							 WPA_COMPLETED);
35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_AP */
35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 0);
35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
35148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
35158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_DISABLED:
35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled");
351701904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt#ifdef CONFIG_P2P
351801904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
351901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		    (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group &&
352001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		     wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)) {
352101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			/*
3522ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 * Mark interface disabled if this happens to end up not
3523ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 * being removed as a separate P2P group interface.
3524ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 */
3525ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
3526ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			/*
352701904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 * The interface was externally disabled. Remove
352801904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 * it assuming an external entity will start a
352901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 * new session if needed.
353001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 */
3531ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			if (wpa_s->current_ssid &&
3532ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			    wpa_s->current_ssid->p2p_group)
3533ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				wpas_p2p_interface_unavailable(wpa_s);
3534ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			else
3535ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				wpas_p2p_disconnect(wpa_s);
3536ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			/*
3537ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 * wpa_s instance may have been freed, so must not use
3538ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 * it here anymore.
3539ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 */
354001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			break;
354101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		}
35426dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		if (wpa_s->p2p_scan_work && wpa_s->global->p2p &&
35436dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		    p2p_in_progress(wpa_s->global->p2p) > 1) {
35446dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt			/* This radio work will be cancelled, so clear P2P
35456dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt			 * state as well.
35466dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt			 */
35476dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt			p2p_stop_find(wpa_s->global->p2p);
35486dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		}
354901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt#endif /* CONFIG_P2P */
355001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt
35517832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt		if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
35527832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			/*
35537832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			 * Indicate disconnection to keep ctrl_iface events
35547832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			 * consistent.
35557832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			 */
35567832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			wpa_supplicant_event_disassoc(
35577832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
35587832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt		}
35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_mark_disassoc(wpa_s);
3560bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		radio_remove_works(wpa_s, NULL, 0);
3561bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt
35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_CHANNEL_LIST_CHANGED:
35657dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		wpa_supplicant_update_channel_list(
35667dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			wpa_s, &data->channel_list_changed);
35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_UNAVAILABLE:
35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_interface_unavailable(wpa_s);
35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_BEST_CHANNEL:
35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Best channel event received "
35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"(%d %d %d)",
35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->best_chan.freq_24, data->best_chan.freq_5,
35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->best_chan.freq_overall);
35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->best_24_freq = data->best_chan.freq_24;
35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->best_5_freq = data->best_chan.freq_5;
35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->best_overall_freq = data->best_chan.freq_overall;
35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_update_best_channels(wpa_s, data->best_chan.freq_24,
35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      data->best_chan.freq_5,
35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      data->best_chan.freq_overall);
35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_UNPROT_DEAUTH:
35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_unprot_deauth(wpa_s,
35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   &data->unprot_deauth);
35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_UNPROT_DISASSOC:
35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_unprot_disassoc(wpa_s,
35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     &data->unprot_disassoc);
35908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
35918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_STATION_LOW_ACK:
35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
35938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface && data)
35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			hostapd_event_sta_low_ack(wpa_s->ap_iface->bss[0],
35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  data->low_ack.addr);
35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
35971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TDLS
35981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (data)
359943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			wpa_tdls_disable_unreachable_link(wpa_s->wpa,
360043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt							  data->low_ack.addr);
36011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TDLS */
36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_IBSS_PEER_LOST:
36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ibss_rsn_stop(wpa_s->ibss_rsn, data->ibss_peer_lost.peer);
36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
36078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
36081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_DRIVER_GTK_REKEY:
36091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (os_memcmp(data->driver_gtk_rekey.bssid,
36101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			      wpa_s->bssid, ETH_ALEN))
36111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			break;
36121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!wpa_s->wpa)
36131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			break;
36141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_sm_update_replay_ctr(wpa_s->wpa,
36151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					 data->driver_gtk_rekey.replay_ctr);
36161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
36171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_SCHED_SCAN_STOPPED:
36181846323989242844f0e857458a8939fa5836429cDmitry Shmidt		wpa_s->pno = 0;
36191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->sched_scanning = 0;
36201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_supplicant_notify_scanning(wpa_s, 0);
36211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
36221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
36231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			break;
36241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
36251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/*
36261846323989242844f0e857458a8939fa5836429cDmitry Shmidt		 * Start a new sched scan to continue searching for more SSIDs
36271846323989242844f0e857458a8939fa5836429cDmitry Shmidt		 * either if timed out or PNO schedule scan is pending.
36281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 */
36299866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt		if (wpa_s->sched_scan_timed_out) {
36309866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt			wpa_supplicant_req_sched_scan(wpa_s);
36319866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt		} else if (wpa_s->pno_sched_pending) {
36329866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt			wpa_s->pno_sched_pending = 0;
36339866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt			wpas_start_pno(wpa_s);
36341846323989242844f0e857458a8939fa5836429cDmitry Shmidt		}
36351846323989242844f0e857458a8939fa5836429cDmitry Shmidt
36361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
36371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_WPS_BUTTON_PUSHED:
36381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_WPS
36391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpas_wps_start_pbc(wpa_s, NULL, 0);
36401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_WPS */
36411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
3642cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	case EVENT_AVOID_FREQUENCIES:
3643cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_supplicant_notify_avoid_freq(wpa_s, data);
3644cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		break;
3645f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	case EVENT_CONNECT_FAILED_REASON:
3646f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_AP
3647f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		if (!wpa_s->ap_iface || !data)
3648f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			break;
3649f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		hostapd_event_connect_failed_reason(
3650f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			wpa_s->ap_iface->bss[0],
3651f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			data->connect_failed_reason.addr,
3652f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			data->connect_failed_reason.code);
3653f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_AP */
3654f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		break;
36556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	case EVENT_NEW_PEER_CANDIDATE:
36566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH
36576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (!wpa_s->ifmsh || !data)
36586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			break;
36596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_mesh_notify_peer(wpa_s, data->mesh_peer.peer,
36606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				     data->mesh_peer.ies,
36616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				     data->mesh_peer.ie_len);
36626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */
36636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		break;
36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3669