From: Aloka Dixit Date: Tue, 19 Apr 2022 18:04:09 +0000 (-0700) Subject: EHT: Add operation element in AP mode Management frames X-Git-Tag: hostap_2_11~1992 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d54e3d0495740518b6c7b98d165a07b16333aec3;p=thirdparty%2Fhostap.git EHT: Add operation element in AP mode Management frames Add EHT Operation element in Beacon, Probe Response, and (Re)Association Response frames using the format described in IEEE P802.11be/D1.5, 9.4.2.311. Signed-off-by: Aloka Dixit Signed-off-by: Muna Sinada Signed-off-by: Pradeep Kumar Chitrapu --- diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 270b28b71..7212f501f 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -510,8 +510,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, #endif /* CONFIG_IEEE80211AX */ #ifdef CONFIG_IEEE80211BE - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); + buflen += 3 + sizeof(struct ieee80211_eht_operation); + } #endif /* CONFIG_IEEE80211BE */ buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP); @@ -641,8 +643,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, #endif /* CONFIG_IEEE80211AX */ #ifdef CONFIG_IEEE80211BE - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { pos = hostapd_eid_eht_capab(hapd, pos, IEEE80211_MODE_AP); + pos = hostapd_eid_eht_operation(hapd, pos); + } #endif /* CONFIG_IEEE80211BE */ #ifdef CONFIG_IEEE80211AC @@ -1549,8 +1553,10 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, #endif /* CONFIG_IEEE80211AX */ #ifdef CONFIG_IEEE80211BE - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { tail_len += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); + tail_len += 3 + sizeof(struct ieee80211_eht_operation); + } #endif /* CONFIG_IEEE80211BE */ tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON); @@ -1701,9 +1707,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, #endif /* CONFIG_IEEE80211AX */ #ifdef CONFIG_IEEE80211BE - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { tailpos = hostapd_eid_eht_capab(hapd, tailpos, IEEE80211_MODE_AP); + tailpos = hostapd_eid_eht_operation(hapd, tailpos); + } #endif /* CONFIG_IEEE80211BE */ #ifdef CONFIG_IEEE80211AC diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index c7ee3e126..d4f49330c 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -5045,8 +5045,10 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, buflen += 5 + sta->dpp_pfs->curve->prime_len; #endif /* CONFIG_DPP2 */ #ifdef CONFIG_IEEE80211BE - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); + buflen += 3 + sizeof(struct ieee80211_eht_operation); + } #endif /* CONFIG_IEEE80211BE */ buf = os_zalloc(buflen); @@ -5196,8 +5198,10 @@ rsnxe_done: #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_IEEE80211BE - if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { p = hostapd_eid_eht_capab(hapd, p, IEEE80211_MODE_AP); + p = hostapd_eid_eht_operation(hapd, p); + } #endif /* CONFIG_IEEE80211BE */ #ifdef CONFIG_OWE diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index b8fcfae0d..79c76284c 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -205,5 +205,6 @@ size_t hostapd_eid_eht_capab_len(struct hostapd_data *hapd, enum ieee80211_op_mode opmode); u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, enum ieee80211_op_mode opmode); +u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid); #endif /* IEEE802_11_H */ diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c index f4807d081..fe22d4981 100644 --- a/src/ap/ieee802_11_eht.c +++ b/src/ap/ieee802_11_eht.c @@ -155,3 +155,64 @@ u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, *length_pos = pos - (eid + 2); return pos; } + + +u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid) +{ + struct hostapd_config *conf = hapd->iconf; + struct ieee80211_eht_operation *oper; + u8 *pos = eid, chwidth, seg0 = 0, seg1 = 0; + + if (!hapd->iface->current_mode) + return eid; + + *pos++ = WLAN_EID_EXTENSION; + *pos++ = 5; + *pos++ = WLAN_EID_EXT_EHT_OPERATION; + + oper = (struct ieee80211_eht_operation *) pos; + oper->oper_params = EHT_OPER_INFO_PRESENT; + + if (is_6ghz_op_class(conf->op_class)) + chwidth = op_class_to_ch_width(conf->op_class); + else + chwidth = conf->eht_oper_chwidth; + + seg0 = hostapd_get_oper_centr_freq_seg0_idx(conf); + + switch (chwidth) { +#if 0 /* FIX: Need to clean up CHANWIDTH_* use for protocol vs. internal + * needs to be able to define this. */ + case CHANWIDTH_320MHZ: + oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_320MHZ; + seg1 = seg0; + if (hapd->iconf->channel < seg0) + seg0 -= 16; + else + seg0 += 16; + break; +#endif + case CHANWIDTH_160MHZ: + oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_160MHZ; + seg1 = seg0; + if (hapd->iconf->channel < seg0) + seg0 -= 8; + else + seg0 += 8; + break; + case CHANWIDTH_80MHZ: + oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_80MHZ; + break; + case CHANWIDTH_USE_HT: + if (seg0) + oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_40MHZ; + break; + default: + return eid; + } + + oper->oper_info.ccfs0 = seg0 ? seg0 : hapd->iconf->channel; + oper->oper_info.ccfs1 = seg1; + + return pos + 4; +}