From cdd71e307eb5978b0de8bf14eddd6773ad28bf03 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sun, 21 Nov 2010 21:24:20 +0200
Subject: [PATCH] wlantest: Add per-STA counter for (Re)AssocResp comeback
 frames

---
 wlantest/rx_mgmt.c       | 40 ++++++++++++++++++++++++++++++++++++++++
 wlantest/wlantest_cli.c  |  2 ++
 wlantest/wlantest_ctrl.h |  2 ++
 3 files changed, 44 insertions(+)

diff --git a/wlantest/rx_mgmt.c b/wlantest/rx_mgmt.c
index e9ab33035..4921d8d56 100644
--- a/wlantest/rx_mgmt.c
+++ b/wlantest/rx_mgmt.c
@@ -290,6 +290,26 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
 		   aid & 0x3fff);
 
+	if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
+		struct ieee802_11_elems elems;
+		const u8 *ies = mgmt->u.assoc_resp.variable;
+		size_t ies_len = len - (mgmt->u.assoc_resp.variable - data);
+		if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
+		    ParseFailed) {
+			wpa_printf(MSG_INFO, "Failed to parse IEs in "
+				   "AssocResp from " MACSTR,
+				   MAC2STR(mgmt->sa));
+		} else if (elems.timeout_int == 0 ||
+			   elems.timeout_int_len != 5) {
+			wpa_printf(MSG_INFO, "No valid Timeout Interval IE in "
+				   "AssocResp (status=30) from " MACSTR,
+				   MAC2STR(mgmt->sa));
+		} else {
+			sta->counters[
+				WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK]++;
+		}
+	}
+
 	if (status)
 		return;
 
@@ -399,6 +419,26 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
 		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
 		   aid & 0x3fff);
 
+	if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
+		struct ieee802_11_elems elems;
+		const u8 *ies = mgmt->u.reassoc_resp.variable;
+		size_t ies_len = len - (mgmt->u.reassoc_resp.variable - data);
+		if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
+		    ParseFailed) {
+			wpa_printf(MSG_INFO, "Failed to parse IEs in "
+				   "ReassocResp from " MACSTR,
+				   MAC2STR(mgmt->sa));
+		} else if (elems.timeout_int == 0 ||
+			   elems.timeout_int_len != 5) {
+			wpa_printf(MSG_INFO, "No valid Timeout Interval IE in "
+				   "ReassocResp (status=30) from " MACSTR,
+				   MAC2STR(mgmt->sa));
+		} else {
+			sta->counters[
+				WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK]++;
+		}
+	}
+
 	if (status)
 		return;
 
diff --git a/wlantest/wlantest_cli.c b/wlantest/wlantest_cli.c
index 290aa2c0b..301d6f803 100644
--- a/wlantest/wlantest_cli.c
+++ b/wlantest/wlantest_cli.c
@@ -462,6 +462,8 @@ static const struct sta_counters sta_counters[] = {
 	{ "invalid_saqueryresp_rx",
 	  WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX },
 	{ "ping_ok", WLANTEST_STA_COUNTER_PING_OK },
+	{ "assocresp_comeback", WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK },
+	{ "reassocresp_comeback", WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK },
 	{ NULL, 0 }
 };
 
diff --git a/wlantest/wlantest_ctrl.h b/wlantest/wlantest_ctrl.h
index a6de9acae..eeaa5f94d 100644
--- a/wlantest/wlantest_ctrl.h
+++ b/wlantest/wlantest_ctrl.h
@@ -86,6 +86,8 @@ enum wlantest_sta_counter {
 	WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_TX,
 	WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX,
 	WLANTEST_STA_COUNTER_PING_OK,
+	WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK,
+	WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK,
 	NUM_WLANTEST_STA_COUNTER
 };