[06/25] Store the VHT Operation element of an associated STA

Message ID 20180806194643.1328-7-Mathy.Vanhoef@cs.kuleuven.be
State Accepted
Headers show
Series
  • Add support for Operating Channel Validation (OCV)
Related show

Commit Message

Mathy Vanhoef Aug. 6, 2018, 7:46 p.m.
APs and mesh peers use the VHT Operation element to advertise certain
channel properties (e.g. the bandwidth of the channel). Save this
information element so we can later access this information.

Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
---
 src/ap/ieee802_11.c       |  4 ++++
 src/ap/ieee802_11.h       |  2 ++
 src/ap/ieee802_11_vht.c   | 23 +++++++++++++++++++++++
 src/ap/sta_info.c         |  1 +
 src/ap/sta_info.h         |  1 +
 wpa_supplicant/mesh_mpm.c |  1 +
 6 files changed, 32 insertions(+)

Patch

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index d7e7210f7..543058e01 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2482,6 +2482,10 @@  static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
 		if (resp != WLAN_STATUS_SUCCESS)
 			return resp;
 
+		resp = copy_sta_vht_oper(hapd, sta, elems.vht_operation);
+		if (resp != WLAN_STATUS_SUCCESS)
+			return resp;
+
 		resp = set_sta_vht_opmode(hapd, sta, elems.vht_opmode_notif);
 		if (resp != WLAN_STATUS_SUCCESS)
 			return resp;
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index 2f3b4da8e..3d93be299 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -80,6 +80,8 @@  void ht40_intolerant_add(struct hostapd_iface *iface, struct sta_info *sta);
 void ht40_intolerant_remove(struct hostapd_iface *iface, struct sta_info *sta);
 u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
 		       const u8 *vht_capab);
+u16 copy_sta_vht_oper(struct hostapd_data *hapd, struct sta_info *sta,
+		      const u8 *vht_oper);
 u16 set_sta_vht_opmode(struct hostapd_data *hapd, struct sta_info *sta,
 		       const u8 *vht_opmode);
 void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c
index 8d0662078..0a270a34c 100644
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -357,6 +357,29 @@  u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
 }
 
 
+u16 copy_sta_vht_oper(struct hostapd_data *hapd, struct sta_info *sta,
+		      const u8 *vht_oper)
+{
+	if (!vht_oper) {
+		os_free(sta->vht_operation);
+		sta->vht_operation = NULL;
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	if (sta->vht_operation == NULL) {
+		sta->vht_operation =
+			os_zalloc(sizeof(struct ieee80211_vht_operation));
+		if (sta->vht_operation == NULL)
+			return WLAN_STATUS_UNSPECIFIED_FAILURE;
+	}
+
+	os_memcpy(sta->vht_operation, vht_oper,
+		  sizeof(struct ieee80211_vht_operation));
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+
 u16 copy_sta_vendor_vht(struct hostapd_data *hapd, struct sta_info *sta,
 			const u8 *ie, size_t len)
 {
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 179cf43b6..d0f143890 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -328,6 +328,7 @@  void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 
 	os_free(sta->ht_capabilities);
 	os_free(sta->vht_capabilities);
+	os_free(sta->vht_operation);
 	hostapd_free_psk_list(sta->psk);
 	os_free(sta->identity);
 	os_free(sta->radius_cui);
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 9cac6f157..48365822e 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -162,6 +162,7 @@  struct sta_info {
 
 	struct ieee80211_ht_capabilities *ht_capabilities;
 	struct ieee80211_vht_capabilities *vht_capabilities;
+	struct ieee80211_vht_operation *vht_operation;
 	u8 vht_opmode;
 
 #ifdef CONFIG_IEEE80211W
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index d166cfeec..fd5b90a42 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -698,6 +698,7 @@  static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
 
 #ifdef CONFIG_IEEE80211AC
 	copy_sta_vht_capab(data, sta, elems->vht_capabilities);
+	copy_sta_vht_oper(data, sta, elems->vht_operation);
 	set_sta_vht_opmode(data, sta, elems->vht_opmode_notif);
 #endif /* CONFIG_IEEE80211AC */