From ad20a1367f8dc2232521c025906990f21e9e12d1 Mon Sep 17 00:00:00 2001 From: Mathy Vanhoef Date: Mon, 6 Aug 2018 15:46:24 -0400 Subject: [PATCH] Store the VHT Operation element of an associated STA 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 --- 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(+) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index fce5781c2..41de3f6c1 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2485,6 +2485,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..54ee080a4 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) { + sta->vht_operation = + os_zalloc(sizeof(struct ieee80211_vht_operation)); + if (!sta->vht_operation) + 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 eafb0af7b..75ee0f775 100644 --- a/wpa_supplicant/mesh_mpm.c +++ b/wpa_supplicant/mesh_mpm.c @@ -699,6 +699,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 */