diff --git a/src/wifi/model/he/he-phy.cc b/src/wifi/model/he/he-phy.cc index 4f26883a6..e3a59ca22 100644 --- a/src/wifi/model/he/he-phy.cc +++ b/src/wifi/model/he/he-phy.cc @@ -1856,47 +1856,6 @@ HePhy::ConvertHeRuSubcarriers(uint16_t bandWidth, return convertedSubcarriers; } -HePhy::RuBands -HePhy::GetRuBands(Ptr phy, uint16_t channelWidth, uint16_t guardBandwidth) -{ - HePhy::RuBands ruBands{}; - for (uint16_t bw = 160; bw >= 20; bw = bw / 2) - { - for (uint32_t i = 0; i < (channelWidth / bw); ++i) - { - for (uint32_t type = 0; type < 7; type++) - { - auto ruType = static_cast(type); - std::size_t nRus = HeRu::GetNRus(bw, ruType); - for (std::size_t phyIndex = 1; phyIndex <= nRus; phyIndex++) - { - HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup(bw, ruType, phyIndex); - HeRu::SubcarrierRange subcarrierRange = - std::make_pair(group.front().first, group.back().second); - const auto bandIndices = ConvertHeRuSubcarriers(bw, - guardBandwidth, - phy->GetSubcarrierSpacing(), - subcarrierRange, - i); - const auto bandFrequencies = phy->ConvertIndicesToFrequencies(bandIndices); - WifiSpectrumBandInfo band = {bandIndices, bandFrequencies}; - std::size_t index = - (bw == 160 && phyIndex > nRus / 2 ? phyIndex - nRus / 2 : phyIndex); - const auto p20Index = phy->GetOperatingChannel().GetPrimaryChannelIndex(20); - bool primary80IsLower80 = (p20Index < bw / 40); - bool primary80 = (bw < 160 || ruType == HeRu::RU_2x996_TONE || - (primary80IsLower80 && phyIndex <= nRus / 2) || - (!primary80IsLower80 && phyIndex > nRus / 2)); - HeRu::RuSpec ru(ruType, index, primary80); - NS_ABORT_IF(ru.GetPhyIndex(bw, p20Index) != phyIndex); - ruBands.insert({band, ru}); - } - } - } - } - return ruBands; -} - } // namespace ns3 namespace diff --git a/src/wifi/model/he/he-phy.h b/src/wifi/model/he/he-phy.h index fe70fbecb..b7ad97300 100644 --- a/src/wifi/model/he/he-phy.h +++ b/src/wifi/model/he/he-phy.h @@ -451,21 +451,6 @@ class HePhy : public VhtPhy HeRu::SubcarrierRange subcarrierRange, uint8_t bandIndex = 0); - /// Map a spectrum band associated with an RU to the RU specification - using RuBands = std::map; - - /** - * Static function to compute the RU bands that belong to a given channel width. - * - * \param phy the PHY that issued the function call - * \param channelWidth the channelWidth the channel width in MHz - * \param guardBandwidth width of the guard band in MHz - * \returns the computed RU bands that belong to the channel width - */ - static RuBands GetRuBands(Ptr phy, - uint16_t channelWidth, - uint16_t guardBandwidth); - protected: PhyFieldRxStatus ProcessSig(Ptr event, PhyFieldRxStatus status, diff --git a/src/wifi/model/phy-entity.h b/src/wifi/model/phy-entity.h index 114cdc2ab..8160e66bd 100644 --- a/src/wifi/model/phy-entity.h +++ b/src/wifi/model/phy-entity.h @@ -31,7 +31,6 @@ #include "ns3/event-id.h" #include "ns3/nstime.h" #include "ns3/simple-ref-count.h" -#include "ns3/wifi-spectrum-value-helper.h" #include #include diff --git a/src/wifi/model/spectrum-wifi-phy.cc b/src/wifi/model/spectrum-wifi-phy.cc index e1cfa8793..762c34d45 100644 --- a/src/wifi/model/spectrum-wifi-phy.cc +++ b/src/wifi/model/spectrum-wifi-phy.cc @@ -121,16 +121,15 @@ SpectrumWifiPhy::DoInitialize() WifiPhy::DoInitialize(); } -void -SpectrumWifiPhy::UpdateInterferenceHelperBands() +WifiSpectrumBands +SpectrumWifiPhy::ComputeBands(Ptr spectrumPhyInterface) { - NS_LOG_FUNCTION(this); - NS_ASSERT(!m_spectrumPhyInterfaces.empty()); - uint16_t channelWidth = GetChannelWidth(); - WifiSpectrumPhyInterface::WifiSpectrumBands bands{}; + NS_LOG_FUNCTION(this << spectrumPhyInterface); + WifiSpectrumBands bands{}; + const auto channelWidth = spectrumPhyInterface->GetChannelWidth(); if (channelWidth < 20) { - bands.push_back(GetBand(channelWidth)); + bands.push_back(GetBandForInterface(spectrumPhyInterface, channelWidth)); } else { @@ -138,26 +137,79 @@ SpectrumWifiPhy::UpdateInterferenceHelperBands() { for (uint32_t i = 0; i < (channelWidth / bw); ++i) { - bands.push_back(GetBand(bw, i)); + bands.push_back(GetBandForInterface(spectrumPhyInterface, bw, i)); } } } - WifiSpectrumPhyInterface::WifiSpectrumBands allBands{bands}; + return bands; +} + +HeRuBands +SpectrumWifiPhy::GetHeRuBands(Ptr spectrumPhyInterface, + uint16_t guardBandwidth) +{ + HeRuBands heRuBands{}; + const auto channelWidth = spectrumPhyInterface->GetChannelWidth(); + for (uint16_t bw = 160; bw >= 20; bw = bw / 2) + { + for (uint32_t i = 0; i < (channelWidth / bw); ++i) + { + for (uint32_t type = 0; type < 7; type++) + { + auto ruType = static_cast(type); + std::size_t nRus = HeRu::GetNRus(bw, ruType); + for (std::size_t phyIndex = 1; phyIndex <= nRus; phyIndex++) + { + HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup(bw, ruType, phyIndex); + HeRu::SubcarrierRange subcarrierRange = + std::make_pair(group.front().first, group.back().second); + const auto bandIndices = HePhy::ConvertHeRuSubcarriers(bw, + guardBandwidth, + GetSubcarrierSpacing(), + subcarrierRange, + i); + const auto bandFrequencies = + ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, bandIndices); + WifiSpectrumBandInfo band = {bandIndices, bandFrequencies}; + std::size_t index = + (bw == 160 && phyIndex > nRus / 2 ? phyIndex - nRus / 2 : phyIndex); + const auto p20Index = GetOperatingChannel().GetPrimaryChannelIndex(20); + bool primary80IsLower80 = (p20Index < bw / 40); + bool primary80 = (bw < 160 || ruType == HeRu::RU_2x996_TONE || + (primary80IsLower80 && phyIndex <= nRus / 2) || + (!primary80IsLower80 && phyIndex > nRus / 2)); + HeRu::RuSpec ru(ruType, index, primary80); + NS_ABORT_IF(ru.GetPhyIndex(bw, p20Index) != phyIndex); + heRuBands.insert({band, ru}); + } + } + } + } + return heRuBands; +} + +void +SpectrumWifiPhy::UpdateInterferenceHelperBands(Ptr spectrumPhyInterface) +{ + NS_LOG_FUNCTION(this << spectrumPhyInterface); + auto&& bands = ComputeBands(spectrumPhyInterface); + WifiSpectrumBands allBands{bands}; if (GetStandard() >= WIFI_STANDARD_80211ax) { - auto&& ruBands = HePhy::GetRuBands(this, channelWidth, GetGuardBandwidth(channelWidth)); - for (const auto& bandRuPair : ruBands) + const auto channelWidth = spectrumPhyInterface->GetChannelWidth(); + auto&& heRuBands = GetHeRuBands(spectrumPhyInterface, GetGuardBandwidth(channelWidth)); + for (const auto& bandRuPair : heRuBands) { allBands.push_back(bandRuPair.first); } - m_currentSpectrumPhyInterface->SetRuBands(std::move(ruBands)); + spectrumPhyInterface->SetHeRuBands(std::move(heRuBands)); } - m_currentSpectrumPhyInterface->SetBands(std::move(bands)); + spectrumPhyInterface->SetBands(std::move(bands)); if (m_interference->HasBands()) { - m_interference->UpdateBands(allBands, GetCurrentFrequencyRange()); + m_interference->UpdateBands(allBands, spectrumPhyInterface->GetFrequencyRange()); } else { @@ -205,9 +257,11 @@ SpectrumWifiPhy::AddChannel(const Ptr channel, const FrequencyR } void -SpectrumWifiPhy::ResetSpectrumModelIfNeeded() +SpectrumWifiPhy::ResetSpectrumModel(Ptr spectrumPhyInterface, + uint16_t centerFrequency, + uint16_t channelWidth) { - NS_LOG_FUNCTION(this); + NS_LOG_FUNCTION(this << spectrumPhyInterface << centerFrequency << channelWidth); // We have to reset the spectrum model because we changed RF channel. Consequently, // we also have to add the spectrum interface to the spectrum channel again because @@ -217,31 +271,15 @@ SpectrumWifiPhy::ResetSpectrumModelIfNeeded() // duplicated spectrum interfaces (the latter removes the spectrum interface and adds // it again in the entry associated with the new RX spectrum model UID) - const auto channelWidth = GetChannelWidth(); - const auto centerFrequency = GetFrequency(); - if (m_currentSpectrumPhyInterface->GetCenterFrequency() == centerFrequency) - { - // Center frequency has not changed for that interface, hence we do not need to - // reset the spectrum model nor update any band stored in the interference helper - if (!m_trackSignalsInactiveInterfaces) - { - // If we are not tracking signals from inactive interface, - // this means the spectrum interface has been disconnected - // from the spectrum channel and has to be connected back - m_currentSpectrumPhyInterface->GetChannel()->AddRx(m_currentSpectrumPhyInterface); - } - return; - } - // Replace existing spectrum model with new one - m_currentSpectrumPhyInterface->SetRxSpectrumModel(centerFrequency, - channelWidth, - GetSubcarrierSpacing(), - GetGuardBandwidth(channelWidth)); + spectrumPhyInterface->SetRxSpectrumModel(centerFrequency, + channelWidth, + GetSubcarrierSpacing(), + GetGuardBandwidth(channelWidth)); - m_currentSpectrumPhyInterface->GetChannel()->AddRx(m_currentSpectrumPhyInterface); + spectrumPhyInterface->GetChannel()->AddRx(spectrumPhyInterface); - UpdateInterferenceHelperBands(); + UpdateInterferenceHelperBands(spectrumPhyInterface); } void @@ -282,7 +320,26 @@ SpectrumWifiPhy::DoChannelSwitch() } m_currentSpectrumPhyInterface = newSpectrumPhyInterface; - ResetSpectrumModelIfNeeded(); + + auto reset = true; + if (m_currentSpectrumPhyInterface->GetCenterFrequency() == frequencyAfter) + { + // Center frequency has not changed for that interface, hence we do not need to + // reset the spectrum model nor update any band stored in the interference helper + if (!m_trackSignalsInactiveInterfaces) + { + // If we are not tracking signals from inactive interface, + // this means the spectrum interface has been disconnected + // from the spectrum channel and has to be connected back + m_currentSpectrumPhyInterface->GetChannel()->AddRx(m_currentSpectrumPhyInterface); + } + reset = false; + } + + if (reset) + { + ResetSpectrumModel(m_currentSpectrumPhyInterface, frequencyAfter, widthAfter); + } if (IsInitialized()) { @@ -348,10 +405,10 @@ SpectrumWifiPhy::StartRx(Ptr rxParams, if (GetStandard() >= WIFI_STANDARD_80211ax) { - const auto& ruBands = - interface ? interface->GetRuBands() : m_currentSpectrumPhyInterface->GetRuBands(); - NS_ASSERT(!ruBands.empty()); - for (const auto& [band, ru] : ruBands) + const auto& heRuBands = + interface ? interface->GetHeRuBands() : m_currentSpectrumPhyInterface->GetHeRuBands(); + NS_ASSERT(!heRuBands.empty()); + for (const auto& [band, ru] : heRuBands) { double rxPowerPerBandW = WifiSpectrumValueHelper::GetBandPowerW(receivedSignalPsd, band.indices); @@ -497,18 +554,19 @@ SpectrumWifiPhy::GetGuardBandwidth(uint16_t currentChannelWidth) const } WifiSpectrumBandInfo -SpectrumWifiPhy::GetBand(uint16_t bandWidth, uint8_t bandIndex /* = 0 */) +SpectrumWifiPhy::GetBandForInterface(Ptr spectrumPhyInterface, + uint16_t bandWidth, + uint8_t bandIndex /* = 0 */) { - auto channelWidth = GetChannelWidth(); - auto subcarrierSpacing = GetSubcarrierSpacing(); + const auto subcarrierSpacing = GetSubcarrierSpacing(); + const auto channelWidth = spectrumPhyInterface->GetChannelWidth(); + const auto numBandsInBand = static_cast(bandWidth * 1e6 / subcarrierSpacing); auto numBandsInChannel = static_cast(channelWidth * 1e6 / subcarrierSpacing); - auto numBandsInBand = static_cast(bandWidth * 1e6 / subcarrierSpacing); if (numBandsInBand % 2 == 0) { numBandsInChannel += 1; // symmetry around center frequency } - NS_ABORT_IF(!m_currentSpectrumPhyInterface); - auto rxSpectrumModel = m_currentSpectrumPhyInterface->GetRxSpectrumModel(); + auto rxSpectrumModel = spectrumPhyInterface->GetRxSpectrumModel(); size_t totalNumBands = rxSpectrumModel->GetNumBands(); NS_ASSERT_MSG((numBandsInChannel % 2 == 1) && (totalNumBands % 2 == 1), "Should have odd number of bands"); @@ -516,8 +574,9 @@ SpectrumWifiPhy::GetBand(uint16_t bandWidth, uint8_t bandIndex /* = 0 */) NS_ASSERT(totalNumBands >= numBandsInChannel); auto startIndex = ((totalNumBands - numBandsInChannel) / 2) + (bandIndex * numBandsInBand); auto stopIndex = startIndex + numBandsInBand - 1; - auto frequencies = ConvertIndicesToFrequencies({startIndex, stopIndex}); - auto freqRange = m_currentSpectrumPhyInterface->GetFrequencyRange(); + auto frequencies = + ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, {startIndex, stopIndex}); + auto freqRange = spectrumPhyInterface->GetFrequencyRange(); NS_ASSERT(frequencies.first >= (freqRange.minFrequency * 1e6)); NS_ASSERT(frequencies.second <= (freqRange.maxFrequency * 1e6)); NS_ASSERT((frequencies.second - frequencies.first) == (bandWidth * 1e6)); @@ -529,11 +588,27 @@ SpectrumWifiPhy::GetBand(uint16_t bandWidth, uint8_t bandIndex /* = 0 */) return {{startIndex, stopIndex}, frequencies}; } +WifiSpectrumBandInfo +SpectrumWifiPhy::GetBand(uint16_t bandWidth, uint8_t bandIndex /* = 0 */) +{ + NS_ABORT_IF(!m_currentSpectrumPhyInterface); + return GetBandForInterface(m_currentSpectrumPhyInterface, bandWidth, bandIndex); +} + WifiSpectrumBandFrequencies SpectrumWifiPhy::ConvertIndicesToFrequencies(const WifiSpectrumBandIndices& indices) const { NS_ABORT_IF(!m_currentSpectrumPhyInterface); - auto rxSpectrumModel = m_currentSpectrumPhyInterface->GetRxSpectrumModel(); + return ConvertIndicesToFrequenciesForInterface(m_currentSpectrumPhyInterface, indices); +} + +WifiSpectrumBandFrequencies +SpectrumWifiPhy::ConvertIndicesToFrequenciesForInterface( + Ptr spectrumPhyInterface, + const WifiSpectrumBandIndices& indices) const +{ + NS_ABORT_IF(!spectrumPhyInterface); + auto rxSpectrumModel = spectrumPhyInterface->GetRxSpectrumModel(); auto startGuardBand = rxSpectrumModel->Begin(); auto startChannel = std::next(startGuardBand, indices.first); auto endChannel = std::next(startGuardBand, indices.second + 1); diff --git a/src/wifi/model/spectrum-wifi-phy.h b/src/wifi/model/spectrum-wifi-phy.h index e704e7dd2..23eefa5e4 100644 --- a/src/wifi/model/spectrum-wifi-phy.h +++ b/src/wifi/model/spectrum-wifi-phy.h @@ -42,6 +42,9 @@ struct SpectrumSignalParameters; class WifiSpectrumPhyInterface; struct WifiSpectrumSignalParameters; +/// Map a spectrum band associated with an RU to the RU specification +using HeRuBands = std::map; + /** * \brief 802.11 PHY layer model * \ingroup wifi @@ -178,15 +181,62 @@ class SpectrumWifiPhy : public WifiPhy private: /** - * Perform run-time spectrum model change if the one used by the current Spectrum PHY interface - * has changed + * Perform run-time spectrum model change + * \param spectrumPhyInterface the spectrum PHY interface for which the spectrum model should be + * changed \param centerFrequency the center frequency in MHz the PHY interface should use + * \param channelWidth the channel width in MHz the PHY interface should use */ - void ResetSpectrumModelIfNeeded(); + void ResetSpectrumModel(Ptr spectrumPhyInterface, + uint16_t centerFrequency, + uint16_t channelWidth); /** * This function is called to update the bands handled by the InterferenceHelper. + * \param spectrumPhyInterface the spectrum PHY interface for which the bands should be updated */ - void UpdateInterferenceHelperBands(); + void UpdateInterferenceHelperBands(Ptr spectrumPhyInterface); + + /** + * This function computes the RU bands that belong to a given spectrum PHY interface. + * + * \param spectrumPhyInterface the spectrum PHY interface to consider to compute the RU bands + * \param guardBandwidth width of the guard band in MHz + * \returns the computed RU bands for the spectrum PHY interface + */ + HeRuBands GetHeRuBands(Ptr spectrumPhyInterface, + uint16_t guardBandwidth); + + /** + * This function computes the bands that belong to a given spectrum PHY interface. + * + * \param spectrumPhyInterface the spectrum PHY interface to consider to compute the bands + * \returns the computed bands for the spectrum PHY interface + */ + WifiSpectrumBands ComputeBands(Ptr spectrumPhyInterface); + + /** + * Get the info of a given band that belongs to a given spectrum PHY interface + * + * \param spectrumPhyInterface the spectrum PHY interface + * \param bandWidth the width of the band to be returned (MHz) + * \param bandIndex the index of the band to be returned + * + * \return the info that defines the band + */ + WifiSpectrumBandInfo GetBandForInterface(Ptr spectrumPhyInterface, + uint16_t bandWidth, + uint8_t bandIndex = 0); + + /** + * This is a helper function to convert start and stop indices to start and stop frequencies. + * + * \param spectrumPhyInterface the spectrum PHY interface to consider for the calculations + * \param indices the start/stop indices to convert + * \return the converted frequencies + */ + WifiSpectrumBandFrequencies ConvertIndicesToFrequenciesForInterface( + Ptr spectrumPhyInterface, + const WifiSpectrumBandIndices& indices) const; /** * Determine whether the PHY shall issue a PHY-RXSTART.indication primitive in response to a diff --git a/src/wifi/model/wifi-phy-common.h b/src/wifi/model/wifi-phy-common.h index 42e45cf7e..87f5bbd54 100644 --- a/src/wifi/model/wifi-phy-common.h +++ b/src/wifi/model/wifi-phy-common.h @@ -60,6 +60,9 @@ struct WifiSpectrumBandInfo WifiSpectrumBandFrequencies frequencies; //!< the start and stop frequencies of the band }; +/// vector of spectrum bands +using WifiSpectrumBands = std::vector; + /** * \ingroup wifi * Compare two bands. diff --git a/src/wifi/model/wifi-spectrum-phy-interface.cc b/src/wifi/model/wifi-spectrum-phy-interface.cc index ca42ef2e3..4f35b68a4 100644 --- a/src/wifi/model/wifi-spectrum-phy-interface.cc +++ b/src/wifi/model/wifi-spectrum-phy-interface.cc @@ -45,7 +45,7 @@ WifiSpectrumPhyInterface::WifiSpectrumPhyInterface(FrequencyRange freqRange) m_centerFrequency{0}, m_channelWidth{0}, m_bands{}, - m_ruBands{} + m_heRuBands{} { NS_LOG_FUNCTION(this << freqRange); } @@ -59,7 +59,7 @@ WifiSpectrumPhyInterface::DoDispose() m_netDevice = nullptr; m_channel = nullptr; m_bands.clear(); - m_ruBands.clear(); + m_heRuBands.clear(); } void @@ -158,27 +158,27 @@ WifiSpectrumPhyInterface::GetChannelWidth() const } void -WifiSpectrumPhyInterface::SetBands(WifiSpectrumPhyInterface::WifiSpectrumBands&& bands) +WifiSpectrumPhyInterface::SetBands(WifiSpectrumBands&& bands) { m_bands = std::move(bands); } -const WifiSpectrumPhyInterface::WifiSpectrumBands& +const WifiSpectrumBands& WifiSpectrumPhyInterface::GetBands() const { return m_bands; } void -WifiSpectrumPhyInterface::SetRuBands(HePhy::RuBands&& ruBands) +WifiSpectrumPhyInterface::SetHeRuBands(HeRuBands&& heRuBands) { - m_ruBands = std::move(ruBands); + m_heRuBands = std::move(heRuBands); } -const HePhy::RuBands& -WifiSpectrumPhyInterface::GetRuBands() const +const HeRuBands& +WifiSpectrumPhyInterface::GetHeRuBands() const { - return m_ruBands; + return m_heRuBands; } void diff --git a/src/wifi/model/wifi-spectrum-phy-interface.h b/src/wifi/model/wifi-spectrum-phy-interface.h index a050fa059..670bc0338 100644 --- a/src/wifi/model/wifi-spectrum-phy-interface.h +++ b/src/wifi/model/wifi-spectrum-phy-interface.h @@ -126,9 +126,6 @@ class WifiSpectrumPhyInterface : public SpectrumPhy uint32_t bandBandwidth, uint16_t guardBandwidth); - /// vector of spectrum bands handled by this interface - using WifiSpectrumBands = std::vector; - /** * Set the vector of spectrum bands handled by this interface * @@ -145,15 +142,15 @@ class WifiSpectrumPhyInterface : public SpectrumPhy /** * Set the HE RU spectrum bands handled by this interface (if any) * - * \param ruBands the HE RU spectrum bands + * \param heRuBands the HE RU spectrum bands */ - void SetRuBands(HePhy::RuBands&& ruBands); + void SetHeRuBands(HeRuBands&& heRuBands); /** * Get the HE RU spectrum bands handled by this interface * * \return the HE RU spectrum bands */ - const HePhy::RuBands& GetRuBands() const; + const HeRuBands& GetHeRuBands() const; private: void DoDispose() override; @@ -168,7 +165,7 @@ class WifiSpectrumPhyInterface : public SpectrumPhy WifiSpectrumBands m_bands; /**< Store all the distinct spectrum bands associated with every channels widths */ - HePhy::RuBands m_ruBands; /**< Store all the distinct spectrum bands associated with every RU */ + HeRuBands m_heRuBands; /**< Store all the distinct spectrum bands associated with every RU */ }; } // namespace ns3