Accumulative patch from commit  cc03d0fef3bf5913f8e11b7e998c10bf36a3c07f

  Author: Amar Singhal <asinghal@qca.qualcomm.com>
  Date:   Wed Feb 6 00:31:34 2013 +0200
    Add "BSS LAST ..." command

 - Add "BSS LAST ..." command
 - HS 2.0: Fix IE buffer length for extra scan IEs
 - TDLS: Several fixes
 - P2P: Fix P2P-GROUP-STARTED event for p2p_connect-join
 - P2P: Fix Action frame processing if Interworking is enabled
 - wpa_supplicant: Fix access to the freed memory when removing all networks
 - Add driver for OpenBSD net80211 layer
 - Make wpas_select_network_from_last_scan() static
 - wpa_supplicant: Implement fast-associate on SelectNetwork
 - Update scan interval gracefully
 - eloop: Add a timer cancel that returns the remaining time
 - nl80211: Do not use void pointer for driver_ops used internally
 - hostapd: Fix crash when scan fails

Change-Id: I083747a0b1f7000730a9ab3ea80f3ee7e6247181
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 2b62e6b..d1b58eb 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -44,6 +44,9 @@
 #include "interworking.h"
 
 
+static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s);
+
+
 static int wpas_temp_disabled(struct wpa_supplicant *wpa_s,
 			      struct wpa_ssid *ssid)
 {
@@ -1109,8 +1112,8 @@
 						   data ? &data->scan_info :
 						   NULL, 1);
 	if (scan_res == NULL) {
-		if ((wpa_s->conf->ap_scan == 2 || ap) ||
-		    (wpa_s->scan_res_handler == scan_only_handler))
+		if (wpa_s->conf->ap_scan == 2 || ap ||
+		    wpa_s->scan_res_handler == scan_only_handler)
 			return -1;
 		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results - try "
 			"scanning again");
@@ -1205,7 +1208,7 @@
 }
 
 
-int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s)
+static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s)
 {
 	struct wpa_bss *selected;
 	struct wpa_ssid *ssid = NULL;
@@ -1348,6 +1351,26 @@
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 
 
+int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_NO_SCAN_PROCESSING
+	return -1;
+#else /* CONFIG_NO_SCAN_PROCESSING */
+	struct os_time now;
+
+	if (wpa_s->last_scan_res_used <= 0)
+		return -1;
+
+	os_get_time(&now);
+	if (now.sec - wpa_s->last_scan.sec > 5) {
+		wpa_printf(MSG_DEBUG, "Fast associate: Old scan results");
+		return -1;
+	}
+
+	return wpas_select_network_from_last_scan(wpa_s);
+#endif /* CONFIG_NO_SCAN_PROCESSING */
+}
+
 #ifdef CONFIG_WNM
 
 static void wnm_bss_keep_alive(void *eloop_ctx, void *sock_ctx)
@@ -2178,10 +2201,14 @@
 		return;
 	switch (data->tdls.oper) {
 	case TDLS_REQUEST_SETUP:
-		wpa_tdls_start(wpa_s->wpa, data->tdls.peer);
+		wpa_tdls_remove(wpa_s->wpa, data->tdls.peer);
+		if (wpa_tdls_is_external_setup(wpa_s->wpa))
+			wpa_tdls_start(wpa_s->wpa, data->tdls.peer);
+		else
+			wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, data->tdls.peer);
 		break;
 	case TDLS_REQUEST_TEARDOWN:
-		wpa_tdls_send_teardown(wpa_s->wpa, data->tdls.peer,
+		wpa_tdls_teardown_link(wpa_s->wpa, data->tdls.peer,
 				       data->tdls.reason_code);
 		break;
 	}