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
74dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt/**
75dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt * wpas_reenabled_network_time - Time until first network is re-enabled
76dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
77dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt * Returns: If all enabled networks are temporarily disabled, returns the time
78dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt *	(in sec) until the first network is re-enabled. Otherwise returns 0.
79dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt *
80dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt * This function is used in case all enabled networks are temporarily disabled,
81dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt * in which case it returns the time (in sec) that the first network will be
82dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt * re-enabled. The function assumes that at least one network is enabled.
83dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt */
84dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidtstatic int wpas_reenabled_network_time(struct wpa_supplicant *wpa_s)
85dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt{
86dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	struct wpa_ssid *ssid;
87dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	int disabled_for, res = 0;
88dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
89dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt#ifdef CONFIG_INTERWORKING
90dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (wpa_s->conf->auto_interworking && wpa_s->conf->interworking &&
91dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	    wpa_s->conf->cred)
92dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		return 0;
93dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt#endif /* CONFIG_INTERWORKING */
94dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
95dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
96dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		if (ssid->disabled)
97dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			continue;
98dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
99dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		disabled_for = wpas_temp_disabled(wpa_s, ssid);
100dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		if (!disabled_for)
101dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			return 0;
102dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
103dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		if (!res || disabled_for < res)
104dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			res = disabled_for;
105dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	}
106dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
107dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	return res;
108dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt}
109dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
110dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
111dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidtvoid wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx)
112dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt{
113dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
114dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
115dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (wpa_s->disconnected || wpa_s->wpa_state != WPA_SCANNING)
116dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		return;
117dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
118dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG,
119dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		"Try to associate due to network getting re-enabled");
120dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (wpa_supplicant_fast_associate(wpa_s) != 1) {
121dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		wpa_supplicant_cancel_sched_scan(wpa_s);
122dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
123dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	}
124dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt}
125dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
126dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
127cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic struct wpa_bss * wpa_supplicant_get_new_bss(
128cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_supplicant *wpa_s, const u8 *bssid)
129cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
130cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_bss *bss = NULL;
131cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
132cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
133cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (ssid->ssid_len > 0)
134cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len);
135cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (!bss)
136cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		bss = wpa_bss_get_bssid(wpa_s, bssid);
137cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
138cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return bss;
139cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
140cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
141cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1425c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinenstatic void wpa_supplicant_update_current_bss(struct wpa_supplicant *wpa_s)
1435c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen{
1445c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, wpa_s->bssid);
1455c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
1465c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	if (!bss) {
1475c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		wpa_supplicant_update_scan_results(wpa_s);
1485c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
1495c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		/* Get the BSS from the new scan results */
1505c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		bss = wpa_supplicant_get_new_bss(wpa_s, wpa_s->bssid);
1515c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	}
1525c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
1535c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	if (bss)
1545c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		wpa_s->current_bss = bss;
1555c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen}
1565c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
1575c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid, *old_ssid;
1619d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt	u8 drv_ssid[SSID_MAX_LEN];
162dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	size_t drv_ssid_len;
16361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int res;
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1655c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid) {
1665c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen		wpa_supplicant_update_current_bss(wpa_s);
167dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
168dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		if (wpa_s->current_ssid->ssid_len == 0)
169dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			return 0; /* current profile still in use */
170dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		res = wpa_drv_get_ssid(wpa_s, drv_ssid);
171dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		if (res < 0) {
172dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			wpa_msg(wpa_s, MSG_INFO,
173dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt				"Failed to read SSID from driver");
174dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			return 0; /* try to use current profile */
175dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		}
176dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		drv_ssid_len = res;
177dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
178dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		if (drv_ssid_len == wpa_s->current_ssid->ssid_len &&
179dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		    os_memcmp(drv_ssid, wpa_s->current_ssid->ssid,
180dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			      drv_ssid_len) == 0)
181dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			return 0; /* current profile still in use */
182dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
183dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		wpa_msg(wpa_s, MSG_DEBUG,
184dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			"Driver-initiated BSS selection changed the SSID to %s",
185dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			wpa_ssid_txt(drv_ssid, drv_ssid_len));
186dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		/* continue selecting a new network profile */
1875c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	}
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Select network based on association "
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"information");
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_supplicant_get_ssid(wpa_s);
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO,
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"No network configuration found for the current AP");
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpas_network_disabled(wpa_s, ssid)) {
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is disabled");
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
203d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (disallowed_bssid(wpa_s, wpa_s->bssid) ||
204d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	    disallowed_ssid(wpa_s, ssid->ssid, ssid->ssid_len)) {
205d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS is disallowed");
206d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return -1;
207d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
208d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
20961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	res = wpas_temp_disabled(wpa_s, ssid);
21061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (res > 0) {
21161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is temporarily "
21261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			"disabled for %d second(s)", res);
21361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
21461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
21561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Network configuration found for the "
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"current AP");
2181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 wpa_ie[80];
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		size_t wpa_ie_len = sizeof(wpa_ie);
221a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
222a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt					      wpa_ie, &wpa_ie_len) < 0)
223a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Could not set WPA suites");
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid && wpa_s->current_ssid != ssid)
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_invalidate_cached_session(wpa_s->eapol);
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ssid = wpa_s->current_ssid;
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_ssid = ssid;
232cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
2335c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen	wpa_supplicant_update_current_bss(wpa_s);
234cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_initiate_eapol(wpa_s);
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ssid != wpa_s->current_ssid)
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_changed(wpa_s);
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx)
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->countermeasures) {
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->countermeasures = 0;
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_countermeasures(wpa_s, 0);
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped");
2527f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
2537f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		/*
2547f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * It is possible that the device is sched scanning, which means
2557f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * that a connection attempt will be done only when we receive
2567f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * scan results. However, in this case, it would be preferable
2577f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * to scan and connect immediately, so cancel the sched_scan and
2587f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * issue a regular scan flow.
2597f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 */
2607f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_supplicant_cancel_sched_scan(wpa_s);
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int bssid_changed;
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wnm_bss_keep_alive_deinit(wpa_s);
27104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ibss_rsn_deinit(wpa_s->ibss_rsn);
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ibss_rsn = NULL;
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
277c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt#ifdef CONFIG_AP
278c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	wpa_supplicant_ap_deinit(wpa_s);
279c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt#endif /* CONFIG_AP */
280c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(wpa_s->bssid, 0, ETH_ALEN);
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	sme_clear_on_disassoc(wpa_s);
289c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_P2P
290c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
291c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_P2P */
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_bss = NULL;
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->assoc_freq = 0;
294c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bssid_changed)
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_bssid_changed(wpa_s);
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ap_ies_from_associnfo = 0;
30361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->current_ssid = NULL;
304b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
30561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->key_mgmt = 0;
3066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
3076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpas_rrm_reset(wpa_s);
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ie_data ie;
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pmksa_set = -1;
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ie.pmkid == NULL)
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < ie.num_pmkid; i++) {
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pmksa_set = pmksa_cache_set_current(wpa_s->wpa,
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    ie.pmkid + i * PMKID_LEN,
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    NULL, NULL, 0);
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pmksa_set == 0) {
326216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID from assoc IE %sfound from "
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"PMKSA cache", pmksa_set == 0 ? "" : "not ");
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s,
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 union wpa_event_data *data)
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL) {
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: No data in PMKID candidate "
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"event");
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		" index=%d preauth=%d",
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(data->pmkid_candidate.bssid),
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		data->pmkid_candidate.index,
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		data->pmkid_candidate.preauth);
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid,
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->pmkid_candidate.index,
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->pmkid_candidate.preauth);
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid &&
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !(wpa_s->current_ssid->eapol_flags &
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	      (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) {
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* IEEE 802.1X, but not using dynamic WEP keys (i.e., either
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * plaintext or static WEP keys). */
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 1;
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_scard_init - Initialize SIM/USIM access with PC/SC
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: pointer to wpa_supplicant data
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: Configuration data for the network
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when starting authentication with a network that is
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured to use PC/SC for SIM/USIM access (EAP-SIM or EAP-AKA).
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      struct wpa_ssid *ssid)
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef PCSC_FUNCS
392391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	int aka = 0, sim = 0;
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
394df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	if ((ssid != NULL && ssid->eap.pcsc == NULL) ||
395df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	    wpa_s->scard != NULL || wpa_s->conf->external_sim)
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
398df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	if (ssid == NULL || ssid->eap.eap_methods == NULL) {
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sim = 1;
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		aka = 1;
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct eap_method_type *eap = ssid->eap.eap_methods;
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (eap->vendor != EAP_VENDOR_IETF ||
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       eap->method != EAP_TYPE_NONE) {
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (eap->vendor == EAP_VENDOR_IETF) {
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (eap->method == EAP_TYPE_SIM)
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					sim = 1;
40804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				else if (eap->method == EAP_TYPE_AKA ||
40904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 eap->method == EAP_TYPE_AKA_PRIME)
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					aka = 1;
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eap++;
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL)
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sim = 0;
41804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL &&
41904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME) ==
42004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    NULL)
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		aka = 0;
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!sim && !aka) {
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to "
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"use SIM, but neither EAP-SIM nor EAP-AKA are "
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"enabled");
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to use SIM "
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"(sim=%d aka=%d) - initialize PCSC", sim, aka);
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4332271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt	wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->scard == NULL) {
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "Failed to initialize SIM "
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"(pcsc-lite)");
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
4411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* PCSC_FUNCS */
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_SCAN_PROCESSING
449b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
450b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidtstatic int has_wep_key(struct wpa_ssid *ssid)
451b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt{
452b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	int i;
453b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
454b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
455b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		if (ssid->wep_key_len[i])
456b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			return 1;
457b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	}
458b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
459b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	return 0;
460b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt}
461b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
462b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
4639bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidtstatic int wpa_supplicant_match_privacy(struct wpa_bss *bss,
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					struct wpa_ssid *ssid)
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
466b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	int privacy = 0;
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mixed_cell)
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
476b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	if (has_wep_key(ssid))
477b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		privacy = 1;
478b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 EAPOL_FLAG_REQUIRE_KEY_BROADCAST))
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		privacy = 1;
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
48675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_key_mgmt_wpa(ssid->key_mgmt))
48775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		privacy = 1;
48875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
489f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if (ssid->key_mgmt & WPA_KEY_MGMT_OSEN)
490f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		privacy = 1;
491f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->caps & IEEE80211_CAP_PRIVACY)
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return privacy;
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return !privacy;
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_ssid *ssid,
5009bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt					 struct wpa_bss *bss)
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ie_data ie;
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int proto_match = 0;
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *rsn_ie, *wpa_ie;
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wep_ok;
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret >= 0)
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ret;
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Allow TSN if local configuration accepts WEP use without WPA/WPA2 */
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wep_ok = !wpa_key_mgmt_wpa(ssid->key_mgmt) &&
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		(((ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  ssid->wep_key_len[ssid->wep_tx_keyidx] > 0) ||
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA));
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5189bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		proto_match++;
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - parse "
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"failed");
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wep_ok &&
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on TSN "
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"in RSN IE");
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.proto & ssid->proto)) {
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - proto "
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - PTK "
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"cipher mismatch");
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.group_cipher & ssid->group_cipher)) {
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - GTK "
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"cipher mismatch");
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.key_mgmt & ssid->key_mgmt)) {
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - key mgmt "
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
562807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt		    wpas_get_ssid_pmf(wpa_s, ssid) ==
563d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		    MGMT_FRAME_PROTECTION_REQUIRED) {
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - no mgmt "
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"frame protection");
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on RSN IE");
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5749bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		proto_match++;
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_parse_wpa_ie(wpa_ie, 2 + wpa_ie[1], &ie)) {
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - parse "
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"failed");
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wep_ok &&
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on TSN "
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"in WPA IE");
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.proto & ssid->proto)) {
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - proto "
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - PTK "
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"cipher mismatch");
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.group_cipher & ssid->group_cipher)) {
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - GTK "
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"cipher mismatch");
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(ie.key_mgmt & ssid->key_mgmt)) {
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - key mgmt "
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on WPA IE");
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
62061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && !wpa_ie &&
62161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    !rsn_ie) {
62261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   allow for non-WPA IEEE 802.1X");
62361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return 1;
62461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
62561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((ssid->proto & (WPA_PROTO_WPA | WPA_PROTO_RSN)) &&
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_key_mgmt_wpa(ssid->key_mgmt) && proto_match == 0) {
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no WPA/RSN proto match");
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
632f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) &&
633f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE)) {
634f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   allow in OSEN");
635f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		return 1;
636f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	}
637f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_key_mgmt_wpa(ssid->key_mgmt)) {
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   allow in non-WPA/WPA2");
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "   reject due to mismatch with "
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"WPA/WPA2");
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int freq_allowed(int *freqs, int freq)
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freqs == NULL)
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; freqs[i]; i++)
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (freqs[i] == freq)
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6649bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidtstatic int rate_match(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
6651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
6661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	const struct hostapd_hw_modes *mode = NULL, *modes;
6671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	const u8 scan_ie[2] = { WLAN_EID_SUPP_RATES, WLAN_EID_EXT_SUPP_RATES };
6681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	const u8 *rate_ie;
6691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int i, j, k;
6701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (bss->freq == 0)
6721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 1; /* Cannot do matching without knowing band */
6731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	modes = wpa_s->hw.modes;
6751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (modes == NULL) {
6761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/*
6771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * The driver does not provide any additional information
6781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * about the utilized hardware, so allow the connection attempt
6791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * to continue.
6801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 */
6811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 1;
6821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
6831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; i < wpa_s->hw.num_modes; i++) {
6851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		for (j = 0; j < modes[i].num_channels; j++) {
6861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			int freq = modes[i].channels[j].freq;
6871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (freq == bss->freq) {
6881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				if (mode &&
6891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				    mode->mode == HOSTAPD_MODE_IEEE80211G)
6901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					break; /* do not allow 802.11b replace
6911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						* 802.11g */
6921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				mode = &modes[i];
6931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				break;
6941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
6951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
6961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
6971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (mode == NULL)
6991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
7001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; i < (int) sizeof(scan_ie); i++) {
7029bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		rate_ie = wpa_bss_get_ie(bss, scan_ie[i]);
7031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (rate_ie == NULL)
7041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
7051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		for (j = 2; j < rate_ie[1] + 2; j++) {
7071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			int flagged = !!(rate_ie[j] & 0x80);
7081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			int r = (rate_ie[j] & 0x7f) * 5;
7091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/*
7111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * IEEE Std 802.11n-2009 7.3.2.2:
7121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * The new BSS Membership selector value is encoded
7131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * like a legacy basic rate, but it is not a rate and
7141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * only indicates if the BSS members are required to
7151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * support the mandatory features of Clause 20 [HT PHY]
7161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * in order to join the BSS.
7171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 */
7181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (flagged && ((rate_ie[j] & 0x7f) ==
7191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					BSS_MEMBERSHIP_SELECTOR_HT_PHY)) {
7201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				if (!ht_supported(mode)) {
7211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					wpa_dbg(wpa_s, MSG_DEBUG,
7221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						"   hardware does not support "
7231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						"HT PHY");
7241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					return 0;
7251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				}
7261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				continue;
7271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
7281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
729c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			/* There's also a VHT selector for 802.11ac */
730c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			if (flagged && ((rate_ie[j] & 0x7f) ==
731c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					BSS_MEMBERSHIP_SELECTOR_VHT_PHY)) {
732c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				if (!vht_supported(mode)) {
733c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					wpa_dbg(wpa_s, MSG_DEBUG,
734c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt						"   hardware does not support "
735c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt						"VHT PHY");
736c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					return 0;
737c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				}
738c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				continue;
739c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			}
740c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
7411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (!flagged)
7421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				continue;
7431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/* check for legacy basic rates */
7451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			for (k = 0; k < mode->num_rates; k++) {
7461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				if (mode->rates[k] == r)
7471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					break;
7481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
7491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (k == mode->num_rates) {
7501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				/*
7511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 * IEEE Std 802.11-2007 7.3.2.2 demands that in
7521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 * order to join a BSS all required rates
7531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 * have to be supported by the hardware.
7541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 */
7554dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG,
7564dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt					"   hardware does not support required rate %d.%d Mbps (freq=%d mode==%d num_rates=%d)",
7574dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt					r / 10, r % 10,
7584dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt					bss->freq, mode->mode, mode->num_rates);
7591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				return 0;
7601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
7611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
7621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
7631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 1;
7651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
7661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
768f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt/*
769f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Test whether BSS is in an ESS.
770f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * This is done differently in DMG (60 GHz) and non-DMG bands
771f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */
772f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstatic int bss_is_ess(struct wpa_bss *bss)
773f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
774f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	if (bss_is_dmg(bss)) {
775f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		return (bss->caps & IEEE80211_CAP_DMG_MASK) ==
776f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			IEEE80211_CAP_DMG_AP;
777f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	}
778f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
779f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	return ((bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
780f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		IEEE80211_CAP_ESS);
781f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
782f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
783f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
784ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int match_mac_mask(const u8 *addr_a, const u8 *addr_b, const u8 *mask)
785ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{
786ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	size_t i;
787ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
788ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	for (i = 0; i < ETH_ALEN; i++) {
789ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if ((addr_a[i] & mask[i]) != (addr_b[i] & mask[i]))
790ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			return 0;
791ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	}
792ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	return 1;
793ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt}
794ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
795ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
796ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int addr_in_list(const u8 *addr, const u8 *list, size_t num)
797ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{
798ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	size_t i;
799ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
800ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	for (i = 0; i < num; i++) {
801ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		const u8 *a = list + i * ETH_ALEN * 2;
802ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		const u8 *m = a + ETH_ALEN;
803ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
804ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if (match_mac_mask(a, addr, m))
805ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			return 1;
806ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	}
807ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt	return 0;
808ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt}
809ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
810ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
8129bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt					    int i, struct wpa_bss *bss,
813f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt					    struct wpa_ssid *group,
814f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt					    int only_first_ssid)
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8169bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	u8 wpa_ie_len, rsn_ie_len;
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wpa;
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_blacklist *e;
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *ie;
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
821f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	int osen;
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8239bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_ie_len = ie ? ie[1] : 0;
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8269bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rsn_ie_len = ie ? ie[1] : 0;
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
829f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
830f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	osen = ie != NULL;
831f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
833f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		"wpa_ie_len=%u rsn_ie_len=%u caps=0x%x level=%d%s%s%s",
8349bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		i, MAC2STR(bss->bssid), wpa_ssid_txt(bss->ssid, bss->ssid_len),
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_ie_len, rsn_ie_len, bss->caps, bss->level,
8369657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE) ? " wps" : "",
8379657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		(wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) ||
8389657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		 wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) ?
839f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		" p2p" : "",
840f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		osen ? " osen=1" : "");
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	e = wpa_blacklist_get(wpa_s, bss->bssid);
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (e) {
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int limit = 1;
84504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_supplicant_enabled_networks(wpa_s) == 1) {
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * When only a single network is enabled, we can
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * trigger blacklisting on the first failure. This
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * should not be done with multiple enabled networks to
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * avoid getting forced to move into a worse ESS on
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * single error if there are no other BSSes of the
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * current ESS.
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			limit = 0;
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (e->count > limit) {
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - blacklisted "
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"(count=%d limit=%d)", e->count, limit);
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return NULL;
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8639bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (bss->ssid_len == 0) {
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID not known");
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
868d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (disallowed_bssid(wpa_s, bss->bssid)) {
869d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   skip - BSSID disallowed");
870d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return NULL;
871d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
872d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
873d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) {
874d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID disallowed");
875d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return NULL;
876d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
877d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa = wpa_ie_len > 0 || rsn_ie_len > 0;
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
880f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	for (ssid = group; ssid; ssid = only_first_ssid ? NULL : ssid->pnext) {
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int check_ssid = wpa ? 1 : (ssid->ssid_len != 0);
88261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		int res;
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
88404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpas_network_disabled(wpa_s, ssid)) {
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - disabled");
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
88961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		res = wpas_temp_disabled(wpa_s, ssid);
89061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (res > 0) {
89161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - disabled "
89261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				"temporarily for %d second(s)", res);
89361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			continue;
89461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
89561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && e && e->count > 0) {
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - blacklisted "
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"(WPS)");
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa && ssid->ssid_len == 0 &&
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			check_ssid = 0;
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Only allow wildcard SSID match if an AP
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * advertises active WPS operation that matches
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * with our mode. */
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			check_ssid = 1;
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ssid->ssid_len == 0 &&
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				check_ssid = 0;
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (ssid->bssid_set && ssid->ssid_len == 0 &&
9191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) == 0)
9201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			check_ssid = 0;
9211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (check_ssid &&
9239bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		    (bss->ssid_len != ssid->ssid_len ||
9249bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		     os_memcmp(bss->ssid, ssid->ssid, bss->ssid_len) != 0)) {
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID mismatch");
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->bssid_set &&
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) {
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - BSSID mismatch");
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
935ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		/* check blacklist */
936ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if (ssid->num_bssid_blacklist &&
937ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		    addr_in_list(bss->bssid, ssid->bssid_blacklist,
938ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				 ssid->num_bssid_blacklist)) {
939ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
940ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				"   skip - BSSID blacklisted");
941ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			continue;
942ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		}
943ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
944ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		/* if there is a whitelist, only accept those APs */
945ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		if (ssid->num_bssid_whitelist &&
946ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		    !addr_in_list(bss->bssid, ssid->bssid_whitelist,
947ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				  ssid->num_bssid_whitelist)) {
948ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
949ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				"   skip - BSSID not in whitelist");
950ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			continue;
951ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt		}
952ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
956f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		if (!osen && !wpa &&
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) {
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - non-WPA network "
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"not allowed");
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
965b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		if (wpa && !wpa_key_mgmt_wpa(ssid->key_mgmt) &&
966b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		    has_wep_key(ssid)) {
967b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - ignore WPA/WPA2 AP for WEP network block");
968b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			continue;
969b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		}
970b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt
971f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) && !osen) {
972f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - non-OSEN network "
973f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt				"not allowed");
974f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			continue;
975f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		}
976f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
97775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_supplicant_match_privacy(bss, ssid)) {
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - privacy "
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mismatch");
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
983f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		if (!bss_is_ess(bss)) {
984f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - not ESS network");
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!freq_allowed(ssid->freq_list, bss->freq)) {
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - frequency not "
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"allowed");
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!rate_match(wpa_s, bss)) {
9951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - rate sets do "
9961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				"not match");
9971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
9981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
9991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
10019657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		if (ssid->p2p_group &&
10029657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		    !wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
10039657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		    !wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
10049657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no P2P IE seen");
10059657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt			continue;
10069657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt		}
10079657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt
10085460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt		if (!is_zero_ether_addr(ssid->go_p2p_dev_addr)) {
10095460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			struct wpabuf *p2p_ie;
10105460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			u8 dev_addr[ETH_ALEN];
10115460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
10125460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			ie = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
10135460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			if (ie == NULL) {
10145460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no P2P element");
10155460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				continue;
10165460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			}
10175460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			p2p_ie = wpa_bss_get_vendor_ie_multi(
10185460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				bss, P2P_IE_VENDOR_TYPE);
10195460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			if (p2p_ie == NULL) {
10205460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "   skip - could not fetch P2P element");
10215460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				continue;
10225460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			}
10235460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
10245460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			if (p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr) < 0
10255460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			    || os_memcmp(dev_addr, ssid->go_p2p_dev_addr,
10265460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt					 ETH_ALEN) != 0) {
10275460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no matching GO P2P Device Address in P2P element");
10285460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				wpabuf_free(p2p_ie);
10295460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				continue;
10305460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			}
10315460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			wpabuf_free(p2p_ie);
10325460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt		}
10335460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * TODO: skip the AP if its P2P IE has Group Formation
10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * bit set in the P2P Group Capability Bitmap and we
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * are not in Group Formation with that device.
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Matching configuration found */
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ssid;
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* No matching configuration found */
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_bss *
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  struct wpa_ssid *group,
1053f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			  struct wpa_ssid **selected_ssid,
1054f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			  int only_first_ssid)
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10569bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	unsigned int i;
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1058f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if (only_first_ssid)
1059f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Try to find BSS matching pre-selected network id=%d",
1060f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			group->id);
1061f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	else
1062f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d",
1063f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			group->priority);
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10659bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	for (i = 0; i < wpa_s->last_scan_res_used; i++) {
10669bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		struct wpa_bss *bss = wpa_s->last_scan_res[i];
1067f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		*selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group,
1068f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt						    only_first_ssid);
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!*selected_ssid)
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "   selected BSS " MACSTR
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" ssid='%s'",
10739bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt			MAC2STR(bss->bssid),
10749bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt			wpa_ssid_txt(bss->ssid, bss->ssid_len));
10759bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		return bss;
10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1082444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtstruct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
1083444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt					     struct wpa_ssid **selected_ssid)
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *selected = NULL;
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int prio;
10874582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt	struct wpa_ssid *next_ssid = NULL;
1088912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt	struct wpa_ssid *ssid;
10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10909bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (wpa_s->last_scan_res == NULL ||
10919bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	    wpa_s->last_scan_res_used == 0)
10929bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		return NULL; /* no scan results from last update */
10939bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
10944582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt	if (wpa_s->next_ssid) {
10954582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		/* check that next_ssid is still valid */
10964582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
10974582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt			if (ssid == wpa_s->next_ssid)
10984582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt				break;
10994582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		}
11004582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		next_ssid = ssid;
11014582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		wpa_s->next_ssid = NULL;
11024582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt	}
1103f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
11044582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt	while (selected == NULL) {
11054582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt		for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
11064582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt			if (next_ssid && next_ssid->priority ==
11074582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt			    wpa_s->conf->pssid[prio]->priority) {
1108f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt				selected = wpa_supplicant_select_bss(
11094582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt					wpa_s, next_ssid, selected_ssid, 1);
1110f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt				if (selected)
1111f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt					break;
1112f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			}
11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			selected = wpa_supplicant_select_bss(
11149bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt				wpa_s, wpa_s->conf->pssid[prio],
1115f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt				selected_ssid, 0);
11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (selected)
11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (selected == NULL && wpa_s->blacklist &&
11211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    !wpa_s->countermeasures) {
11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "No APs found - clear "
11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"blacklist and try again");
11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_blacklist_clear(wpa_s);
11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->blacklist_cleared++;
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (selected == NULL)
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1130912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt	ssid = *selected_ssid;
1131912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt	if (selected && ssid && ssid->mem_only_psk && !ssid->psk_set &&
1132912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt	    !ssid->passphrase && !ssid->ext_psk) {
1133912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt		const char *field_name, *txt = NULL;
1134912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt
1135912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
1136912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			"PSK/passphrase not yet available for the selected network");
1137912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt
1138912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt		wpas_notify_network_request(wpa_s, ssid,
1139912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt					    WPA_CTRL_REQ_PSK_PASSPHRASE, NULL);
1140912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt
1141912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt		field_name = wpa_supplicant_ctrl_req_to_string(
1142912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			WPA_CTRL_REQ_PSK_PASSPHRASE, NULL, &txt);
1143912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt		if (field_name == NULL)
1144912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt			return NULL;
1145912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt
1146912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt		wpas_send_ctrl_req(wpa_s, ssid, field_name, txt);
1147912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt
1148912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt		selected = NULL;
1149912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt	}
1150912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt
11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return selected;
11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					int timeout_sec, int timeout_usec)
11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
115804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_supplicant_enabled_networks(wpa_s)) {
11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * No networks are enabled; short-circuit request so
11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * we don't wait timeout seconds before transitioning
11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * to INACTIVE state.
11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
1164aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Short-circuit new scan request "
1165aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt			"since there are no enabled networks");
11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1169d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
1170d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->scan_for_connection = 1;
11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
117544da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidtint wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
11761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   struct wpa_bss *selected,
11771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   struct wpa_ssid *ssid)
11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"PBC session overlap");
11827a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt		wpas_notify_wps_event_pbc_overlap(wpa_s);
11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
1184df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt		if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
1185df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt		    wpa_s->p2p_in_provisioning) {
1186df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt			eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb,
1187df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt					       wpa_s, NULL);
118844da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt			return -1;
1189df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt		}
11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_wps_cancel(wpa_s);
11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
119544da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt		return -1;
11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1198f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG,
1199f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		"Considering connect request: reassociate: %d  selected: "
1200f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		MACSTR "  bssid: " MACSTR "  pending: " MACSTR
1201f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		"  wpa_state: %s  ssid=%p  current_ssid=%p",
1202f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		wpa_s->reassociate, MAC2STR(selected->bssid),
1203f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1204f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		wpa_supplicant_state_txt(wpa_s->wpa_state),
1205f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		ssid, wpa_s->current_ssid);
1206f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt
12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Do not trigger new association unless the BSSID has changed or if
12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * reassociation is requested. If we are in process of associating with
12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * the selected BSSID, do not trigger new attempt.
12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
12121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->reassociate ||
12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     ((wpa_s->wpa_state != WPA_ASSOCIATING &&
12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       wpa_s->wpa_state != WPA_AUTHENTICATING) ||
1216f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	      (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1217f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	       os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) !=
1218f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	       0) ||
1219f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	      (is_zero_ether_addr(wpa_s->pending_bssid) &&
1220f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt	       ssid != wpa_s->current_ssid)))) {
12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_scard_init(wpa_s, ssid)) {
12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_req_new_scan(wpa_s, 10, 0);
122344da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt			return 0;
12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1225f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		wpa_msg(wpa_s, MSG_DEBUG, "Request association with " MACSTR,
1226f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			MAC2STR(selected->bssid));
12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_associate(wpa_s, selected, ssid);
12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
1229f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Already associated or trying to "
1230f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt			"connect with the selected AP");
12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
123344da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt	return 0;
12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_ssid *
12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int prio;
12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (ssid = wpa_s->conf->pssid[prio]; ssid; ssid = ssid->pnext)
12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
124604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (wpas_network_disabled(wpa_s, ssid))
12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue;
12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ssid->mode == IEEE80211_MODE_IBSS ||
12496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			    ssid->mode == IEEE80211_MODE_AP ||
12506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			    ssid->mode == IEEE80211_MODE_MESH)
12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return ssid;
12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based
12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * on BSS added and BSS changed events */
12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_rsn_preauth_scan_results(
126187fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	struct wpa_supplicant *wpa_s)
12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
126387fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	struct wpa_bss *bss;
12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
126887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *ssid, *rsn;
12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
127187fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		ssid = wpa_bss_get_ie(bss, WLAN_EID_SSID);
12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid == NULL)
12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
127587fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (rsn == NULL)
12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
127987fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		rsn_preauth_scan_result(wpa_s->wpa, bss->bssid, ssid, rsn);
12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       struct wpa_bss *selected,
12879bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt				       struct wpa_ssid *ssid)
12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12899bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	struct wpa_bss *current_bss = NULL;
1290912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt#ifndef CONFIG_NO_ROAMING
12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int min_diff;
1292912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt#endif /* CONFIG_NO_ROAMING */
12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->reassociate)
12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* explicit request to reassociate */
12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state < WPA_ASSOCIATED)
12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* we are not associated; continue */
12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid == NULL)
12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* unknown current SSID */
13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid != ssid)
13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* different network block */
13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpas_driver_bss_selection(wpa_s))
13041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0; /* Driver-based roaming */
13051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
13069bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (wpa_s->current_ssid->ssid)
13079bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		current_bss = wpa_bss_get(wpa_s, wpa_s->bssid,
13089bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt					  wpa_s->current_ssid->ssid,
13099bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt					  wpa_s->current_ssid->ssid_len);
13109bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (!current_bss)
13119bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		current_bss = wpa_bss_get_bssid(wpa_s, wpa_s->bssid);
13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!current_bss)
13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1; /* current BSS not seen in scan results */
13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13169bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (current_bss == selected)
13179bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		return 0;
13189bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
13199bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	if (selected->last_update_idx > current_bss->last_update_idx)
13209bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		return 1; /* current BSS not seen in the last scan */
13219bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
13229e07767d5d76159ef38a241da00eb0d9f3bc6420Dmitry Shmidt#ifndef CONFIG_NO_ROAMING
13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Considering within-ESS reassociation");
13247f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Current BSS: " MACSTR
13257f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		" level=%d snr=%d est_throughput=%u",
13267f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		MAC2STR(current_bss->bssid), current_bss->level,
13277f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		current_bss->snr, current_bss->est_throughput);
13287f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS: " MACSTR
13297f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		" level=%d snr=%d est_throughput=%u",
13307f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		MAC2STR(selected->bssid), selected->level,
13317f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		selected->snr, selected->est_throughput);
13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid->bssid_set &&
13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    os_memcmp(selected->bssid, wpa_s->current_ssid->bssid, ETH_ALEN) ==
13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    0) {
13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Allow reassociation - selected BSS "
13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"has preferred BSSID");
13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13417f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	if (selected->est_throughput > current_bss->est_throughput + 5000) {
13427f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
13437f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			"Allow reassociation - selected BSS has better estimated throughput");
13447f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		return 1;
13457f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	}
13467f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
1347d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (current_bss->level < 0 && current_bss->level > selected->level) {
1348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
1349d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			"signal level");
1350d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return 0;
1351d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
1352d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	min_diff = 2;
13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (current_bss->level < 0) {
13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (current_bss->level < -85)
13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 1;
13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (current_bss->level < -80)
13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 2;
13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (current_bss->level < -75)
13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 3;
13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (current_bss->level < -70)
13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 4;
13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			min_diff = 5;
13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (abs(current_bss->level - selected->level) < min_diff) {
13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - too small difference "
13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"in signal level");
13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 1;
137304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#else /* CONFIG_NO_ROAMING */
1374efdec2efdda2f534d84b32f2737ca3d8a00fdf02Dmitry Shmidt	return 0;
137504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_NO_ROAMING */
13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1378c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
137989ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen/* Return != 0 if no scan results could be fetched or if scan results should not
138004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * be shared with other virtual interfaces. */
1381f6c92c4dd33d21c040e51bcb30beac24173a62b9Dmitry Shmidtstatic int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
138237d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt					      union wpa_event_data *data,
138337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt					      int own_request)
13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1385fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct wpa_scan_results *scan_res = NULL;
1386fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int ret = 0;
13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ap = 0;
13884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifndef CONFIG_NO_RANDOM_POOL
13894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt	size_t i, num;
13904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_NO_RANDOM_POOL */
13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface)
13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ap = 1;
13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_notify_scanning(wpa_s, 0);
13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	scan_res = wpa_supplicant_get_scan_results(wpa_s,
14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   data ? &data->scan_info :
14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   NULL, 1);
14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (scan_res == NULL) {
14034b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		if (wpa_s->conf->ap_scan == 2 || ap ||
14044b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		    wpa_s->scan_res_handler == scan_only_handler)
14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
140637d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt		if (!own_request)
140737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt			return -1;
14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results - try "
14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"scanning again");
14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_new_scan(wpa_s, 1, 0);
1411fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		ret = -1;
1412fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RANDOM_POOL
14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	num = scan_res->num;
14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (num > 10)
14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		num = 10;
14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < num; i++) {
14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 buf[5];
14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_scan_res *res = scan_res->res[i];
14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[0] = res->bssid[5];
14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[1] = res->qual & 0xff;
14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[2] = res->noise & 0xff;
14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[3] = res->level & 0xff;
14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		buf[4] = res->tsf & 0xff;
14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		random_add_randomness(buf, sizeof(buf));
14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RANDOM_POOL */
14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1431fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (own_request && wpa_s->scan_res_handler &&
14322f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt	    (wpa_s->own_scan_running || !wpa_s->radio->external_scan_running)) {
14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_scan_results *scan_res);
14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		scan_res_handler = wpa_s->scan_res_handler;
14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->scan_res_handler = NULL;
14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		scan_res_handler(wpa_s, scan_res);
1439fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		ret = -2;
1440fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ap) {
14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Ignore scan results in AP mode");
14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface->scan_cb)
14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->ap_iface->scan_cb(wpa_s->ap_iface);
14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
1449fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
145137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt
1452fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "New scan results available (own=%u ext=%u)",
14532f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt		wpa_s->own_scan_running, wpa_s->radio->external_scan_running);
1454fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
1455fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    wpa_s->manual_scan_use_id && wpa_s->own_scan_running) {
1456fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u",
1457fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			     wpa_s->manual_scan_id);
1458fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->manual_scan_use_id = 0;
1459fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	} else {
1460fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
1461fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
146204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpas_notify_scan_results(wpa_s);
14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_scan_done(wpa_s, 1);
14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt	if (!wpa_s->own_scan_running && wpa_s->radio->external_scan_running) {
1467fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Do not use results from externally requested scan operation for network selection");
146804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_scan_results_free(scan_res);
146904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
147004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
147104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
14726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wnm_scan_process(wpa_s, 1) > 0)
14736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		goto scan_work_done;
14746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
1475fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (sme_proc_obss_scan(wpa_s) > 0)
1476fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1478fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)))
1479fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
1480fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1481fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (autoscan_notify_scan(wpa_s, scan_res))
1482fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
148304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->disconnected) {
14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1486fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpas_driver_bss_selection(wpa_s) &&
1490fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    bgscan_notify_scan(wpa_s, scan_res) == 1)
1491fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		goto scan_work_done;
14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
149361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpas_wps_update_ap_info(wpa_s, scan_res);
149461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
14959bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	wpa_scan_results_free(scan_res);
14969bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
1497fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->scan_work) {
1498fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct wpa_radio_work *work = wpa_s->scan_work;
1499fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->scan_work = NULL;
1500fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_done(work);
1501fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1502fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1503e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	return wpas_select_network_from_last_scan(wpa_s, 1, own_request);
1504fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
1505fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtscan_work_done:
1506fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_scan_results_free(scan_res);
1507fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (wpa_s->scan_work) {
1508fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct wpa_radio_work *work = wpa_s->scan_work;
1509fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->scan_work = NULL;
1510fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_done(work);
1511fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
1512fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return ret;
15139bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt}
15149bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
15159bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
15168da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidtstatic int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
1517e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt					      int new_scan, int own_request)
15189bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt{
15199bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	struct wpa_bss *selected;
15209bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	struct wpa_ssid *ssid = NULL;
1521dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	int time_to_reenable = wpas_reenabled_network_time(wpa_s);
1522dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
1523dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (time_to_reenable > 0) {
1524dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
1525dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			"Postpone network selection by %d seconds since all networks are disabled",
1526dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			time_to_reenable);
1527dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
1528dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		eloop_register_timeout(time_to_reenable, 0,
1529dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt				       wpas_network_reenabled, wpa_s, NULL);
1530dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		return 0;
1531dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	}
15329bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
1533203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	if (wpa_s->p2p_mgmt)
1534203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		return 0; /* no normal connection on p2p_mgmt interface */
1535203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt
15369bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	selected = wpa_supplicant_pick_network(wpa_s, &ssid);
15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (selected) {
15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int skip;
15409bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt		skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid);
15411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (skip) {
15428da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt			if (new_scan)
15438da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt				wpa_supplicant_rsn_preauth_scan_results(wpa_s);
15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
15451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
15461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
154744da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt		if (wpa_supplicant_connect(wpa_s, selected, ssid) < 0) {
15481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Connect failed");
154944da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt			return -1;
155044da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt		}
15518da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt		if (new_scan)
15528da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt			wpa_supplicant_rsn_preauth_scan_results(wpa_s);
155389ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		/*
155489ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * Do not notify other virtual radios of scan results since we do not
155589ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * want them to start other associations at the same time.
155689ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 */
155789ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		return 1;
15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
15596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH
15606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (wpa_s->ifmsh) {
15616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_msg(wpa_s, MSG_INFO,
15626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				"Avoiding join because we already joined a mesh group");
15636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			return 0;
15646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		}
15656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */
15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "No suitable network found");
15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = wpa_supplicant_pick_new_network(wpa_s);
15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid) {
15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Setup a new network");
15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_associate(wpa_s, NULL, ssid);
15718da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt			if (new_scan)
15728da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt				wpa_supplicant_rsn_preauth_scan_results(wpa_s);
1573e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt		} else if (own_request) {
1574e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			/*
1575e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			 * No SSID found. If SCAN results are as a result of
1576e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			 * own scan request and not due to a scan request on
1577e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			 * another shared interface, try another scan.
1578e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			 */
15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int timeout_sec = wpa_s->scan_interval;
15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int timeout_usec = 0;
15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
15827f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			int res;
15837f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
15847f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			res = wpas_p2p_scan_no_go_seen(wpa_s);
15857f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			if (res == 2)
15867f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt				return 2;
15877f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			if (res == 1)
158804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return 0;
158904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1590fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			if (wpa_s->p2p_in_provisioning ||
159115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt			    wpa_s->show_group_started ||
159215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt			    wpa_s->p2p_in_invitation) {
15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				/*
15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 * Use shorter wait during P2P Provisioning
1595fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt				 * state and during P2P join-a-group operation
1596fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt				 * to speed up group formation.
15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 */
15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				timeout_sec = 0;
15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				timeout_usec = 250000;
16001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
16011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							    timeout_usec);
16021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				return 0;
16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
160561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_INTERWORKING
160661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (wpa_s->conf->auto_interworking &&
160761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    wpa_s->conf->interworking &&
160861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    wpa_s->conf->cred) {
160961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: "
161061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"start ANQP fetch since no matching "
161161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"networks found");
161261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_s->network_select = 1;
161361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_s->auto_network_select = 1;
161461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				interworking_start_fetch_anqp(wpa_s);
161589ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen				return 1;
161661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
161761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
1618fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_WPS
1619fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			if (wpa_s->after_wps > 0 || wpas_wps_searching(wpa_s)) {
1620fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				wpa_dbg(wpa_s, MSG_DEBUG, "Use shorter wait during WPS processing");
1621fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				timeout_sec = 0;
1622fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				timeout_usec = 500000;
1623fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
1624fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt							    timeout_usec);
1625fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				return 0;
1626fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			}
1627fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_WPS */
16281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (wpa_supplicant_req_sched_scan(wpa_s))
16291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
16301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							    timeout_usec);
16314171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt
16324171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt			wpa_msg_ctrl(wpa_s, MSG_INFO,
16334171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt				     WPA_EVENT_NETWORK_NOT_FOUND);
16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16407f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidtstatic int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
16417f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt					     union wpa_event_data *data)
16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *ifs;
16447f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	int res;
164537d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt
16467f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	res = _wpa_supplicant_event_scan_results(wpa_s, data, 1);
16477f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	if (res == 2) {
16487f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		/*
16497f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * Interface may have been removed, so must not dereference
16507f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 * wpa_s after this.
16517f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		 */
16527f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		return 1;
16537f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	}
16547f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	if (res != 0) {
16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * If no scan results could be fetched, then no need to
16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * notify those interfaces that did not actually request
165889ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * this scan. Similarly, if scan results started a new operation on this
165989ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * interface, do not notify other interfaces to avoid concurrent
166089ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen		 * operations during a connection attempt.
16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
16627f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		return 0;
16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
166601904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt	 * Check other interfaces to see if they share the same radio. If
16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * so, they get updated with this same scan info.
16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
166901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
167001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 radio_list) {
167101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		if (ifs != wpa_s) {
16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "%s: Updating scan results from "
16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "sibling", ifs->ifname);
167437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt			_wpa_supplicant_event_scan_results(ifs, data, 0);
16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16777f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt
16787f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	return 0;
16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16844b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidtint wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s)
16854b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt{
16864b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt#ifdef CONFIG_NO_SCAN_PROCESSING
16874b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	return -1;
16884b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt#else /* CONFIG_NO_SCAN_PROCESSING */
1689fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct os_reltime now;
16904b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
16914171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt	if (wpa_s->last_scan_res_used == 0)
16924b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		return -1;
16934b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
1694fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_get_reltime(&now);
1695fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (os_reltime_expired(&now, &wpa_s->last_scan, 5)) {
16964b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		wpa_printf(MSG_DEBUG, "Fast associate: Old scan results");
16974b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		return -1;
16984b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	}
16994b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
1700e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	return wpas_select_network_from_last_scan(wpa_s, 0, 1);
17014b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
17024b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt}
17034b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
170404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WNM
170504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
170604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wnm_bss_keep_alive(void *eloop_ctx, void *sock_ctx)
170704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
170804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
170904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
171004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->wpa_state < WPA_ASSOCIATED)
171104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
171204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1713a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (!wpa_s->no_keep_alive) {
1714a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		wpa_printf(MSG_DEBUG, "WNM: Send keep-alive to AP " MACSTR,
1715a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			   MAC2STR(wpa_s->bssid));
1716a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* TODO: could skip this if normal data traffic has been sent */
1717a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* TODO: Consider using some more appropriate data frame for
1718a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		 * this */
1719a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (wpa_s->l2)
1720a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			l2_packet_send(wpa_s->l2, wpa_s->bssid, 0x0800,
1721a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt				       (u8 *) "", 0);
1722a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
172304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
172404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_SME
172504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->sme.bss_max_idle_period) {
172604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		unsigned int msec;
172704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		msec = wpa_s->sme.bss_max_idle_period * 1024; /* times 1000 */
172804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (msec > 100)
172904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			msec -= 100;
173004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eloop_register_timeout(msec / 1000, msec % 1000 * 1000,
173104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				       wnm_bss_keep_alive, wpa_s, NULL);
173204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
173304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_SME */
173404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
173504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
173604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
173704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wnm_process_assoc_resp(struct wpa_supplicant *wpa_s,
173804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   const u8 *ies, size_t ies_len)
173904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
174004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct ieee802_11_elems elems;
174104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
174204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ies == NULL)
174304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
174404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
174504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
174604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
174704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
174804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_SME
174904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (elems.bss_max_idle_period) {
175004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		unsigned int msec;
175104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->sme.bss_max_idle_period =
175204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			WPA_GET_LE16(elems.bss_max_idle_period);
175304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "WNM: BSS Max Idle Period: %u (* 1000 "
175404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "TU)%s", wpa_s->sme.bss_max_idle_period,
175504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   (elems.bss_max_idle_period[2] & 0x01) ?
175604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   " (protected keep-live required)" : "");
175704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->sme.bss_max_idle_period == 0)
175804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->sme.bss_max_idle_period = 1;
175904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
176004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL);
176104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			 /* msec times 1000 */
176204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			msec = wpa_s->sme.bss_max_idle_period * 1024;
176304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (msec > 100)
176404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				msec -= 100;
176504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			eloop_register_timeout(msec / 1000, msec % 1000 * 1000,
176604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       wnm_bss_keep_alive, wpa_s,
176704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       NULL);
176804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
176904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
177004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_SME */
177104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
177204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
177304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WNM */
177404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
177504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
177604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s)
177704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
177804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WNM
177904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL);
178004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WNM */
178104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
178204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
178304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1784051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef CONFIG_INTERWORKING
1785051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1786051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtstatic int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map,
1787051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			    size_t len)
1788051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
1789051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	int res;
1790051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1791051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	wpa_hexdump(MSG_DEBUG, "Interworking: QoS Map Set", qos_map, len);
1792051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	res = wpa_drv_set_qos_map(wpa_s, qos_map, len);
1793051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (res) {
1794051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Interworking: Failed to configure QoS Map Set to the driver");
1795051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	}
1796051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1797051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	return res;
1798051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
1799051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1800051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1801051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtstatic void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s,
1802051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt					    const u8 *ies, size_t ies_len)
1803051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
1804051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	struct ieee802_11_elems elems;
1805051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1806051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (ies == NULL)
1807051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return;
1808051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1809051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
1810051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return;
1811051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1812051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (elems.qos_map_set) {
1813051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		wpas_qos_map_set(wpa_s, elems.qos_map_set,
1814051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				 elems.qos_map_set_len);
1815051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	}
1816051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
1817051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1818051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
1819051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
1820051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  union wpa_event_data *data)
18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int l, len, found = 0, wpa_found, rsn_found;
18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *p;
1826700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#ifdef CONFIG_IEEE80211R
1827700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	u8 bssid[ETH_ALEN];
1828700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data->assoc_info.req_ies)
18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->assoc_info.req_ies_len);
18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data->assoc_info.resp_ies) {
18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies,
18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->assoc_info.resp_ies_len);
18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_tdls_assoc_resp_ies(wpa_s->wpa, data->assoc_info.resp_ies,
18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->assoc_info.resp_ies_len);
18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
184104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WNM
184204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
184304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				       data->assoc_info.resp_ies_len);
184404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WNM */
1845051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef CONFIG_INTERWORKING
1846051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
1847051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt						data->assoc_info.resp_ies_len);
1848051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data->assoc_info.beacon_ies)
18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_DEBUG, "beacon_ies",
18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->assoc_info.beacon_ies,
18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->assoc_info.beacon_ies_len);
18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data->assoc_info.freq)
18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "freq=%u MHz",
18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->assoc_info.freq);
18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p = data->assoc_info.req_ies;
18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l = data->assoc_info.req_ies_len;
18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Go through the IEs and make a copy of the WPA/RSN IE, if present. */
18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (p && l >= 2) {
18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = p[1] + 2;
18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len > l) {
18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    p, l);
18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((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		    (p[0] == WLAN_EID_RSN && p[1] >= 2)) {
18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			found = 1;
18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_find_assoc_pmkid(wpa_s);
18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l -= len;
18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p += len;
18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!found && data->assoc_info.req_ies)
18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SME
18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpa_ft_validate_reassoc_resp(wpa_s->wpa,
18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 data->assoc_info.resp_ies,
18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 data->assoc_info.resp_ies_len,
18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 bssid) < 0) {
18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of "
18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"Reassociation Response failed");
18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_deauthenticate(
18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_INVALID_IE);
18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p = data->assoc_info.resp_ies;
19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l = data->assoc_info.resp_ies_len;
19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS_STRICT
19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p && wpa_s->current_ssid &&
19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpabuf *wps;
19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wps = ieee802_11_vendor_ie_concat(p, l, WPS_IE_VENDOR_TYPE);
19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps == NULL) {
19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "WPS-STRICT: AP did not "
19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"include WPS IE in (Re)Association Response");
19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps_validate_assoc_resp(wps) < 0) {
19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpabuf_free(wps);
19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_deauthenticate(
19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_INVALID_IE);
19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wps);
19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS_STRICT */
19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Go through the IEs and make a copy of the MDIE, if present. */
19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (p && l >= 2) {
19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = p[1] + 2;
19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len > l) {
19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    p, l);
19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p[0] == WLAN_EID_MOBILITY_DOMAIN &&
19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    p[1] >= MOBILITY_DOMAIN_ID_LEN) {
19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->sme.ft_used = 1;
19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_s->sme.mobility_domain, p + 2,
19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  MOBILITY_DOMAIN_ID_LEN);
19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l -= len;
19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p += len;
19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SME */
19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1944700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	/* Process FT when SME is in the driver */
1945700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1946700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	    wpa_ft_is_completed(wpa_s->wpa)) {
1947700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
1948700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		    wpa_ft_validate_reassoc_resp(wpa_s->wpa,
1949700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt						 data->assoc_info.resp_ies,
1950700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt						 data->assoc_info.resp_ies_len,
1951700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt						 bssid) < 0) {
1952700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of "
1953700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				"Reassociation Response failed");
1954700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			wpa_supplicant_deauthenticate(
1955700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt				wpa_s, WLAN_REASON_INVALID_IE);
1956700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt			return -1;
1957700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		}
1958700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done");
1959700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	}
1960700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt
19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     data->assoc_info.resp_ies_len);
19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* WPA/RSN IE from Beacon/ProbeResp */
19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p = data->assoc_info.beacon_ies;
19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l = data->assoc_info.beacon_ies_len;
19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Go through the IEs and make a copy of the WPA/RSN IEs, if present.
19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_found = rsn_found = 0;
19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (p && l >= 2) {
19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = p[1] + 2;
19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len > l) {
19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_hexdump(MSG_DEBUG, "Truncated IE in beacon_ies",
19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    p, l);
19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_found &&
19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_found = 1;
19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len);
19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!rsn_found &&
19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    p[0] == WLAN_EID_RSN && p[1] >= 2) {
19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			rsn_found = 1;
19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l -= len;
19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p += len;
19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_found && data->assoc_info.beacon_ies)
19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!rsn_found && data->assoc_info.beacon_ies)
19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_found || rsn_found)
20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ap_ies_from_associnfo = 1;
20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
200387fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	if (wpa_s->assoc_freq && data->assoc_info.freq &&
200487fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	    wpa_s->assoc_freq != data->assoc_info.freq) {
200587fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		wpa_printf(MSG_DEBUG, "Operating frequency changed from "
200687fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen			   "%u to %u MHz",
200787fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen			   wpa_s->assoc_freq, data->assoc_info.freq);
200887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		wpa_supplicant_update_scan_results(wpa_s);
200987fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen	}
201087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen
20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->assoc_freq = data->assoc_info.freq;
20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2017c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s)
2018c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2019c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const u8 *bss_wpa = NULL, *bss_rsn = NULL;
2020c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2021c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpa_s->current_bss || !wpa_s->current_ssid)
2022c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return -1;
2023c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2024c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpa_key_mgmt_wpa_any(wpa_s->current_ssid->key_mgmt))
2025c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
2026c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2027c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	bss_wpa = wpa_bss_get_vendor_ie(wpa_s->current_bss,
2028c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					WPA_IE_VENDOR_TYPE);
2029c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	bss_rsn = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSN);
2030c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2031c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
2032c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 bss_wpa ? 2 + bss_wpa[1] : 0) ||
2033c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	    wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
2034c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 bss_rsn ? 2 + bss_rsn[1] : 0))
2035c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return -1;
2036c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2037c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2038c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2039c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2040c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       union wpa_event_data *data)
20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN];
20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ft_completed;
20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface) {
204909f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt		if (!data)
205009f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt			return;
20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hostapd_notif_assoc(wpa_s->ap_iface->bss[0],
20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->assoc_info.addr,
20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->assoc_info.req_ies,
20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->assoc_info.req_ies_len,
20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->assoc_info.reassoc);
20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2060dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
2061dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ft_completed = wpa_ft_is_completed(wpa_s->wpa);
20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0)
20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
206661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
206761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_dbg(wpa_s, MSG_ERROR, "Failed to get BSSID");
2068d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_supplicant_deauthenticate(
206961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
207061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
207161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
207261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
207461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MACSTR, MAC2STR(bssid));
20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		random_add_randomness(bssid, ETH_ALEN);
20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
208061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_notify_bssid_changed(wpa_s);
20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) {
20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_clear_keys(wpa_s, bssid);
20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_select_config(wpa_s) < 0) {
2086d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			wpa_supplicant_deauthenticate(
20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2090c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
20911e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt#ifdef ANDROID
20921e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt		if (wpa_s->conf->ap_scan == 1) {
20931e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt#else
2094c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (wpa_s->conf->ap_scan == 1 &&
2095c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		    wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION) {
20961e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt#endif
2097c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			if (wpa_supplicant_assoc_update_ie(wpa_s) < 0)
2098c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				wpa_msg(wpa_s, MSG_WARNING,
2099c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					"WPA/RSN IEs not updated");
2100c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		}
21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SME
21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN);
21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->sme.prev_bssid_set = 1;
21060c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt	wpa_s->sme.last_unprot_disconnect.sec = 0;
21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SME */
21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid) {
21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* When using scanning (ap_scan=1), SIM PC/SC interface can be
21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * initialized before association, but for other modes,
21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * initialize PC/SC here, if the current configuration needs
21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * smartcard or SIM/USIM. */
21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid);
21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_notify_assoc(wpa_s->wpa, bssid);
21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->l2)
21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l2_packet_notify_auth_start(wpa_s->l2);
21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Set portEnabled first to FALSE in order to get EAP state machine out
21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE
21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * state machine may transit to AUTHENTICATING state based on obsolete
21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to
21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * AUTHENTICATED without ever giving chance to EAP state machine to
21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * reset the state.
21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!ft_completed) {
21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed)
21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* 802.1X::portControl = Auto */
21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->eapol_received = 0;
21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE ||
21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (wpa_s->current_ssid &&
21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS)) {
214209f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt		if (wpa_s->current_ssid &&
214309f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt		    wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE &&
214451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt		    (wpa_s->drv_flags &
214551b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt		     WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) {
214651b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			/*
214751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			 * Set the key after having received joined-IBSS event
214851b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			 * from the driver.
214951b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			 */
215051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt			wpa_supplicant_set_wpa_none_key(wpa_s,
215151b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt							wpa_s->current_ssid);
215251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt		}
21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (!ft_completed) {
21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Timeout for receiving the first EAPOL packet */
21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cancel_scan(wpa_s);
21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * We are done; the driver will take care of RSN 4-way
21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * handshake.
21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * The driver will take care of RSN 4-way handshake, so we need
21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * to allow EAPOL supplicant to complete its work without
21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * waiting for WPA supplicant.
21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (ft_completed) {
21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * FT protocol completed - make sure EAPOL state machine ends
21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * up in authenticated.
21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2190a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen	wpa_s->last_eapol_matches_bssid = 0;
2191a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen
21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->pending_eapol_rx) {
2193fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		struct os_reltime now, age;
2194fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_get_reltime(&now);
2195fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_reltime_sub(&now, &wpa_s->pending_eapol_rx_time, &age);
21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (age.sec == 0 && age.usec < 100000 &&
21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) ==
21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    0) {
21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Process pending EAPOL "
22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"frame that was received just before "
22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"association notification");
22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_rx_eapol(
22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, wpa_s->pending_eapol_rx_src,
22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpabuf_head(wpa_s->pending_eapol_rx),
22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpabuf_len(wpa_s->pending_eapol_rx));
22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wpa_s->pending_eapol_rx);
22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pending_eapol_rx = NULL;
22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
221351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt	    wpa_s->current_ssid &&
221451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) {
22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Set static WEP keys again */
22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_set_wep_keys(wpa_s, wpa_s->current_ssid);
22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid &&
22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE &&
22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->ibss_rsn == NULL) {
22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ibss_rsn = ibss_rsn_init(wpa_s);
22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_s->ibss_rsn) {
22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "Failed to init IBSS RSN");
22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_deauthenticate(
22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ibss_rsn_set_psk(wpa_s->ibss_rsn, wpa_s->current_ssid->psk);
22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
223661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
223761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpas_wps_notify_assoc(wpa_s, bssid);
22386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
22396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (data) {
22406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wmm_ac_notify_assoc(wpa_s, data->assoc_info.resp_ies,
22416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				    data->assoc_info.resp_ies_len,
22426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				    &data->assoc_info.wmm_params);
22436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
22446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (wpa_s->reassoc_same_bss)
22456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wmm_ac_restore_tspecs(wpa_s);
22466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int disconnect_reason_recoverable(u16 reason_code)
22511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
22521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY ||
22531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA ||
22541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA;
22551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
22561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
22571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
2259c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					  u16 reason_code,
2260c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					  int locally_generated)
22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *bssid;
22632b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
22642b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
22652b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		/*
22662b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		 * At least Host AP driver and a Prism3 card seemed to be
22672b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		 * generating streams of disconnected events when configuring
22682b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		 * IBSS for WPA-None. Ignore them for now.
22692b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		 */
22702b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		return;
22712b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	}
22722b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
22732b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	bssid = wpa_s->bssid;
22742b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	if (is_zero_ether_addr(bssid))
22752b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		bssid = wpa_s->pending_bssid;
22762b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
22772b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	if (!is_zero_ether_addr(bssid) ||
22782b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	    wpa_s->wpa_state >= WPA_AUTHENTICATING) {
22792b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
22802b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen			" reason=%d%s",
22812b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen			MAC2STR(bssid), reason_code,
22822b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen			locally_generated ? " locally_generated=1" : "");
22832b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	}
22842b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen}
22852b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
22862b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen
2287d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int could_be_psk_mismatch(struct wpa_supplicant *wpa_s, u16 reason_code,
2288d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				 int locally_generated)
2289d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{
2290d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (wpa_s->wpa_state != WPA_4WAY_HANDSHAKE ||
2291d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	    !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
2292d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return 0; /* Not in 4-way handshake with PSK */
2293d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2294d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	/*
2295d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 * It looks like connection was lost while trying to go through PSK
2296d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 * 4-way handshake. Filter out known disconnection cases that are caused
2297d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 * by something else than PSK mismatch to avoid confusing reports.
2298d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 */
2299d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2300d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (locally_generated) {
2301d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		if (reason_code == WLAN_REASON_IE_IN_4WAY_DIFFERS)
2302d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			return 0;
2303d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
2304d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2305d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	return 1;
2306d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt}
2307d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
2308d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
23092b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenstatic void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
23102b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen						 u16 reason_code,
23112b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen						 int locally_generated)
23122b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen{
23132b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen	const u8 *bssid;
23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int authenticating;
23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 prev_pending_bssid[ETH_ALEN];
23161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_bss *fast_reconnect = NULL;
23171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_ssid *fast_reconnect_ssid = NULL;
2318f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen	struct wpa_ssid *last_ssid;
23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * At least Host AP driver and a Prism3 card seemed to be
23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * generating streams of disconnected events when configuring
23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * IBSS for WPA-None. Ignore them for now.
23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - ignore in "
23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"IBSS/WPA-None mode");
23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2334d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) {
23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"pre-shared key may be incorrect");
2337391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		if (wpas_p2p_4way_hs_failed(wpa_s) > 0)
2338391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			return; /* P2P group removed */
23396dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		wpas_auth_failed(wpa_s, "WRONG_KEY");
23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2341ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt	if (!wpa_s->disconnected &&
2342ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt	    (!wpa_s->auto_reconnect_disabled ||
2343661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	     wpa_s->key_mgmt == WPA_KEY_MGMT_WPS ||
2344661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	     wpas_wps_searching(wpa_s))) {
23451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect enabled: try to "
2346661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			"reconnect (wps=%d/%d wpa_state=%d)",
23471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s->key_mgmt == WPA_KEY_MGMT_WPS,
2348661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			wpas_wps_searching(wpa_s),
23491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s->wpa_state);
23501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_s->wpa_state == WPA_COMPLETED &&
23511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    wpa_s->current_ssid &&
23521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
2353c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		    !locally_generated &&
23541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    disconnect_reason_recoverable(reason_code)) {
23551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/*
23561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * It looks like the AP has dropped association with
23571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * us, but could allow us to get back in. Try to
23581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * reconnect to the same BSS without full scan to save
23591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * time for some common cases.
23601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 */
23611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			fast_reconnect = wpa_s->current_bss;
23621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			fast_reconnect_ssid = wpa_s->current_ssid;
23631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (wpa_s->wpa_state >= WPA_ASSOCIATING)
2364c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 100000);
23651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		else
23661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Do not request new "
23671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				"immediate scan");
23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
23691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect disabled: do not "
23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"try to re-connect");
23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->reassociate = 0;
23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->disconnected = 1;
2373c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_supplicant_cancel_sched_scan(wpa_s);
23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bssid = wpa_s->bssid;
23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (is_zero_ether_addr(bssid))
23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid = wpa_s->pending_bssid;
23781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
23791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpas_connection_failed(wpa_s, bssid);
23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_notify_disassoc(wpa_s->wpa);
238104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (locally_generated)
238204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->disconnect_reason = -reason_code;
238304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
238404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->disconnect_reason = reason_code;
238504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpas_notify_disconnect_reason(wpa_s);
23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_dynamic_keys(wpa_s)) {
23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - remove keys");
23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_clear_keys(wpa_s, wpa_s->bssid);
23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2390f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen	last_ssid = wpa_s->current_ssid;
23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_mark_disassoc(wpa_s);
23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2393f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen	if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) {
23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sme_disassoc_while_authenticating(wpa_s, prev_pending_bssid);
2395f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen		wpa_s->current_ssid = last_ssid;
2396f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen	}
23971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2398f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if (fast_reconnect &&
2399f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    !wpas_network_disabled(wpa_s, fast_reconnect_ssid) &&
2400f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    !disallowed_bssid(wpa_s, fast_reconnect->bssid) &&
2401f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    !disallowed_ssid(wpa_s, fast_reconnect->ssid,
2402f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			     fast_reconnect->ssid_len) &&
2403f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	    !wpas_temp_disabled(wpa_s, fast_reconnect_ssid)) {
24041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_SCAN_PROCESSING
24051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Try to reconnect to the same BSS");
24061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_supplicant_connect(wpa_s, fast_reconnect,
24071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   fast_reconnect_ssid) < 0) {
24081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/* Recover through full scan */
24091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 100000);
24101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
24111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
2412f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	} else if (fast_reconnect) {
2413f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		/*
2414f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 * Could not reconnect to the same BSS due to network being
2415f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 * disabled. Use a new scan to match the alternative behavior
2416f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 * above, i.e., to continue automatic reconnection attempt in a
2417f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 * way that enforces disabled network rules.
2418f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		 */
2419f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 100000);
24201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
24251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpa_supplicant_delayed_mic_error_report(void *eloop_ctx, void *sock_ctx)
24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->pending_mic_error_report)
24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Sending pending MIC error report");
24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_key_request(wpa_s->wpa, 1, wpa_s->pending_mic_error_pairwise);
24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pending_mic_error_report = 0;
24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 union wpa_event_data *data)
24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pairwise;
2444fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	struct os_reltime t;
24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pairwise = (data && data->michael_mic_failure.unicast);
2448fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	os_get_reltime(&t);
2449fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if ((wpa_s->last_michael_mic_error.sec &&
2450fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	     !os_reltime_expired(&t, &wpa_s->last_michael_mic_error, 60)) ||
24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->pending_mic_error_report) {
24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->pending_mic_error_report) {
24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * Send the pending MIC error report immediately since
24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * we are going to start countermeasures and AP better
24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * do the same.
24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_sm_key_request(wpa_s->wpa, 1,
24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   wpa_s->pending_mic_error_pairwise);
24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Send the new MIC error report immediately since we are going
24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * to start countermeasures and AP better do the same.
24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* initialize countermeasures */
24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->countermeasures = 1;
24691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
24701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_blacklist_add(wpa_s, wpa_s->bssid);
24711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Need to wait for completion of request frame. We do not get
24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * any callback for the message completion, so just wait a
24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * short while and hope for the best. */
24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_sleep(0, 10000);
24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_countermeasures(wpa_s, 1);
24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deauthenticate(wpa_s,
24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      WLAN_REASON_MICHAEL_MIC_FAILURE);
24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_cancel_timeout(wpa_supplicant_stop_countermeasures,
24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     wpa_s, NULL);
24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_register_timeout(60, 0,
24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       wpa_supplicant_stop_countermeasures,
24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       wpa_s, NULL);
24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* TODO: mark the AP rejected for 60 second. STA is
24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * allowed to associate with another AP.. */
24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->mic_errors_seen) {
24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * Reduce the effectiveness of Michael MIC error
24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * reports as a means for attacking against TKIP if
24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * more than one MIC failure is noticed with the same
24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * PTK. We delay the transmission of the reports by a
24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * random time between 0 and 60 seconds in order to
24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * force the attacker wait 60 seconds before getting
25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * the information on whether a frame resulted in a MIC
25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * failure.
25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 rval[4];
25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int sec;
25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_get_random(rval, sizeof(rval)) < 0)
25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				sec = os_random() % 60;
25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				sec = WPA_GET_BE32(rval) % 60;
25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Delay MIC error "
25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"report %d seconds", sec);
25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->pending_mic_error_report = 1;
25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->pending_mic_error_pairwise = pairwise;
25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop_cancel_timeout(
25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_delayed_mic_error_report,
25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, NULL);
25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop_register_timeout(
25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				sec, os_random() % 1000000,
25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_delayed_mic_error_report,
25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, NULL);
25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_DELAYED_MIC_ERROR_REPORT */
25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2528fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_s->last_michael_mic_error = t;
25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->mic_errors_seen++;
25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TERMINATE_ONLASTIF
25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int any_interfaces(struct wpa_supplicant *head)
25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = head; wpa_s != NULL; wpa_s = wpa_s->next)
25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_s->interface_removed)
25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TERMINATE_ONLASTIF */
25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      union wpa_event_data *data)
25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (data->interface_status.ievent) {
25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_ADDED:
25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_s->interface_removed)
25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->interface_removed = 0;
25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was added");
25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_driver_init(wpa_s) < 0) {
25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "Failed to initialize the "
25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"driver after interface was added");
25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2563a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt
2564a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt#ifdef CONFIG_P2P
2565a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		if (!wpa_s->global->p2p &&
2566a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		    !wpa_s->global->p2p_disabled &&
2567a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		    !wpa_s->conf->p2p_disabled &&
2568a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		    (wpa_s->drv_flags &
2569a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		     WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
2570a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		    wpas_p2p_add_p2pdev_interface(
2571a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			    wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
2572a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			wpa_printf(MSG_INFO,
2573a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				   "P2P: Failed to enable P2P Device interface");
2574a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			/* Try to continue without. P2P will be disabled. */
2575a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		}
2576a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt#endif /* CONFIG_P2P */
2577a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt
25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_REMOVED:
25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was removed");
25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->interface_removed = 1;
25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_mark_disassoc(wpa_s);
258304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l2_packet_deinit(wpa_s->l2);
25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->l2 = NULL;
2586a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt
2587a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt#ifdef CONFIG_P2P
2588a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		if (wpa_s->global->p2p &&
2589a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		    wpa_s->global->p2p_init_wpa_s->parent == wpa_s &&
2590a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		    (wpa_s->drv_flags &
2591a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		     WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) {
2592a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
2593a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				"Removing P2P Device interface");
2594a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			wpa_supplicant_remove_iface(
2595a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				wpa_s->global, wpa_s->global->p2p_init_wpa_s,
2596a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				0);
2597a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt			wpa_s->global->p2p_init_wpa_s = NULL;
2598a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt		}
2599a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt#endif /* CONFIG_P2P */
2600a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt
26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TERMINATE_ONLASTIF
26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* check if last interface */
26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!any_interfaces(wpa_s->global->ifaces))
26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop_terminate();
26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TERMINATE_ONLASTIF */
26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY
26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_event_stkstart(struct wpa_supplicant *wpa_s,
26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      union wpa_event_data *data)
26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL)
26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_stkstart(wpa_s->wpa, data->stkstart.peer);
26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */
26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_tdls(struct wpa_supplicant *wpa_s,
26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      union wpa_event_data *data)
26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL)
26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (data->tdls.oper) {
26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TDLS_REQUEST_SETUP:
26314b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		wpa_tdls_remove(wpa_s->wpa, data->tdls.peer);
26324b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		if (wpa_tdls_is_external_setup(wpa_s->wpa))
26334b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			wpa_tdls_start(wpa_s->wpa, data->tdls.peer);
26344b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		else
26354b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, data->tdls.peer);
26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TDLS_REQUEST_TEARDOWN:
26386a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt		if (wpa_tdls_is_external_setup(wpa_s->wpa))
26396a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt			wpa_tdls_teardown_link(wpa_s->wpa, data->tdls.peer,
26406a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt					       data->tdls.reason_code);
26416a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt		else
26426a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt			wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN,
26436a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt					  data->tdls.peer);
26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
26454dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt	case TDLS_REQUEST_DISCOVER:
26464dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt			wpa_tdls_send_discovery_request(wpa_s->wpa,
26474dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt							data->tdls.peer);
26484dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt		break;
26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2654a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_WNM
265561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void wpa_supplicant_event_wnm(struct wpa_supplicant *wpa_s,
265661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				     union wpa_event_data *data)
265761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
265861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (data == NULL)
265961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
266061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	switch (data->wnm.oper) {
266161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	case WNM_OPER_SLEEP:
266261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Start sending WNM-Sleep Request "
266361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "(action=%d, intval=%d)",
266461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   data->wnm.sleep_action, data->wnm.sleep_intval);
266561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ieee802_11_send_wnmsleep_req(wpa_s, data->wnm.sleep_action,
2666a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt					     data->wnm.sleep_intval, NULL);
266761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		break;
266861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
266961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
2670a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_WNM */
267161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
267261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s,
26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 union wpa_event_data *data)
26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL)
26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_ft_process_response(wpa_s->wpa, data->ft_ies.ies,
26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.ies_len,
26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.ft_action,
26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.target_ap,
26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.ric_ies,
26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    data->ft_ies.ric_ies_len) < 0) {
26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* TODO: prevent MLME/driver from trying to associate? */
26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s,
26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						union wpa_event_data *data)
26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state < WPA_ASSOCIATED)
26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data == NULL)
27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_s->current_ssid;
27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL)
27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt))
27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer);
27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2710c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2711c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2712c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic void wpa_supplicant_event_ibss_auth(struct wpa_supplicant *wpa_s,
2713c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					   union wpa_event_data *data)
2714c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
2715c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
2716c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2717c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (ssid == NULL)
2718c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2719c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2720c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	/* check if the ssid is correctly configured as IBSS/RSN */
2721c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt))
2722c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2723c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2724c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	ibss_rsn_handle_auth(wpa_s->ibss_rsn, data->rx_mgmt.frame,
2725c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			     data->rx_mgmt.frame_len);
2726c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ft_rx_action(struct wpa_supplicant *wpa_s, const u8 *data,
27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 size_t len)
27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *sta_addr, *target_ap_addr;
27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 status;
27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump(MSG_MSGDUMP, "FT: RX Action", data, len);
27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return; /* only SME case supported for now */
27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len < 1 + 2 * ETH_ALEN + 2)
27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (data[0] != 2)
27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return; /* Only FT Action Response is supported for now */
27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sta_addr = data + 1;
27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	target_ap_addr = data + 1 + ETH_ALEN;
27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	status = WPA_GET_LE16(data + 1 + 2 * ETH_ALEN);
27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "FT: Received FT Action Response: STA "
27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MACSTR " TargetAP " MACSTR " status %u",
27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(sta_addr), MAC2STR(target_ap_addr), status);
27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) {
27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "FT: Foreign STA Address " MACSTR
27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" in FT Action Response", MAC2STR(sta_addr));
27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (status) {
27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "FT: FT Action Response indicates "
27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"failure (status code %d)", status);
27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* TODO: report error to FT code(?) */
27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_ft_process_response(wpa_s->wpa, data + 1 + 2 * ETH_ALEN + 2,
27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    len - (1 + 2 * ETH_ALEN + 2), 1,
27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    target_ap_addr, NULL, 0) < 0)
27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SME
27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	{
27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_bss *bss;
27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss = wpa_bss_get_bssid(wpa_s, target_ap_addr);
27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss)
27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->sme.freq = bss->freq;
27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->sme.auth_alg = WPA_AUTH_ALG_FT;
27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sme_associate(wpa_s, WPAS_MODE_INFRA, target_ap_addr,
27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      WLAN_AUTH_FT);
27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SME */
27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_unprot_deauth(struct wpa_supplicant *wpa_s,
27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       struct unprot_deauth *e)
27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Unprotected Deauthentication frame "
27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "dropped: " MACSTR " -> " MACSTR
27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   " (reason code %u)",
27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_event_unprot_disassoc(struct wpa_supplicant *wpa_s,
27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 struct unprot_disassoc *e)
27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Unprotected Disassociation frame "
28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "dropped: " MACSTR " -> " MACSTR
28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   " (reason code %u)",
28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2810c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic void wpas_event_disconnect(struct wpa_supplicant *wpa_s, const u8 *addr,
2811c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				  u16 reason_code, int locally_generated,
2812c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				  const u8 *ie, size_t ie_len, int deauth)
2813c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
2814c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_AP
2815c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->ap_iface && addr) {
2816c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], addr);
2817c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2818c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2819c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2820c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->ap_iface) {
2821c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Ignore deauth event in AP mode");
2822c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2823c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2824c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
2825c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2826203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	if (!locally_generated)
2827203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		wpa_s->own_disconnect_req = 0;
2828203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt
2829c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_supplicant_event_disassoc(wpa_s, reason_code, locally_generated);
2830c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2831344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	if (((reason_code == WLAN_REASON_IEEE_802_1X_AUTH_FAILED ||
2832344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	      ((wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
2833344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt		(wpa_s->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) &&
2834344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	       eapol_sm_failed(wpa_s->eapol))) &&
2835344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt	     !wpa_s->eap_expected_failure))
28366dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		wpas_auth_failed(wpa_s, "AUTH_FAILED");
2837c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2838c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_P2P
2839391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (deauth && reason_code > 0) {
2840c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		if (wpas_p2p_deauth_notif(wpa_s, addr, reason_code, ie, ie_len,
2841c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					  locally_generated) > 0) {
2842c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			/*
2843c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			 * The interface was removed, so cannot continue
2844c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			 * processing any additional operations after this.
2845c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			 */
2846c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			return;
2847c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		}
2848c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2849c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_P2P */
2850c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2851c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_supplicant_event_disassoc_finish(wpa_s, reason_code,
2852c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					     locally_generated);
2853c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
2854c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2855c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2856c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic void wpas_event_disassoc(struct wpa_supplicant *wpa_s,
2857c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				struct disassoc_info *info)
2858c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
2859c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	u16 reason_code = 0;
2860c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	int locally_generated = 0;
2861c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	const u8 *addr = NULL;
2862c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	const u8 *ie = NULL;
2863c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	size_t ie_len = 0;
2864c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2865c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Disassociation notification");
2866c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2867c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (info) {
2868c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		addr = info->addr;
2869c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		ie = info->ie;
2870c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		ie_len = info->ie_len;
2871c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		reason_code = info->reason_code;
2872c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		locally_generated = info->locally_generated;
2873c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s", reason_code,
2874c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			locally_generated ? " (locally generated)" : "");
2875c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		if (addr)
2876c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
2877c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				MAC2STR(addr));
2878c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_hexdump(MSG_DEBUG, "Disassociation frame IE(s)",
2879c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			    ie, ie_len);
2880c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2881c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2882c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_AP
2883c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->ap_iface && info && info->addr) {
2884c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], info->addr);
2885c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2886c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2887c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2888c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->ap_iface) {
2889c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Ignore disassoc event in AP mode");
2890c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return;
2891c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2892c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
2893c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2894c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_P2P
2895c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (info) {
2896c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpas_p2p_disassoc_notif(
2897c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			wpa_s, info->addr, reason_code, info->ie, info->ie_len,
2898c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			locally_generated);
2899c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2900c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_P2P */
2901c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2902c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
2903c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		sme_event_disassoc(wpa_s, info);
2904c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2905c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpas_event_disconnect(wpa_s, addr, reason_code, locally_generated,
2906c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			      ie, ie_len, 0);
2907c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
2908c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2909c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2910c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic void wpas_event_deauth(struct wpa_supplicant *wpa_s,
2911c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			      struct deauth_info *info)
2912c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{
2913c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	u16 reason_code = 0;
2914c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	int locally_generated = 0;
2915c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	const u8 *addr = NULL;
2916c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	const u8 *ie = NULL;
2917c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	size_t ie_len = 0;
2918c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2919c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Deauthentication notification");
2920c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2921c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	if (info) {
2922c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		addr = info->addr;
2923c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		ie = info->ie;
2924c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		ie_len = info->ie_len;
2925c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		reason_code = info->reason_code;
2926c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		locally_generated = info->locally_generated;
2927c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s",
2928c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			reason_code,
2929c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			locally_generated ? " (locally generated)" : "");
2930c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		if (addr) {
2931c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
2932c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				MAC2STR(addr));
2933c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		}
2934c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpa_hexdump(MSG_DEBUG, "Deauthentication frame IE(s)",
2935c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			    ie, ie_len);
2936c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	}
2937c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2938c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpa_reset_ft_completed(wpa_s->wpa);
2939c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2940c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt	wpas_event_disconnect(wpa_s, addr, reason_code,
2941c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			      locally_generated, ie, ie_len, 1);
2942c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt}
2943c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
2944c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt
29457dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtstatic const char * reg_init_str(enum reg_change_initiator init)
29467dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt{
29477dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	switch (init) {
29487dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_SET_BY_CORE:
29497dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "CORE";
29507dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_SET_BY_USER:
29517dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "USER";
29527dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_SET_BY_DRIVER:
29537dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "DRIVER";
29547dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_SET_BY_COUNTRY_IE:
29557dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "COUNTRY_IE";
29567dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_BEACON_HINT:
29577dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "BEACON_HINT";
29587dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	}
29597dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	return "?";
29607dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt}
29617dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
29627dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
29637dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtstatic const char * reg_type_str(enum reg_type type)
29647dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt{
29657dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	switch (type) {
29667dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_UNKNOWN:
29677dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "UNKNOWN";
29687dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_COUNTRY:
29697dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "COUNTRY";
29707dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_WORLD:
29717dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "WORLD";
29727dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_CUSTOM_WORLD:
29737dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "CUSTOM_WORLD";
29747dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	case REGDOM_TYPE_INTERSECTION:
29757dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		return "INTERSECTION";
29767dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	}
29777dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	return "?";
29787dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt}
29797dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
29807dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
29817dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtstatic void wpa_supplicant_update_channel_list(
29827dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	struct wpa_supplicant *wpa_s, struct channel_list_changed *info)
2983cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{
2984cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	struct wpa_supplicant *ifs;
2985cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
29867dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s",
2987c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt		reg_init_str(info->initiator), reg_type_str(info->type),
29887dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		info->alpha2[0] ? " alpha2=" : "",
29897dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		info->alpha2[0] ? info->alpha2 : "");
29907dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt
2991cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (wpa_s->drv_priv == NULL)
2992cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		return; /* Ignore event during drv initialization */
2993cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
2994cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	free_hw_features(wpa_s);
2995cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	wpa_s->hw.modes = wpa_drv_get_hw_feature_data(
2996cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		wpa_s, &wpa_s->hw.num_modes, &wpa_s->hw.flags);
2997cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
2998cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	wpas_p2p_update_channel_list(wpa_s);
2999cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
3000cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	/*
300101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt	 * Check other interfaces to see if they share the same radio. If
3002cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 * so, they get updated with this same hw mode info.
3003cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 */
300401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
300501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 radio_list) {
300601904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		if (ifs != wpa_s) {
3007cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			wpa_printf(MSG_DEBUG, "%s: Updating hw mode",
3008cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				   ifs->ifname);
3009cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			free_hw_features(ifs);
3010cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			ifs->hw.modes = wpa_drv_get_hw_feature_data(
3011cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				ifs, &ifs->hw.num_modes, &ifs->hw.flags);
3012cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		}
3013cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	}
3014dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
3015dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	/* Restart sched_scan with updated channel list */
3016dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (wpa_s->sched_scanning) {
3017dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
3018dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			"Channel list changed restart sched scan.");
3019dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		wpa_supplicant_cancel_sched_scan(wpa_s);
3020dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
3021dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	}
3022cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt}
3023cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
3024cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
3025fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
30266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				      const u8 *frame, size_t len, int freq,
30276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				      int rssi)
3028fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
3029623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt	const struct ieee80211_mgmt *mgmt;
3030fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	const u8 *payload;
3031fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	size_t plen;
3032fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	u8 category;
3033fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3034fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (len < IEEE80211_HDRLEN + 2)
3035fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
3036fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3037623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt	mgmt = (const struct ieee80211_mgmt *) frame;
3038623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt	payload = frame + IEEE80211_HDRLEN;
3039fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	category = *payload++;
3040623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt	plen = len - IEEE80211_HDRLEN - 1;
3041fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3042fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Received Action frame: SA=" MACSTR
3043fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		" Category=%u DataLen=%d freq=%d MHz",
3044fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		MAC2STR(mgmt->sa), category, (int) plen, freq);
3045fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
30466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (category == WLAN_ACTION_WMM) {
30476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wmm_ac_rx_action(wpa_s, mgmt->da, mgmt->sa, payload, plen);
30486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return;
30496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
30506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
3051fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_IEEE80211R
3052fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (category == WLAN_ACTION_FT) {
3053fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		ft_rx_action(wpa_s, payload, plen);
3054fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
3055fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
3056fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
3057fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3058fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_IEEE80211W
3059fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_SME
3060fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (category == WLAN_ACTION_SA_QUERY) {
3061fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		sme_sa_query_rx(wpa_s, mgmt->sa, payload, plen);
3062fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
3063fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
3064fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_SME */
3065fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
3066fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3067fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_WNM
3068fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (mgmt->u.action.category == WLAN_ACTION_WNM) {
3069fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		ieee802_11_rx_wnm_action(wpa_s, mgmt, len);
3070fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
3071fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
3072fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_WNM */
3073fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3074fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_GAS
30751846323989242844f0e857458a8939fa5836429cDmitry Shmidt	if ((mgmt->u.action.category == WLAN_ACTION_PUBLIC ||
30761846323989242844f0e857458a8939fa5836429cDmitry Shmidt	     mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) &&
3077fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    gas_query_rx(wpa_s->gas, mgmt->da, mgmt->sa, mgmt->bssid,
30781846323989242844f0e857458a8939fa5836429cDmitry Shmidt			 mgmt->u.action.category,
3079fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			 payload, plen, freq) == 0)
3080fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
3081fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_GAS */
3082fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3083fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_TDLS
3084fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (category == WLAN_ACTION_PUBLIC && plen >= 4 &&
3085fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    payload[0] == WLAN_TDLS_DISCOVERY_RESPONSE) {
3086fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
3087fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			"TDLS: Received Discovery Response from " MACSTR,
3088fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			MAC2STR(mgmt->sa));
3089fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
3090fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
3091fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_TDLS */
3092fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3093fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_INTERWORKING
3094fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (category == WLAN_ACTION_QOS && plen >= 1 &&
3095fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	    payload[0] == QOS_QOS_MAP_CONFIG) {
3096fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		const u8 *pos = payload + 1;
3097fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		size_t qlen = plen - 1;
3098fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: Received QoS Map Configure frame from "
3099fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			MACSTR, MAC2STR(mgmt->sa));
3100fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) == 0 &&
3101fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		    qlen > 2 && pos[0] == WLAN_EID_QOS_MAP_SET &&
3102fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		    pos[1] <= qlen - 2 && pos[1] >= 16)
3103fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpas_qos_map_set(wpa_s, pos + 2, pos[1]);
3104fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
3105fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
3106fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
3107fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
31086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
31096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	    payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) {
31106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpas_rrm_process_neighbor_rep(wpa_s, payload + 1, plen - 1);
31116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return;
31126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
31136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
31146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
31156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	    payload[0] == WLAN_RRM_LINK_MEASUREMENT_REQUEST) {
31166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpas_rrm_handle_link_measurement_request(wpa_s, mgmt->sa,
31176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt							 payload + 1, plen - 1,
31186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt							 rssi);
31196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return;
31206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
31216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
3122fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
3123fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			   category, payload, plen, freq);
31246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_s->ifmsh)
31256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		mesh_mpm_action_rx(wpa_s, mgmt, len);
3126fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
3127fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3128fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3129cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic void wpa_supplicant_notify_avoid_freq(struct wpa_supplicant *wpa_s,
3130cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					     union wpa_event_data *event)
3131cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
3132cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P
3133cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_supplicant *ifs;
3134cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */
3135cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wpa_freq_range_list *list;
3136cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	char *str = NULL;
3137cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3138cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	list = &event->freq_range;
3139cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3140cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (list->num)
3141cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		str = freq_range_list_str(list);
3142cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AVOID_FREQ "ranges=%s",
3143cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		str ? str : "");
3144cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3145cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_P2P
3146cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (freq_range_list_parse(&wpa_s->global->p2p_go_avoid_freq, str)) {
3147cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_dbg(wpa_s, MSG_ERROR, "%s: Failed to parse freq range",
3148cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			__func__);
3149cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	} else {
3150cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Update channel list based on frequency avoid event");
3151cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpas_p2p_update_channel_list(wpa_s);
3152cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
3153cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3154cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
3155cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		int freq;
3156cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (!ifs->current_ssid ||
3157cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    !ifs->current_ssid->p2p_group ||
3158cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		    (ifs->current_ssid->mode != WPAS_MODE_P2P_GO &&
3159cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		     ifs->current_ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION))
3160cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			continue;
3161cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3162cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		freq = ifs->current_ssid->frequency;
3163cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		if (!freq_range_list_includes(list, freq)) {
3164cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			wpa_dbg(ifs, MSG_DEBUG, "P2P GO operating frequency %d MHz in safe range",
3165cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				freq);
3166cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			continue;
3167cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		}
3168cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3169cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_dbg(ifs, MSG_DEBUG, "P2P GO operating in unsafe frequency %d MHz",
3170cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			freq);
3171cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		/* TODO: Consider using CSA or removing the group within
3172cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		 * wpa_supplicant */
3173cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_msg(ifs, MSG_INFO, P2P_EVENT_REMOVE_AND_REFORM_GROUP);
3174cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
3175cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_P2P */
3176cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3177cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	os_free(str);
3178cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
3179cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
3180cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
31816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpa_supplicant_event_assoc_auth(struct wpa_supplicant *wpa_s,
31826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					    union wpa_event_data *data)
31836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
31846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG,
31856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		"Connection authorized by device, previous state %d",
31866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_s->wpa_state);
31876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (wpa_s->wpa_state == WPA_ASSOCIATED) {
31886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
31896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
31906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
31916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
31926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	}
31936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_sm_set_rx_replay_ctr(wpa_s->wpa, data->assoc_info.key_replay_ctr);
31946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	wpa_sm_set_ptk_kck_kek(wpa_s->wpa, data->assoc_info.ptk_kck,
3195807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt			       data->assoc_info.ptk_kck_len,
3196807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt			       data->assoc_info.ptk_kek,
3197807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt			       data->assoc_info.ptk_kek_len);
31986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
31996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
32006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_event(void *ctx, enum wpa_event_type event,
32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  union wpa_event_data *data)
32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3205af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt	int resched;
32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    event != EVENT_INTERFACE_ENABLED &&
32091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    event != EVENT_INTERFACE_STATUS &&
32101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    event != EVENT_SCHED_SCAN_STOPPED) {
32111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
32121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			"Ignore event %s (%d) while interface is disabled",
32131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			event_to_string(event), event);
32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG
32181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
32191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int level = MSG_DEBUG;
32201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
322104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (event == EVENT_RX_MGMT && data->rx_mgmt.frame_len >= 24) {
32221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		const struct ieee80211_hdr *hdr;
32231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		u16 fc;
32241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
32251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		fc = le_to_host16(hdr->frame_control);
32261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
32271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
32281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			level = MSG_EXCESSIVE;
32291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
32301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
32311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_dbg(wpa_s, level, "Event %s (%d) received",
32321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		event_to_string(event), event);
32331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
32341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */
32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (event) {
32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_AUTH:
32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sme_event_auth(wpa_s, data);
32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_ASSOC:
32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_assoc(wpa_s, data);
32426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (data && data->assoc_info.authorized)
32436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_supplicant_event_assoc_auth(wpa_s, data);
32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_DISASSOC:
3246c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpas_event_disassoc(wpa_s,
3247c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				    data ? &data->disassoc_info : NULL);
3248c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		break;
32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_DEAUTH:
3250c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		wpas_event_deauth(wpa_s,
3251c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				  data ? &data->deauth_info : NULL);
32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_MICHAEL_MIC_FAILURE:
32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_michael_mic_failure(wpa_s, data);
32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_SCAN_PROCESSING
3257fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	case EVENT_SCAN_STARTED:
3258fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_get_reltime(&wpa_s->scan_start_time);
3259fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (wpa_s->own_scan_requested) {
3260fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			struct os_reltime diff;
3261fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3262fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			os_reltime_sub(&wpa_s->scan_start_time,
3263fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				       &wpa_s->scan_trigger_time, &diff);
3264fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Own scan request started a scan in %ld.%06ld seconds",
3265fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				diff.sec, diff.usec);
3266fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_s->own_scan_requested = 0;
3267fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_s->own_scan_running = 1;
3268fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
3269fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			    wpa_s->manual_scan_use_id) {
3270661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				wpa_msg_ctrl(wpa_s, MSG_INFO,
3271661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					     WPA_EVENT_SCAN_STARTED "id=%u",
3272661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					     wpa_s->manual_scan_id);
3273fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			} else {
3274661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt				wpa_msg_ctrl(wpa_s, MSG_INFO,
3275661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt					     WPA_EVENT_SCAN_STARTED);
3276fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			}
3277fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		} else {
3278fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "External program started a scan");
32792f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt			wpa_s->radio->external_scan_running = 1;
3280661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_STARTED);
3281fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		}
3282fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		break;
32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_SCAN_RESULTS:
3284fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (os_reltime_initialized(&wpa_s->scan_start_time)) {
3285fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			struct os_reltime now, diff;
3286fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			os_get_reltime(&now);
3287fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			os_reltime_sub(&now, &wpa_s->scan_start_time, &diff);
3288fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_s->scan_start_time.sec = 0;
3289fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_s->scan_start_time.usec = 0;
3290fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Scan completed in %ld.%06ld seconds",
3291fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				diff.sec, diff.usec);
3292fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		}
32937f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		if (wpa_supplicant_event_scan_results(wpa_s, data))
32947f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			break; /* interface may have been removed */
3295fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		wpa_s->own_scan_running = 0;
32962f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt		wpa_s->radio->external_scan_running = 0;
3297fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		radio_work_check_next(wpa_s);
32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_SCAN_PROCESSING */
33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_ASSOCINFO:
33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_associnfo(wpa_s, data);
33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_STATUS:
33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_interface_status(wpa_s, data);
33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_PMKID_CANDIDATE:
33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_pmkid_candidate(wpa_s, data);
33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY
33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_STKSTART:
33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_stkstart(wpa_s, data);
33128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */
33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_TDLS:
33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_tdls(wpa_s, data);
33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
3319a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_WNM
332061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	case EVENT_WNM:
332161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_supplicant_event_wnm(wpa_s, data);
332261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		break;
3323a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_WNM */
33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_FT_RESPONSE:
33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_ft_response(wpa_s, data);
33278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
33298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
33308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_IBSS_RSN_START:
33318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_ibss_rsn_start(wpa_s, data);
33328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_ASSOC_REJECT:
33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (data->assoc_reject.bssid)
33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"bssid=" MACSTR	" status_code=%u",
33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				MAC2STR(data->assoc_reject.bssid),
33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->assoc_reject.status_code);
33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"status_code=%u",
33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->assoc_reject.status_code);
33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			sme_event_assoc_reject(wpa_s, data);
3346b485b188f853a4ec5342c2ea49705b545b2caf3dJeff Johnson		else {
3347d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			const u8 *bssid = data->assoc_reject.bssid;
3348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			if (bssid == NULL || is_zero_ether_addr(bssid))
3349d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				bssid = wpa_s->pending_bssid;
3350d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			wpas_connection_failed(wpa_s, bssid);
3351d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			wpa_supplicant_mark_disassoc(wpa_s);
3352d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		}
33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_AUTH_TIMED_OUT:
33556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		/* It is possible to get this event from earlier connection */
33566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (wpa_s->current_ssid &&
33576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		    wpa_s->current_ssid->mode == WPAS_MODE_MESH) {
33586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
33596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				"Ignore AUTH_TIMED_OUT in mesh configuration");
33606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			break;
33616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		}
33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			sme_event_auth_timed_out(wpa_s, data);
33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_ASSOC_TIMED_OUT:
33666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		/* It is possible to get this event from earlier connection */
33676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (wpa_s->current_ssid &&
33686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		    wpa_s->current_ssid->mode == WPAS_MODE_MESH) {
33696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG,
33706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				"Ignore ASSOC_TIMED_OUT in mesh configuration");
33716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			break;
33726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		}
33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			sme_event_assoc_timed_out(wpa_s, data);
33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_TX_STATUS:
33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS dst=" MACSTR
33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" type=%d stype=%d",
33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(data->tx_status.dst),
33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->tx_status.type, data->tx_status.stype);
33811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_AP
33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface == NULL) {
33831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->tx_status.stype == WLAN_FC_STYPE_ACTION)
33861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				offchannel_send_action_tx_status(
33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_s, data->tx_status.dst,
33888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->tx_status.data,
33898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->tx_status.data_len,
33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->tx_status.ack ?
33911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					OFFCHANNEL_SEND_ACTION_SUCCESS :
33921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					OFFCHANNEL_SEND_ACTION_NO_ACK);
33931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
33958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
33961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_AP */
33971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
33988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS pending_dst="
33998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MACSTR, MAC2STR(wpa_s->parent->pending_action_dst));
34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
34018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Catch TX status events for Action frames we sent via group
34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * interface in GO mode.
34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    data->tx_status.stype == WLAN_FC_STYPE_ACTION &&
34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(wpa_s->parent->pending_action_dst,
34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      data->tx_status.dst, ETH_ALEN) == 0) {
34081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			offchannel_send_action_tx_status(
34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->parent, data->tx_status.dst,
34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->tx_status.data,
34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->tx_status.data_len,
34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				data->tx_status.ack ?
34131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				OFFCHANNEL_SEND_ACTION_SUCCESS :
34141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				OFFCHANNEL_SEND_ACTION_NO_ACK);
34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
34171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
34181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_AP
34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		switch (data->tx_status.type) {
34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case WLAN_FC_TYPE_MGMT:
34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ap_mgmt_tx_cb(wpa_s, data->tx_status.data,
34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      data->tx_status.data_len,
34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      data->tx_status.stype,
34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      data->tx_status.ack);
34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case WLAN_FC_TYPE_DATA:
34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ap_tx_status(wpa_s, data->tx_status.dst,
34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     data->tx_status.data,
34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     data->tx_status.data_len,
34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     data->tx_status.ack);
34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
34331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_AP */
34341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
34351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_AP
34361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_EAPOL_TX_STATUS:
34371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ap_eapol_tx_status(wpa_s, data->eapol_tx_status.dst,
34381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   data->eapol_tx_status.data,
34391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   data->eapol_tx_status.data_len,
34401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   data->eapol_tx_status.ack);
34411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
34421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_DRIVER_CLIENT_POLL_OK:
34431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ap_client_poll_ok(wpa_s, data->client_poll.addr);
34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_RX_FROM_UNKNOWN:
34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface == NULL)
34478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
34481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.addr,
34491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       data->rx_from_unknown.wds);
34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
345104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case EVENT_CH_SWITCH:
345204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!data)
345304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
345404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpa_s->ap_iface) {
345504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "AP: Ignore channel switch "
345604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				"event in non-AP mode");
345704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
345804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
345904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
346004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_ap_ch_switch(wpa_s, data->ch_switch.freq,
346104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  data->ch_switch.ht_enabled,
346204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				  data->ch_switch.ch_offset,
346304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				  data->ch_switch.ch_width,
346404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				  data->ch_switch.cf1,
346504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt				  data->ch_switch.cf2);
346604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
3467203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef NEED_AP_MLME
3468203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_RADAR_DETECTED:
3469203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3470203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_radar_detected(wpa_s, &data->dfs_event);
3471203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3472203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_CAC_STARTED:
3473203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3474203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_cac_started(wpa_s, &data->dfs_event);
3475203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3476203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_CAC_FINISHED:
3477203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3478203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_cac_finished(wpa_s, &data->dfs_event);
3479203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3480203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_CAC_ABORTED:
3481203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3482203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_cac_aborted(wpa_s, &data->dfs_event);
3483203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3484203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt	case EVENT_DFS_NOP_FINISHED:
3485203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		if (data)
3486203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt			wpas_event_dfs_cac_nop_finished(wpa_s,
3487203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt							&data->dfs_event);
3488203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt		break;
3489203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* NEED_AP_MLME */
3490c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
349104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case EVENT_RX_MGMT: {
349204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		u16 fc, stype;
349304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		const struct ieee80211_mgmt *mgmt;
349404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3495818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS
3496818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		if (wpa_s->ext_mgmt_frame_handling) {
3497818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			struct rx_mgmt *rx = &data->rx_mgmt;
3498818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			size_t hex_len = 2 * rx->frame_len + 1;
3499818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			char *hex = os_malloc(hex_len);
3500818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			if (hex) {
3501818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt				wpa_snprintf_hex(hex, hex_len,
3502818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt						 rx->frame, rx->frame_len);
3503818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt				wpa_msg(wpa_s, MSG_INFO, "MGMT-RX freq=%d datarate=%u ssi_signal=%d %s",
3504818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt					rx->freq, rx->datarate, rx->ssi_signal,
3505818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt					hex);
3506818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt				os_free(hex);
3507818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			}
3508818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			break;
3509818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		}
3510818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */
3511818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
351204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		mgmt = (const struct ieee80211_mgmt *)
351304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			data->rx_mgmt.frame;
351404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		fc = le_to_host16(mgmt->frame_control);
351504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		stype = WLAN_FC_GET_STYPE(fc);
351604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3517c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_AP
35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface == NULL) {
3519c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
35218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (stype == WLAN_FC_STYPE_PROBE_REQ &&
35228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    data->rx_mgmt.frame_len > 24) {
35238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				const u8 *src = mgmt->sa;
35248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				const u8 *ie = mgmt->u.probe_req.variable;
35258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				size_t ie_len = data->rx_mgmt.frame_len -
35268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					(mgmt->u.probe_req.variable -
35278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 data->rx_mgmt.frame);
352804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpas_p2p_probe_req_rx(
352904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					wpa_s, src, mgmt->da,
353004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					mgmt->bssid, ie, ie_len,
3531a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt					data->rx_mgmt.freq,
353204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					data->rx_mgmt.ssi_signal);
35338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
35348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
3536c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_IBSS_RSN
35376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (wpa_s->current_ssid &&
35386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			    wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
35396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			    stype == WLAN_FC_STYPE_AUTH &&
3540c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			    data->rx_mgmt.frame_len >= 30) {
3541c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				wpa_supplicant_event_ibss_auth(wpa_s, data);
3542c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt				break;
3543c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			}
3544c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_IBSS_RSN */
3545fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
3546fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			if (stype == WLAN_FC_STYPE_ACTION) {
3547fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				wpas_event_rx_mgmt_action(
3548623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt					wpa_s, data->rx_mgmt.frame,
3549623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt					data->rx_mgmt.frame_len,
35506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					data->rx_mgmt.freq,
35516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt					data->rx_mgmt.ssi_signal);
35526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				break;
35536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			}
35546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
35556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			if (wpa_s->ifmsh) {
35566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				mesh_mpm_mgmt_rx(wpa_s, &data->rx_mgmt);
3557fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt				break;
3558fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			}
3559fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "AP: ignore received "
35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"management frame in non-AP mode");
35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3563c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#ifdef CONFIG_AP
35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
356504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
356604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (stype == WLAN_FC_STYPE_PROBE_REQ &&
356704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		    data->rx_mgmt.frame_len > 24) {
356804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			const u8 *ie = mgmt->u.probe_req.variable;
356904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			size_t ie_len = data->rx_mgmt.frame_len -
357004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				(mgmt->u.probe_req.variable -
357104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				 data->rx_mgmt.frame);
357204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
357304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpas_notify_preq(wpa_s, mgmt->sa, mgmt->da,
357404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 mgmt->bssid, ie, ie_len,
357504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 data->rx_mgmt.ssi_signal);
357604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
357704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ap_mgmt_rx(wpa_s, &data->rx_mgmt);
3579c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif /* CONFIG_AP */
35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
358104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_RX_PROBE_REQ:
35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (data->rx_probe_req.sa == NULL ||
35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    data->rx_probe_req.ie == NULL)
35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface) {
35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			hostapd_probe_req_rx(wpa_s->ap_iface->bss[0],
35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     data->rx_probe_req.sa,
35901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					     data->rx_probe_req.da,
35911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					     data->rx_probe_req.bssid,
35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     data->rx_probe_req.ie,
359304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					     data->rx_probe_req.ie_len,
359404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					     data->rx_probe_req.ssi_signal);
35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_probe_req_rx(wpa_s, data->rx_probe_req.sa,
35991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      data->rx_probe_req.da,
36001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      data->rx_probe_req.bssid,
36018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      data->rx_probe_req.ie,
360204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				      data->rx_probe_req.ie_len,
3603a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt				      0,
360404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				      data->rx_probe_req.ssi_signal);
36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_REMAIN_ON_CHANNEL:
36071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
36081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		offchannel_remain_on_channel_cb(
36091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s, data->remain_on_channel.freq,
36101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			data->remain_on_channel.duration);
36111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
36128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_remain_on_channel_cb(
36138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, data->remain_on_channel.freq,
36148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->remain_on_channel.duration);
36158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
36168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_CANCEL_REMAIN_ON_CHANNEL:
36171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
36181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		offchannel_cancel_remain_on_channel_cb(
36191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_s, data->remain_on_channel.freq);
36201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
36218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_cancel_remain_on_channel_cb(
36228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, data->remain_on_channel.freq);
36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_EAPOL_RX:
36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->eapol_rx.data,
36278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					data->eapol_rx.data_len);
36288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
36298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_SIGNAL_CHANGE:
36307dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
36317dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			"above=%d signal=%d noise=%d txrate=%d",
36327dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			data->signal_change.above_threshold,
36337dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			data->signal_change.current_signal,
36347dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			data->signal_change.current_noise,
36357dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			data->signal_change.current_txrate);
36367f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_bss_update_level(wpa_s->current_bss,
36377f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt				     data->signal_change.current_signal);
36388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bgscan_notify_signal_change(
36398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, data->signal_change.above_threshold,
36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->signal_change.current_signal,
36418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->signal_change.current_noise,
36428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->signal_change.current_txrate);
36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
36448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_ENABLED:
36458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled");
36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
36471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_supplicant_update_mac_addr(wpa_s);
3648df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt			if (wpa_s->p2p_mgmt) {
3649df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt				wpa_supplicant_set_state(wpa_s,
3650df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt							 WPA_DISCONNECTED);
3651df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt				break;
3652df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt			}
3653df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt
36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_s->ap_iface) {
36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_set_state(wpa_s,
36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							 WPA_DISCONNECTED);
3658ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				wpa_s->scan_req = NORMAL_SCAN_REQ;
36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_req_scan(wpa_s, 0, 0);
36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else
36618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_set_state(wpa_s,
36628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							 WPA_COMPLETED);
36638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_AP */
36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 0);
36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_DISABLED:
36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled");
367101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt#ifdef CONFIG_P2P
367201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
367301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		    (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group &&
367401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		     wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)) {
367501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			/*
3676ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 * Mark interface disabled if this happens to end up not
3677ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 * being removed as a separate P2P group interface.
3678ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 */
3679ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
3680ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			/*
368101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 * The interface was externally disabled. Remove
368201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 * it assuming an external entity will start a
368301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 * new session if needed.
368401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			 */
3685ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			if (wpa_s->current_ssid &&
3686ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			    wpa_s->current_ssid->p2p_group)
3687ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				wpas_p2p_interface_unavailable(wpa_s);
3688ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			else
3689ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt				wpas_p2p_disconnect(wpa_s);
3690ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			/*
3691ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 * wpa_s instance may have been freed, so must not use
3692ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 * it here anymore.
3693ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt			 */
369401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt			break;
369501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt		}
36966dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		if (wpa_s->p2p_scan_work && wpa_s->global->p2p &&
36976dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		    p2p_in_progress(wpa_s->global->p2p) > 1) {
36986dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt			/* This radio work will be cancelled, so clear P2P
36996dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt			 * state as well.
37006dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt			 */
37016dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt			p2p_stop_find(wpa_s->global->p2p);
37026dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt		}
370301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt#endif /* CONFIG_P2P */
370401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt
37057832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt		if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
37067832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			/*
37077832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			 * Indicate disconnection to keep ctrl_iface events
37087832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			 * consistent.
37097832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			 */
37107832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt			wpa_supplicant_event_disassoc(
37117832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
37127832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt		}
37138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_mark_disassoc(wpa_s);
3714bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		radio_remove_works(wpa_s, NULL, 0);
3715bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt
37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
37178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_CHANNEL_LIST_CHANGED:
37197dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt		wpa_supplicant_update_channel_list(
37207dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt			wpa_s, &data->channel_list_changed);
37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_INTERFACE_UNAVAILABLE:
37238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_interface_unavailable(wpa_s);
37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
37258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_BEST_CHANNEL:
37268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Best channel event received "
37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"(%d %d %d)",
37288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->best_chan.freq_24, data->best_chan.freq_5,
37298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			data->best_chan.freq_overall);
37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->best_24_freq = data->best_chan.freq_24;
37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->best_5_freq = data->best_chan.freq_5;
37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->best_overall_freq = data->best_chan.freq_overall;
37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_update_best_channels(wpa_s, data->best_chan.freq_24,
37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      data->best_chan.freq_5,
37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      data->best_chan.freq_overall);
37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_UNPROT_DEAUTH:
37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_unprot_deauth(wpa_s,
37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   &data->unprot_deauth);
37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_UNPROT_DISASSOC:
37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_event_unprot_disassoc(wpa_s,
37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     &data->unprot_disassoc);
37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_STATION_LOW_ACK:
37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->ap_iface && data)
37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			hostapd_event_sta_low_ack(wpa_s->ap_iface->bss[0],
37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  data->low_ack.addr);
37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
37511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TDLS
37521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (data)
375343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt			wpa_tdls_disable_unreachable_link(wpa_s->wpa,
375443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt							  data->low_ack.addr);
37551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TDLS */
37568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
37578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EVENT_IBSS_PEER_LOST:
37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ibss_rsn_stop(wpa_s->ibss_rsn, data->ibss_peer_lost.peer);
37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
37621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_DRIVER_GTK_REKEY:
37631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (os_memcmp(data->driver_gtk_rekey.bssid,
37641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			      wpa_s->bssid, ETH_ALEN))
37651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			break;
37661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!wpa_s->wpa)
37671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			break;
37681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_sm_update_replay_ctr(wpa_s->wpa,
37691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					 data->driver_gtk_rekey.replay_ctr);
37701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
37711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_SCHED_SCAN_STOPPED:
37721846323989242844f0e857458a8939fa5836429cDmitry Shmidt		wpa_s->pno = 0;
37731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->sched_scanning = 0;
3774af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt		resched = wpa_s->scanning;
37751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_supplicant_notify_scanning(wpa_s, 0);
37761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
37771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
37781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			break;
37791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
37801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/*
37811846323989242844f0e857458a8939fa5836429cDmitry Shmidt		 * Start a new sched scan to continue searching for more SSIDs
37821846323989242844f0e857458a8939fa5836429cDmitry Shmidt		 * either if timed out or PNO schedule scan is pending.
37831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 */
37849866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt		if (wpa_s->sched_scan_timed_out) {
37859866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt			wpa_supplicant_req_sched_scan(wpa_s);
37869866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt		} else if (wpa_s->pno_sched_pending) {
37879866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt			wpa_s->pno_sched_pending = 0;
37889866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt			wpas_start_pno(wpa_s);
3789af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt		} else if (resched) {
3790af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 0);
37911846323989242844f0e857458a8939fa5836429cDmitry Shmidt		}
37921846323989242844f0e857458a8939fa5836429cDmitry Shmidt
37931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
37941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	case EVENT_WPS_BUTTON_PUSHED:
37951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_WPS
37961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpas_wps_start_pbc(wpa_s, NULL, 0);
37971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_WPS */
37981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		break;
3799cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	case EVENT_AVOID_FREQUENCIES:
3800cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_supplicant_notify_avoid_freq(wpa_s, data);
3801cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		break;
3802f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	case EVENT_CONNECT_FAILED_REASON:
3803f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_AP
3804f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		if (!wpa_s->ap_iface || !data)
3805f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			break;
3806f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		hostapd_event_connect_failed_reason(
3807f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			wpa_s->ap_iface->bss[0],
3808f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			data->connect_failed_reason.addr,
3809f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			data->connect_failed_reason.code);
3810f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_AP */
3811f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		break;
38126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	case EVENT_NEW_PEER_CANDIDATE:
38136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH
38146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (!wpa_s->ifmsh || !data)
38156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			break;
38166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		wpa_mesh_notify_peer(wpa_s, data->mesh_peer.peer,
38176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				     data->mesh_peer.ies,
38186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				     data->mesh_peer.ie_len);
38196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */
38206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		break;
38218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
38228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
38238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3826