[PATCH v2 2/2] ANQP/hostapd: Add more data to the ANQP RNR response.
sharadanandk at gmail.com
sharadanandk at gmail.com
Tue Feb 8 08:59:31 PST 2022
From: Sharadanand Karanjkar <skaranjkar at datto.com>
Adding more data apart from BSSID, Channel number -
- SSID
- HE Capabilities
- HE Operations
- HT Capabilities.
- HT Operations.
- Load BSS.
Signed-off-by: Sharadanand Karanjkar <skaranjkar at datto.com>
---
Changes to PATCHv1:
- Fixing white space errors.
---
src/ap/beacon.c | 8 +--
src/ap/ieee802_11.c | 4 +-
src/ap/ieee802_11.h | 4 +-
src/ap/ieee802_11_he.c | 33 ++++++++---
src/ap/neighbor_db.c | 111 ++++++++++++++++++++++++++++++++++-
src/common/ieee802_11_defs.h | 5 ++
wpa_supplicant/mesh_mpm.c | 4 +-
7 files changed, 148 insertions(+), 21 deletions(-)
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 8cd1c4170..3004834d5 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -578,8 +578,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
- pos = hostapd_eid_he_capab(hapd, pos, IEEE80211_MODE_AP);
- pos = hostapd_eid_he_operation(hapd, pos);
+ pos = hostapd_eid_he_capab(hapd, pos, IEEE80211_MODE_AP, false);
+ pos = hostapd_eid_he_operation(hapd, pos, false);
pos = hostapd_eid_spatial_reuse(hapd, pos);
pos = hostapd_eid_he_mu_edca_parameter_set(hapd, pos);
pos = hostapd_eid_he_6ghz_band_cap(hapd, pos);
@@ -1601,8 +1601,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
tailpos = hostapd_eid_he_capab(hapd, tailpos,
- IEEE80211_MODE_AP);
- tailpos = hostapd_eid_he_operation(hapd, tailpos);
+ IEEE80211_MODE_AP, false);
+ tailpos = hostapd_eid_he_operation(hapd, tailpos, false);
tailpos = hostapd_eid_spatial_reuse(hapd, tailpos);
tailpos = hostapd_eid_he_mu_edca_parameter_set(hapd, tailpos);
tailpos = hostapd_eid_he_6ghz_band_cap(hapd, tailpos);
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index f63292537..581fd0007 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -5149,8 +5149,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
#ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
- p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP);
- p = hostapd_eid_he_operation(hapd, p);
+ p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP, false);
+ p = hostapd_eid_he_operation(hapd, p, false);
p = hostapd_eid_spatial_reuse(hapd, p);
p = hostapd_eid_he_mu_edca_parameter_set(hapd, p);
p = hostapd_eid_he_6ghz_band_cap(hapd, p);
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index c59ad5e38..4d7677e2a 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -59,8 +59,8 @@ u8 * hostapd_eid_vendor_vht(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid,
- enum ieee80211_op_mode opmode);
-u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid);
+ enum ieee80211_op_mode opmode, bool forRnr);
+u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid, bool forRnr);
u8 * hostapd_eid_he_mu_edca_parameter_set(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_spatial_reuse(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_he_6ghz_band_cap(struct hostapd_data *hapd, u8 *eid);
diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
index 6cd6c90dc..010e0f4ed 100644
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -81,7 +81,7 @@ static int ieee80211_invalid_he_cap_size(const u8 *buf, size_t len)
u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid,
- enum ieee80211_op_mode opmode)
+ enum ieee80211_op_mode opmode, bool for_rnr)
{
struct ieee80211_he_capabilities *cap;
struct hostapd_hw_modes *mode = hapd->iface->current_mode;
@@ -115,9 +115,17 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid,
ie_size += mcs_nss_size + ppet_size;
- *pos++ = WLAN_EID_EXTENSION;
- *pos++ = 1 + ie_size;
- *pos++ = WLAN_EID_EXT_HE_CAPABILITIES;
+ if(for_rnr)
+ {
+ *pos++ = WMM_NEIGHBOR_HE_CAPB;
+ *pos++ = ie_size;
+ }
+ else
+ {
+ *pos++ = WLAN_EID_EXTENSION;
+ *pos++ = 1 + ie_size;
+ *pos++ = WLAN_EID_EXT_HE_CAPABILITIES;
+ }
cap = (struct ieee80211_he_capabilities *) pos;
os_memset(cap, 0, sizeof(*cap));
@@ -161,7 +169,7 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid,
}
-u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid)
+u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid, bool for_rnr)
{
struct ieee80211_he_operation *oper;
u8 *pos = eid;
@@ -173,10 +181,17 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid)
if (is_6ghz_op_class(hapd->iconf->op_class))
oper_size += 5;
-
- *pos++ = WLAN_EID_EXTENSION;
- *pos++ = 1 + oper_size;
- *pos++ = WLAN_EID_EXT_HE_OPERATION;
+ if(for_rnr)
+ {
+ *pos++ = WMM_NEIGHBOR_HE_OPER;
+ *pos++ = oper_size;
+ }
+ else
+ {
+ *pos++ = WLAN_EID_EXTENSION;
+ *pos++ = 1 + oper_size;
+ *pos++ = WLAN_EID_EXT_HE_OPERATION;
+ }
oper = (struct ieee80211_he_operation *) pos;
os_memset(oper, 0, sizeof(*oper));
diff --git a/src/ap/neighbor_db.c b/src/ap/neighbor_db.c
index 229edd2a9..8013285ca 100644
--- a/src/ap/neighbor_db.c
+++ b/src/ap/neighbor_db.c
@@ -217,6 +217,26 @@ static enum nr_chan_width hostapd_get_nr_chan_width(struct hostapd_data *hapd,
}
#endif /* NEED_AP_MLME */
+#ifdef NEED_AP_MLME
+static void hostapd_neighbor_bss_load(struct hostapd_data *hapd, struct wpabuf **nr)
+{
+#ifdef CONFIG_TESTING_OPTIONS
+ if (hapd->conf->bss_load_test_set) {
+ wpabuf_put_u8(*nr, WMM_NEIGHBOR_BSS_LOAD);
+ wpabuf_put_u8(*nr, 5);
+ wpabuf_put_data(*nr, hapd->conf->bss_load_test, 5);
+ return;
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+ if (hapd->conf->bss_load_update_period) {
+ wpabuf_put_u8(*nr, WMM_NEIGHBOR_BSS_LOAD);
+ wpabuf_put_u8(*nr, 5);
+ wpabuf_put_le16(*nr, hapd->num_sta);
+ wpabuf_put_u8(*nr, hapd->iface->channel_utilization);
+ wpabuf_put_le16(*nr, 0); /* no available admission capabity */
+ }
+}
+#endif
void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
{
@@ -231,6 +251,7 @@ void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
enum nr_chan_width width;
u32 bssid_info;
struct wpabuf *nr;
+ int len = 0;
if (!(hapd->conf->radio_measurements[0] &
WLAN_RRM_CAPS_NEIGHBOR_REPORT))
@@ -291,9 +312,49 @@ void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
/*
* Neighbor Report element size = BSSID + BSSID info + op_class + chan +
- * phy type + wide bandwidth channel subelement.
+ * phy type + wide bandwidth channel subelement + SSID len.
*/
- nr = wpabuf_alloc(ETH_ALEN + 4 + 1 + 1 + 1 + 5);
+ len += ETH_ALEN + 4 + 1 + 1 + 1 + 5 + 2 + ssid.ssid_len;
+ if(ht)
+ {
+ // Adding length for ht cap and ht oper.
+ if(!is_6ghz_op_class(op_class))
+ {
+ len += sizeof(struct ieee80211_ht_capabilities) + 2;
+ len += sizeof(struct ieee80211_ht_operation) + 2;
+ }
+ }
+ if(vht)
+ {
+ // Adding length for vht cap and ht vht oper.
+ if(!is_6ghz_op_class(op_class))
+ {
+ len += sizeof(struct ieee80211_vht_capabilities) + 2;
+ len += sizeof(struct ieee80211_vht_operation) + 2;
+ }
+ }
+
+ if(he)
+ {
+ // Adding length for he cap and he oper length.
+ len += sizeof(struct ieee80211_he_capabilities) + 2 + 1;
+ len += sizeof(struct ieee80211_he_operation) + 2;
+ if(is_6ghz_op_class(op_class) )
+ {
+ len += 5;
+ }
+ }
+
+#ifdef CONFIG_TESTING_OPTIONS
+ if (hapd->conf->bss_load_test_set) {
+ len += 5;
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+ if (hapd->conf->bss_load_update_period) {
+ len += 5;
+ }
+
+ nr = wpabuf_alloc(len);
if (!nr)
return;
@@ -314,6 +375,52 @@ void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
wpabuf_put_u8(nr, center_freq1_idx);
wpabuf_put_u8(nr, center_freq2_idx);
+ if(ht && !is_6ghz_op_class(op_class))
+ {
+ u8* tmp1;
+ u8* tmp = os_zalloc(sizeof(struct ieee80211_ht_capabilities) +
+ sizeof(struct ieee80211_ht_operation) + 4);
+ tmp1 = hostapd_eid_ht_capabilities(hapd, tmp);
+ tmp1 = hostapd_eid_ht_operation(hapd, tmp1);
+ wpabuf_put_data(nr, tmp, sizeof(struct ieee80211_ht_capabilities) +
+ sizeof(struct ieee80211_ht_operation) + 4);
+ os_free(tmp);
+ }
+
+ if(vht && !is_6ghz_op_class(op_class))
+ {
+ u8* tmp1;
+ u8* tmp = os_zalloc(sizeof(struct ieee80211_vht_capabilities) +
+ sizeof(struct ieee80211_vht_operation) +4);
+ tmp1 = hostapd_eid_vht_capabilities(hapd, tmp, 0);
+ tmp1 = hostapd_eid_vht_operation(hapd, tmp1);
+ wpabuf_put_data(nr, tmp, sizeof(struct ieee80211_vht_capabilities) +
+ sizeof(struct ieee80211_vht_operation) +4);
+ os_free(tmp);
+ }
+
+ if(he)
+ {
+ u8* tmp, *tmp1, *tmp2;
+ if(is_6ghz_op_class(op_class) )
+ tmp = os_zalloc(sizeof(struct ieee80211_ht_capabilities) +
+ sizeof(struct ieee80211_ht_operation) + 4 + 5 + 1);
+ else
+ tmp = os_zalloc(sizeof(struct ieee80211_ht_capabilities) +
+ sizeof(struct ieee80211_ht_operation) + 4 + 1);
+ tmp1 = hostapd_eid_he_capab(hapd, tmp, IEEE80211_MODE_AP, true);
+ tmp2 = hostapd_eid_he_operation(hapd, tmp1, true);
+ wpabuf_put_data(nr, tmp, tmp2 - tmp );
+ os_free(tmp);
+ }
+
+ // TODO: Add more IEs
+ hostapd_neighbor_bss_load(hapd, &nr);
+
+ wpabuf_put_u8(nr, WMM_NEIGHBOR_SSID);
+ wpabuf_put_u8(nr, ssid.ssid_len);
+ wpabuf_put_data(nr, ssid.ssid, ssid.ssid_len);
+
hostapd_neighbor_set(hapd, hapd->own_addr, &ssid, nr, hapd->iconf->lci,
hapd->iconf->civic, hapd->iconf->stationary_ap, 0);
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 928b53500..3b228aaf8 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1871,6 +1871,11 @@ enum bss_trans_mgmt_status_code {
#define WNM_NEIGHBOR_MULTIPLE_BSSID 71
#define WNM_NEIGHBOR_VHT_CAPAB 191
#define WNM_NEIGHBOR_VHT_OPER 192
+#define WMM_NEIGHBOR_HE_CAPB 193
+#define WMM_NEIGHBOR_HE_OPER 194
+#define WMM_NEIGHBOR_BSS_LOAD 195
+#define WMM_NEIGHBOR_HE_BSS_LOAD 196
+#define WMM_NEIGHBOR_SSID 197
/* QoS action */
enum qos_action {
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 2eb9a7ef6..765842b6b 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -384,8 +384,8 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
3 + sizeof(struct ieee80211_he_6ghz_band_cap)];
pos = hostapd_eid_he_capab(bss, he_capa_oper,
- IEEE80211_MODE_MESH);
- pos = hostapd_eid_he_operation(bss, pos);
+ IEEE80211_MODE_MESH, false);
+ pos = hostapd_eid_he_operation(bss, pos, false);
pos = hostapd_eid_he_6ghz_band_cap(bss, pos);
wpabuf_put_data(buf, he_capa_oper, pos - he_capa_oper);
}
--
2.30.2
More information about the Hostap
mailing list