diff --git a/src/wifi/model/he/he-phy.cc b/src/wifi/model/he/he-phy.cc index 254d383e0..1212a72be 100644 --- a/src/wifi/model/he/he-phy.cc +++ b/src/wifi/model/he/he-phy.cc @@ -992,13 +992,13 @@ HePhy::GetRuBandForTx(const WifiTxVector& txVector, uint16_t staId) const WIFI_MOD_CLASS_HE); // for a TX spectrum, the guard bandwidth is a function of the transmission channel width // and the spectrum width equals the transmission channel width (hence bandIndex equals 0) - const auto indices = ConvertHeRuSubcarriers(channelWidth, - GetGuardBandwidth(channelWidth), - m_wifiPhy->GetOperatingChannel().GetFrequencies(), - m_wifiPhy->GetChannelWidth(), - m_wifiPhy->GetSubcarrierSpacing(), - {group.front().first, group.back().second}, - 0); + const auto indices = ConvertRuSubcarriers(channelWidth, + GetGuardBandwidth(channelWidth), + m_wifiPhy->GetOperatingChannel().GetFrequencies(), + m_wifiPhy->GetChannelWidth(), + m_wifiPhy->GetSubcarrierSpacing(), + {group.front().first, group.back().second}, + 0); WifiSpectrumBandInfo ruBandForTx{}; for (const auto& indicesPerSegment : indices) { @@ -1025,14 +1025,14 @@ HePhy::GetRuBandForRx(const WifiTxVector& txVector, uint16_t staId) const WIFI_MOD_CLASS_HE); // for an RX spectrum, the guard bandwidth is a function of the operating channel width // and the spectrum width equals the operating channel width - const auto indices = ConvertHeRuSubcarriers( - channelWidth, - GetGuardBandwidth(m_wifiPhy->GetChannelWidth()), - m_wifiPhy->GetOperatingChannel().GetFrequencies(), - m_wifiPhy->GetChannelWidth(), - m_wifiPhy->GetSubcarrierSpacing(), - {group.front().first, group.back().second}, - m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(channelWidth)); + const auto indices = + ConvertRuSubcarriers(channelWidth, + GetGuardBandwidth(m_wifiPhy->GetChannelWidth()), + m_wifiPhy->GetOperatingChannel().GetFrequencies(), + m_wifiPhy->GetChannelWidth(), + m_wifiPhy->GetSubcarrierSpacing(), + {group.front().first, group.back().second}, + m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(channelWidth)); WifiSpectrumBandInfo ruBandForRx{}; for (const auto& indicesPerSegment : indices) { @@ -1821,13 +1821,13 @@ HePhy::GetRxPpduFromTxPpdu(Ptr ppdu) } std::vector -HePhy::ConvertHeRuSubcarriers(MHz_u bandWidth, - MHz_u guardBandwidth, - const std::vector& centerFrequencies, - MHz_u totalWidth, - Hz_u subcarrierSpacing, - SubcarrierRange subcarrierRange, - uint8_t bandIndex) +HePhy::ConvertRuSubcarriers(MHz_u bandWidth, + MHz_u guardBandwidth, + const std::vector& centerFrequencies, + MHz_u totalWidth, + Hz_u subcarrierSpacing, + SubcarrierRange subcarrierRange, + uint8_t bandIndex) { NS_ASSERT_MSG(bandWidth <= totalWidth, "Bandwidth (" << bandWidth << ") cannot exceed total operating channel width (" @@ -1841,26 +1841,13 @@ HePhy::ConvertHeRuSubcarriers(MHz_u bandWidth, NS_ASSERT(bandIndex == 0); bandWidth /= centerFrequencies.size(); } - uint32_t centerFrequencyIndex = 0; - switch (static_cast(bandWidth)) - { - case 20: - centerFrequencyIndex = (nGuardBands / 2) + 6 + 122; - break; - case 40: - centerFrequencyIndex = (nGuardBands / 2) + 12 + 244; - break; - case 80: - centerFrequencyIndex = (nGuardBands / 2) + 12 + 500; - break; - case 160: - centerFrequencyIndex = (nGuardBands / 2) + 12 + 1012; - break; - default: - NS_FATAL_ERROR("ChannelWidth " << bandWidth << " unsupported"); - break; - } - + // Figures 27-5 to 27-7 of IEEE 802.11ax-2021: the number of guard subcarriers is 6 for 20 MHz + // MHz HE PPDUs and 12 for 40/80/160 MHz HE PPDUs + const uint32_t guardSubcarriers = (bandWidth < MHz_u{40}) ? 6 : 12; + const auto refRu = WifiRu::GetRuType(bandWidth); + const auto mc{WIFI_MOD_CLASS_HE}; + const auto offset = WifiRu::GetSubcarrierGroup(bandWidth, refRu, 1, mc).back().second; + uint32_t centerFrequencyIndex = (nGuardBands / 2) + guardSubcarriers + offset; const auto numBandsInBand = static_cast(MHzToHz(bandWidth) / subcarrierSpacing); centerFrequencyIndex += numBandsInBand * bandIndex; // start and stop subcarriers might be in different frequency segments, hence define a low and a diff --git a/src/wifi/model/he/he-phy.h b/src/wifi/model/he/he-phy.h index d4871323b..bc7a09f69 100644 --- a/src/wifi/model/he/he-phy.h +++ b/src/wifi/model/he/he-phy.h @@ -434,15 +434,15 @@ class HePhy : public VhtPhy * @param centerFrequencies the center frequency of each segment * @param totalWidth the width of the operating channel * @param subcarrierSpacing the subcarrier spacing - * @param subcarrierRange the subcarrier range of the HE RU + * @param subcarrierRange the subcarrier range of the RU * @param bandIndex the index (starting at 0) of the band within the operating channel * @return the converted subcarriers * - * This is a helper function to convert HE RU subcarriers, which are relative to the center + * This is a helper function to convert RU subcarriers, which are relative to the center * frequency subcarrier, to the indexes used by the Spectrum model. The size of the returned - * vector corresponds to the number of segments covered by the HE RU. + * vector corresponds to the number of segments covered by the RU. */ - static std::vector ConvertHeRuSubcarriers( + static std::vector ConvertRuSubcarriers( MHz_u bandWidth, MHz_u guardBandwidth, const std::vector& centerFrequencies, diff --git a/src/wifi/model/spectrum-wifi-phy.cc b/src/wifi/model/spectrum-wifi-phy.cc index aebf6960c..4fc531444 100644 --- a/src/wifi/model/spectrum-wifi-phy.cc +++ b/src/wifi/model/spectrum-wifi-phy.cc @@ -165,13 +165,13 @@ SpectrumWifiPhy::GetRuBands(Ptr spectrumPhyInterface, SubcarrierRange subcarrierRange = std::make_pair(group.front().first, group.back().second); const auto bandIndices = - HePhy::ConvertHeRuSubcarriers(bw, - guardBandwidth, - spectrumPhyInterface->GetCenterFrequencies(), - spectrumPhyInterface->GetChannelWidth(), - GetSubcarrierSpacing(), - subcarrierRange, - i); + HePhy::ConvertRuSubcarriers(bw, + guardBandwidth, + spectrumPhyInterface->GetCenterFrequencies(), + spectrumPhyInterface->GetChannelWidth(), + GetSubcarrierSpacing(), + subcarrierRange, + i); WifiSpectrumBandInfo band{}; for (const auto& indicesPerSegment : bandIndices) diff --git a/src/wifi/test/wifi-phy-ofdma-test.cc b/src/wifi/test/wifi-phy-ofdma-test.cc index a6f7bfa6a..32dfd3117 100644 --- a/src/wifi/test/wifi-phy-ofdma-test.cc +++ b/src/wifi/test/wifi-phy-ofdma-test.cc @@ -148,14 +148,14 @@ OfdmaTestHePhy::GetNonOfdmaBand(const WifiTxVector& txVector, uint16_t staId) co WifiRu::GetPhyIndex(nonOfdmaRu, channelWidth, m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(MHz_u{20}))); - const auto indices = ConvertHeRuSubcarriers( - channelWidth, - GetGuardBandwidth(m_wifiPhy->GetChannelWidth()), - m_wifiPhy->GetOperatingChannel().GetFrequencies(), - m_wifiPhy->GetChannelWidth(), - m_wifiPhy->GetSubcarrierSpacing(), - {groupPreamble.front().first, groupPreamble.back().second}, - m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(channelWidth)); + const auto indices = + ConvertRuSubcarriers(channelWidth, + GetGuardBandwidth(m_wifiPhy->GetChannelWidth()), + m_wifiPhy->GetOperatingChannel().GetFrequencies(), + m_wifiPhy->GetChannelWidth(), + m_wifiPhy->GetSubcarrierSpacing(), + {groupPreamble.front().first, groupPreamble.back().second}, + m_wifiPhy->GetOperatingChannel().GetPrimaryChannelIndex(channelWidth)); WifiSpectrumBandInfo nonOfdmaBand{}; for (const auto& indicesPerSegment : indices) {