Cumulative patch from commit f89c32e63f71e66d7b55e284016762b603ae02db

f89c32e Android: Fix max number of sched scan SSIDs based on driver capability
f1a5a34 binder: Implement interface add/remove methods
7b4bbb9 binder: Add binder skeletal code for Android
5914ebf Remove struct ieee80211_mgmt::u.probe_req
094e949 atheros: Do not use struct ieee80211_mgmt::u.probe_req
c01120a wpa_supplicant: Do not use struct ieee80211_mgmt::u.probe_req
e1b9962 AP: Do not use struct ieee80211_mgmt::u.probe_req
5cd317d Do not clear PMKSA entry or EAP session cache if config does not change
f933216 Revert "Assign QCA vendor command and attribute for Tx/Rx aggregation"
bde9a4e Comment out UDP/UNIX socket code from common ctrl_iface based on build
a6fbff2 Fix CONFIG_CTRL_IFACE=udp6/udp6-remote builds
0741c48 SAE: Check SHA256-PRF operation result
ea86a34 SAE: Remove dead code in FFC pwd-value derivation
87faf1f nl80211: Fix libnl-tiny build with CONFIG_LIBNL20=y
31afdd2 Use TIOCOUTQ instead of SIOCOUTQ to avoid need for linux/sockios.h
6d07e76 wlantest: Use local ETH_P_IP define instead of linux/if_ether.h
795abc8 Drop USE_KERNEL_HEADERS define
9b7cd57 Use a separate header file for Linux bridge interface definitions
c815fab Use own header file for defining Linux VLAN kernel interface
81606ab vlan: Fix musl libc conflict with Linux kernel headers
f347429 P2P: Fix persistent group for 60 GHz networks
e868599 vlan: Move if_nametoindex() use out of vlan_init.c
7c03c08 vlan: Move ifconfig helpers to a separate file
59d6390 vlan: Move CONFIG_FULL_DYNAMIC_VLAN functionality into a separate file
0fe28dd vlan: Remove unnecessary header includes from netlink implementation
84d6755 vlan: Clean up netlink vs. ioctl API implementation
cb38bc8 vlan: Fix musl build error
954e10e Make it a bit easier to roam from 2.4 GHz to 5 GHz within ESS
585141b Fix a typo in a comment
1126c07 nl80211: Ignore deauth/disassoc event during Connect reassociation
6a5ee81 Include previous BSSID in connection request to indicate reassociation
00c3c4a nl80211: Add NL80211_ATTR_PREV_BSSID with Connect command
cbc3d6f WNM: Verify BSS TM target match against the current network profile
8854f90 mesh: Simplify wpa_auth_pmksa_set_to_sm()
32d4fe9 privsep: Fix a compiler warning on unsigned/signed comparison
2e997ee Add interface matching support with -M, guarded by CONFIG_MATCH_IFACE
45e3fc7 Find correct driver for interface additions/removals
9037702 wpa_supplicant: Fix CONFIG_IBSS_RSN=y build without CONFIG_AP=y
5ae65de wpa_supplicant: Fix p2p_group_add when UDP-based ctrl_iface is used
24bce46 FST: Fix a compiler warning
e567c58 Fix nfc_pw_token build with CONFIG_FST=y
d774c46 mesh: Use appropriate BLOCKED state duration
9f2cf23 mesh: Add support for PMKSA caching
4c522c7 PMKSA: Flush AP/mesh PMKSA cache by PMKSA_FLUSH command
b8daac1 PMKSA: Show AP/mesh PMKSA list in PMKSA command
2604edb mesh: Add MESH_PEER_ADD command
e174ef3 mesh: Add MESH_PEER_REMOVE command
f7648c8 P2P: Advertise IP Address Allocation only if it is enabled on GO
7f46ad9 BSD: Only down the interface once we are sure we can work with it
192964d Handle OSEN IE in Assoc Request info if req_ies exists
29eddc3 nl80211: Fix error path in if_indices_reason reallocation
ee298f1 nl80211: Do not add NL80211_ATTR_SMPS_MODE attribute if HT is disabled
4ca16b5 Assign QCA vendor command and attribute for Tx/Rx aggregation
64ce590 libxml2: Check for xmlDocDumpFormatMemory() error case
8b827c3 BoringSSL: Keep static analyzers happier with X509_get0_pubkey_bitstr()
42a9553 hs20-osu-client: Fix pol_upd command line parsing
ec1eae8 hs20-osu-client: Remove dead code from sub_rem command line parsing
c3dc68e Do not invalidate EAP session cache on all network block parameter changes
9231c24 wlantest: Fix bip_protect() memory allocation
c6c29be Interworking: Add credential realm to EAP-TLS identity

Change-Id: I870f325171d00fed9c4fcd82a695fe5e2efee792
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index a84ba2d..6b3a2c0 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1346,6 +1346,7 @@
 	struct wpa_bss *current_bss = NULL;
 #ifndef CONFIG_NO_ROAMING
 	int min_diff;
+	int to_5ghz;
 #endif /* CONFIG_NO_ROAMING */
 
 	if (wpa_s->reassociate)
@@ -1401,7 +1402,10 @@
 		return 1;
 	}
 
-	if (current_bss->level < 0 && current_bss->level > selected->level) {
+	to_5ghz = selected->freq > 4000 && current_bss->freq < 4000;
+
+	if (current_bss->level < 0 &&
+	    current_bss->level > selected->level + to_5ghz * 2) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
 			"signal level");
 		return 0;
@@ -1420,6 +1424,13 @@
 		else
 			min_diff = 5;
 	}
+	if (to_5ghz) {
+		/* Make it easier to move to 5 GHz band */
+		if (min_diff > 2)
+			min_diff -= 2;
+		else
+			min_diff = 0;
+	}
 	if (abs(current_bss->level - selected->level) < min_diff) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - too small difference "
 			"in signal level");
@@ -1984,6 +1995,8 @@
 		}
 		if ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
 		     (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
+		    (p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
+		     (os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
 		    (p[0] == WLAN_EID_RSN && p[1] >= 2)) {
 			if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
 				break;
@@ -2760,6 +2773,13 @@
 		}
 #endif /* CONFIG_P2P */
 
+#ifdef CONFIG_MATCH_IFACE
+		if (wpa_s->matched) {
+			wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
+			break;
+		}
+#endif /* CONFIG_MATCH_IFACE */
+
 #ifdef CONFIG_TERMINATE_ONLASTIF
 		/* check if last interface */
 		if (!any_interfaces(wpa_s->global->ifaces))
@@ -3690,12 +3710,14 @@
 #endif /* CONFIG_AP */
 #ifdef CONFIG_P2P
 			if (stype == WLAN_FC_STYPE_PROBE_REQ &&
-			    data->rx_mgmt.frame_len > 24) {
+			    data->rx_mgmt.frame_len > IEEE80211_HDRLEN) {
 				const u8 *src = mgmt->sa;
-				const u8 *ie = mgmt->u.probe_req.variable;
-				size_t ie_len = data->rx_mgmt.frame_len -
-					(mgmt->u.probe_req.variable -
-					 data->rx_mgmt.frame);
+				const u8 *ie;
+				size_t ie_len;
+
+				ie = data->rx_mgmt.frame + IEEE80211_HDRLEN;
+				ie_len = data->rx_mgmt.frame_len -
+					IEEE80211_HDRLEN;
 				wpas_p2p_probe_req_rx(
 					wpa_s, src, mgmt->da,
 					mgmt->bssid, ie, ie_len,
@@ -3735,11 +3757,12 @@
 		}
 
 		if (stype == WLAN_FC_STYPE_PROBE_REQ &&
-		    data->rx_mgmt.frame_len > 24) {
-			const u8 *ie = mgmt->u.probe_req.variable;
-			size_t ie_len = data->rx_mgmt.frame_len -
-				(mgmt->u.probe_req.variable -
-				 data->rx_mgmt.frame);
+		    data->rx_mgmt.frame_len > IEEE80211_HDRLEN) {
+			const u8 *ie;
+			size_t ie_len;
+
+			ie = data->rx_mgmt.frame + IEEE80211_HDRLEN;
+			ie_len = data->rx_mgmt.frame_len - IEEE80211_HDRLEN;
 
 			wpas_notify_preq(wpa_s, mgmt->sa, mgmt->da,
 					 mgmt->bssid, ie, ie_len,
@@ -4010,3 +4033,43 @@
 		break;
 	}
 }
+
+
+void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
+				 union wpa_event_data *data)
+{
+	struct wpa_supplicant *wpa_s;
+
+	if (event != EVENT_INTERFACE_STATUS)
+		return;
+
+	wpa_s = wpa_supplicant_get_iface(ctx, data->interface_status.ifname);
+	if (wpa_s && wpa_s->driver->get_ifindex) {
+		unsigned int ifindex;
+
+		ifindex = wpa_s->driver->get_ifindex(wpa_s->drv_priv);
+		if (ifindex != data->interface_status.ifindex) {
+			wpa_dbg(wpa_s, MSG_DEBUG,
+				"interface status ifindex %d mismatch (%d)",
+				ifindex, data->interface_status.ifindex);
+			return;
+		}
+	}
+#ifdef CONFIG_MATCH_IFACE
+	else if (data->interface_status.ievent == EVENT_INTERFACE_ADDED) {
+		struct wpa_interface *wpa_i;
+
+		wpa_i = wpa_supplicant_match_iface(
+			ctx, data->interface_status.ifname);
+		if (!wpa_i)
+			return;
+		wpa_s = wpa_supplicant_add_iface(ctx, wpa_i, NULL);
+		os_free(wpa_i);
+		if (wpa_s)
+			wpa_s->matched = 1;
+	}
+#endif /* CONFIG_MATCH_IFACE */
+
+	if (wpa_s)
+		wpa_supplicant_event(wpa_s, event, data);
+}