Accumulative patch from commit 17b8995cf5813d7c027cd7a6884700e791d72392

17b8995 Interworking: Try to use same BSS entry for storing GAS results
3db5439 Optimize Extended Capabilities element to be of minimal length
8cd6b7b hostapd/wpa_s: Use driver's extended capabilities
acb5464 Add ctrl_iface command FLUSH for clearing wpa_supplicant state
97236ce WPS: Skip rescanning after provisioning if AP was configured
4342326 Add ignore_old_scan_res configuration parameter
9599ccc WPS: Clear after_wps on new WPS connection
702621e WPS: Use latest updated BSS entry if multiple BSSID matches found
ab547b5 WPS: Add more helpful debug for invalid WPS_REG command parsing
a679c0f WPS: Allow hostapd process to control independent WPS interfaces
ccdff94 WPS AP: Add support for reconfiguration with in-memory config
8970bae nl80211: Use nla_nest_start/end instead of nla_put_nested
558d69e P2P: Omit P2P Group Info in case of no connected peers
65a32cd AP: Fix infinite loop in WPA state machine when out of random bytes
a5f61b2 Fix OLBC non-HT AP detection to check channel
69554d7 ap_list: Remove unused functions
08c99ca ap_list: Remove unused iteration list pointers
6b16917 ap_list: Remove unused fields
66f1f75 P2P: Fix provision discovery response handling in some cases
2f9b66d Extend ROAM command to handle multiple SSIDs per BSS

Change-Id: I46002b1d3bbf6e376c2ae09bcb2c824c54805bbd
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 1b1b5f7..603ce91 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -84,6 +84,10 @@
 	    !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
 		int disabled = wpa_s->current_ssid->disabled;
 		unsigned int freq = wpa_s->assoc_freq;
+		struct wpa_bss *bss;
+		struct wpa_ssid *ssid = NULL;
+		int use_fast_assoc = 0;
+
 		wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - "
 			   "try to associate with the received credential "
 			   "(freq=%u)", freq);
@@ -98,7 +102,26 @@
 		wpa_s->wps_freq = freq;
 		wpa_s->normal_scans = 0;
 		wpa_s->reassociate = 1;
-		wpa_supplicant_req_scan(wpa_s, 0, 0);
+
+		wpa_printf(MSG_DEBUG, "WPS: Checking whether fast association "
+			   "without a new scan can be used");
+		bss = wpa_supplicant_pick_network(wpa_s, &ssid);
+		if (bss) {
+			struct wpabuf *wps;
+			struct wps_parse_attr attr;
+
+			wps = wpa_bss_get_vendor_ie_multi(bss,
+							  WPS_IE_VENDOR_TYPE);
+			if (wps && wps_parse_msg(wps, &attr) == 0 &&
+			    attr.wps_state &&
+			    *attr.wps_state == WPS_STATE_CONFIGURED)
+				use_fast_assoc = 1;
+			wpabuf_free(wps);
+		}
+
+		if (!use_fast_assoc ||
+		    wpa_supplicant_fast_associate(wpa_s) != 1)
+			wpa_supplicant_req_scan(wpa_s, 0, 0);
 		return 1;
 	}
 
@@ -871,9 +894,10 @@
 	struct wpa_ssid *ssid;
 	struct wpa_bss *bss;
 
+	wpa_s->after_wps = 0;
 	wpa_s->known_wps_freq = 0;
 	if (bssid) {
-		bss = wpa_bss_get_bssid(wpa_s, bssid);
+		bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
 		if (bss && bss->freq > 0) {
 			wpa_s->known_wps_freq = 1;
 			wpa_s->wps_freq = bss->freq;