UPSTREAM: hostapd: Save RM enabled capability of station

Save RM enabled capability element of an associating station if radio
measurement is supported in its capability field.

[cherry pick from 629e1804da3bb6eed347b51922fc2fe6aa05f2e5]
[git remote add hostap git://w1.fi/srv/git/hostap.git]

BUG=b:36055223
TEST=1) Manually verified the neighbor report functionality by sending a
     neighbor report request from a STA and receiving response from AP.
     2) stress tested by running through  connect/disconnect/download
        from 7 different stations and observed no regression.

Change-Id: I7eb089cdf8a266718c428d4f54220f2d61850f17
Reviewed-on: https://chromium-review.googlesource.com/456660
Commit-Ready: NARAYANRADDI MASTI <nmasti@google.com>
Tested-by: NARAYANRADDI MASTI <nmasti@google.com>
Reviewed-by: Srinivasa duvvuri <sduvvuri@chromium.org>
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 045417d..1e426d8 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1806,6 +1806,12 @@
 		sta->mb_ies = NULL;
 #endif /* CONFIG_FST */
 
+	if ((sta->capability & WLAN_CAPABILITY_RADIO_MEASUREMENT) &&
+		elems.rrm_enabled &&
+		elems.rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
+		os_memcpy(sta->rrm_enabled_capa, elems.rrm_enabled,
+			sizeof(sta->rrm_enabled_capa));
+
 	return WLAN_STATUS_SUCCESS;
 }
 
@@ -2090,6 +2096,12 @@
 		goto fail;
 	}
 
+	/*
+	 * sta->capability is used in check_assoc_ies() for RRM enabled
+	 * capability element.
+	 */
+	sta->capability = capab_info;
+
 	/* followed by SSID and Supported rates; and HT capabilities if 802.11n
 	 * is used */
 	resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
@@ -2119,7 +2131,6 @@
 		goto fail;
 	}
 
-	sta->capability = capab_info;
 	sta->listen_interval = listen_interval;
 
 	if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 1edcdf7..9b6679f 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -181,6 +181,7 @@
 	char probe_ie_taxonomy[TAXONOMY_STRING_LEN];
 	char assoc_ie_taxonomy[TAXONOMY_STRING_LEN];
 #endif /* CONFIG_CLIENT_TAXONOMY */
+	u8 rrm_enabled_capa[5];
 };
 
 
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 41c6fb8..050c72e 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -409,6 +409,8 @@
 		case WLAN_EID_RRM_ENABLED_CAPABILITIES:
 			elems->rrm_enabled_capab = pos;
 			elems->rrm_enabled_capab_len = elen;
+			elems->rrm_enabled = pos;
+			elems->rrm_enabled_len = elen;
 			break;
 		case WLAN_EID_MIC:
 			elems->mic = pos;
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index 0d9dd49..d932e08 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -62,6 +62,7 @@
 	const u8 *pref_freq_list;
 	const u8 *google_debug_dialog_token;
 	const u8 *google_mesh_group_privacy_mode;
+	const u8 *rrm_enabled;
 
 	u8 ssid_len;
 	u8 supp_rates_len;
@@ -94,6 +95,7 @@
 	u8 pref_freq_list_len;
 	u8 google_debug_dialog_token_len;
 	u8 google_mesh_group_privacy_mode_len;
+	u8 rrm_enabled_len;
 	struct mb_ies_info mb_ies;
 };