From f913604e2c7c358178d56db527394cfde78484d1 Mon Sep 17 00:00:00 2001 From: Rediet Date: Mon, 15 Feb 2021 09:01:25 +0100 Subject: [PATCH] wifi: Move TxPsdFlag to HePpdu Enables to clean up WifiPhy and SpectrumWifiPhy signatures --- src/wifi/model/he-phy.cc | 16 ++-- src/wifi/model/he-phy.h | 2 +- src/wifi/model/he-ppdu.cc | 38 ++++++++- src/wifi/model/he-ppdu.h | 41 +++++++++- src/wifi/model/phy-entity.cc | 2 +- src/wifi/model/phy-entity.h | 4 +- src/wifi/model/spectrum-wifi-phy.cc | 80 ++++++++++--------- src/wifi/model/spectrum-wifi-phy.h | 11 ++- src/wifi/model/wifi-phy.cc | 35 ++++---- src/wifi/model/wifi-phy.h | 10 +-- .../model/wifi-spectrum-signal-parameters.cc | 1 - .../model/wifi-spectrum-signal-parameters.h | 39 --------- src/wifi/model/yans-wifi-phy.cc | 2 +- src/wifi/test/wifi-phy-ofdma-test.cc | 6 +- 14 files changed, 164 insertions(+), 123 deletions(-) diff --git a/src/wifi/model/he-phy.cc b/src/wifi/model/he-phy.cc index 2dcd75330..54fd9e781 100644 --- a/src/wifi/model/he-phy.cc +++ b/src/wifi/model/he-phy.cc @@ -307,18 +307,24 @@ Ptr HePhy::BuildPpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppduDuration) { NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration); + HePpdu::TxPsdFlag flag = (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB) ? + HePpdu::PSD_HE_TB_NON_OFDMA_PORTION : + HePpdu::PSD_NON_HE_TB; return Create (psdus, txVector, ppduDuration, m_wifiPhy->GetPhyBand (), - ObtainNextUid (txVector)); + ObtainNextUid (txVector), flag); } void HePhy::StartReceivePreamble (Ptr ppdu, RxPowerWattPerChannelBand rxPowersW, - Time rxDuration, TxPsdFlag psdFlag) + Time rxDuration) { - NS_LOG_FUNCTION (this << ppdu << rxDuration << psdFlag); + NS_LOG_FUNCTION (this << ppdu << rxDuration); WifiTxVector txVector = ppdu->GetTxVector (); + auto hePpdu = DynamicCast (ppdu); + NS_ASSERT (hePpdu); + HePpdu::TxPsdFlag psdFlag = hePpdu->GetTxPsdFlag (); if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB - && psdFlag == PSD_HE_TB_OFDMA_PORTION) + && psdFlag == HePpdu::PSD_HE_TB_OFDMA_PORTION) { if (m_currentHeTbPpduUid == ppdu->GetUid () && GetCurrentEvent () != 0) @@ -344,7 +350,7 @@ HePhy::StartReceivePreamble (Ptr ppdu, RxPowerWattPerChannelBand rxPow } else { - PhyEntity::StartReceivePreamble (ppdu, rxPowersW, rxDuration, psdFlag); + PhyEntity::StartReceivePreamble (ppdu, rxPowersW, rxDuration); } } diff --git a/src/wifi/model/he-phy.h b/src/wifi/model/he-phy.h index 57223362a..88e64315b 100644 --- a/src/wifi/model/he-phy.h +++ b/src/wifi/model/he-phy.h @@ -74,7 +74,7 @@ public: virtual Ptr BuildPpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppduDuration) override; Ptr GetAddressedPsduInPpdu (Ptr ppdu) const override; void StartReceivePreamble (Ptr ppdu, RxPowerWattPerChannelBand rxPowersW, - Time rxDuration, TxPsdFlag psdFlag) override; + Time rxDuration) override; void CancelAllEvents (void) override; virtual uint16_t GetStaId (const Ptr ppdu) const override; uint16_t GetMeasurementChannelWidth (const Ptr ppdu) const override; diff --git a/src/wifi/model/he-ppdu.cc b/src/wifi/model/he-ppdu.cc index ce4b264fa..7dfe21fa0 100644 --- a/src/wifi/model/he-ppdu.cc +++ b/src/wifi/model/he-ppdu.cc @@ -31,11 +31,27 @@ namespace ns3 { NS_LOG_COMPONENT_DEFINE ("HePpdu"); +std::ostream& operator<< (std::ostream& os, const HePpdu::TxPsdFlag &flag) +{ + switch (flag) + { + case HePpdu::PSD_NON_HE_TB: + return (os << "PSD_NON_HE_TB"); + case HePpdu::PSD_HE_TB_NON_OFDMA_PORTION: + return (os << "PSD_HE_TB_NON_OFDMA_PORTION"); + case HePpdu::PSD_HE_TB_OFDMA_PORTION: + return (os << "PSD_HE_TB_OFDMA_PORTION"); + default: + NS_FATAL_ERROR ("Invalid PSD flag"); + return (os << "INVALID"); + } +} + HePpdu::HePpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppduDuration, - WifiPhyBand band, uint64_t uid) + WifiPhyBand band, uint64_t uid, TxPsdFlag flag) : OfdmPpdu (psdus.begin ()->second, txVector, band, uid, false) //don't instantiate LSigHeader of OfdmPpdu { - NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration << band << uid); + NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration << band << uid << flag); //overwrite with map (since only first element used by OfdmPpdu) m_psdus.begin ()->second = 0; @@ -47,6 +63,7 @@ HePpdu::HePpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppdu } SetPhyHeaders (txVector, ppduDuration); + SetTxPsdFlag (flag); } HePpdu::HePpdu (Ptr psdu, WifiTxVector txVector, Time ppduDuration, @@ -56,6 +73,7 @@ HePpdu::HePpdu (Ptr psdu, WifiTxVector txVector, Time ppduDurati NS_LOG_FUNCTION (this << psdu << txVector << ppduDuration << band << uid); NS_ASSERT (!IsMu ()); SetPhyHeaders (txVector, ppduDuration); + SetTxPsdFlag (PSD_NON_HE_TB); } HePpdu::~HePpdu () @@ -141,7 +159,7 @@ HePpdu::GetTxDuration (void) const Ptr HePpdu::Copy (void) const { - return Create (m_psdus, GetTxVector (), GetTxDuration (), m_band, m_uid); + return Create (m_psdus, GetTxVector (), GetTxDuration (), m_band, m_uid, m_txPsdFlag); } WifiPpduType @@ -213,6 +231,19 @@ HePpdu::GetStaId (void) const return m_psdus.begin ()->first; } +HePpdu::TxPsdFlag +HePpdu::GetTxPsdFlag (void) const +{ + return m_txPsdFlag; +} + +void +HePpdu::SetTxPsdFlag (TxPsdFlag flag) +{ + NS_LOG_FUNCTION (this << flag); + NS_ASSERT ((IsUlMu () && flag > PSD_NON_HE_TB) || (!IsUlMu () && flag == PSD_NON_HE_TB)); + m_txPsdFlag = flag; +} std::string HePpdu::PrintPayload (void) const @@ -221,6 +252,7 @@ HePpdu::PrintPayload (void) const if (IsMu ()) { ss << m_psdus; + ss << ", " << m_txPsdFlag; } else { diff --git a/src/wifi/model/he-ppdu.h b/src/wifi/model/he-ppdu.h index 2002a05a9..0d1e931d0 100644 --- a/src/wifi/model/he-ppdu.h +++ b/src/wifi/model/he-ppdu.h @@ -151,6 +151,18 @@ public: bool m_mu; }; //class HeSigHeader + /** + * The transmit power spectral density flag, namely used + * to correctly build PSD for HE TB PPDU non-OFDMA and + * OFDMA portions. + */ + enum TxPsdFlag + { + PSD_NON_HE_TB = 0, //!< non-HE TB PPDU transmissions + PSD_HE_TB_NON_OFDMA_PORTION, //!< preamble of HE TB PPDU, which should only be sent on minimum subset of 20 MHz channels containing RU + PSD_HE_TB_OFDMA_PORTION //!< OFDMA portion of HE TB PPDU, which should only be sent on RU + }; + /** * Create an SU HE PPDU, storing a PSDU. * @@ -172,9 +184,10 @@ public: * \param ppduDuration the transmission duration of this PPDU * \param band the WifiPhyBand used for the transmission of this PPDU * \param uid the unique ID of this PPDU or of the triggering PPDU if this is an HE TB PPDU + * \param flag the flag indicating the type of Tx PSD to build */ HePpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppduDuration, - WifiPhyBand band, uint64_t uid); + WifiPhyBand band, uint64_t uid, TxPsdFlag flag); /** * Destructor for HePpdu. */ @@ -195,6 +208,20 @@ public: */ Ptr GetPsdu (uint8_t bssColor, uint16_t staId = SU_STA_ID) const; + /** + * \return the transmit PSD flag set for this PPDU + * + * \see TxPsdFlag + */ + TxPsdFlag GetTxPsdFlag (void) const; + + /** + * \param flag the transmit PSD flag set for this PPDU + * + * \see TxPsdFlag + */ + void SetTxPsdFlag (TxPsdFlag flag); + protected: // Inherited std::string PrintPayload (void) const override; @@ -229,9 +256,19 @@ private: */ void SetPhyHeaders (WifiTxVector txVector, Time ppduDuration); - HeSigHeader m_heSig; //!< the HE-SIG PHY header + HeSigHeader m_heSig; //!< the HE-SIG PHY header + TxPsdFlag m_txPsdFlag; //!< the transmit power spectral density flag }; //class HePpdu +/** +* \brief Stream insertion operator. +* +* \param os the stream +* \param flag the transmit power spectral density flag +* \returns a reference to the stream +*/ +std::ostream& operator<< (std::ostream& os, const HePpdu::TxPsdFlag &flag); + } //namespace ns3 #endif /* HE_PPDU_H */ diff --git a/src/wifi/model/phy-entity.cc b/src/wifi/model/phy-entity.cc index e90e5da59..46f2c6abb 100644 --- a/src/wifi/model/phy-entity.cc +++ b/src/wifi/model/phy-entity.cc @@ -353,7 +353,7 @@ PhyEntity::DoEndReceiveField (WifiPpduField field, Ptr event) void PhyEntity::StartReceivePreamble (Ptr ppdu, RxPowerWattPerChannelBand rxPowersW, - Time /* rxDuration */, TxPsdFlag /* psdFlag */) + Time /* rxDuration */) { //The total RX power corresponds to the maximum over all the bands auto it = std::max_element (rxPowersW.begin (), rxPowersW.end (), diff --git a/src/wifi/model/phy-entity.h b/src/wifi/model/phy-entity.h index 820b8ed67..d1aec0487 100644 --- a/src/wifi/model/phy-entity.h +++ b/src/wifi/model/phy-entity.h @@ -27,7 +27,6 @@ #include "wifi-tx-vector.h" #include "wifi-phy-band.h" #include "wifi-ppdu.h" -#include "wifi-spectrum-signal-parameters.h" #include "wifi-mpdu-type.h" #include "wifi-ppdu.h" #include "ns3/event-id.h" @@ -346,10 +345,9 @@ public: * \param ppdu the arriving PPDU * \param rxPowersW the receive power in W per band * \param rxDuration the duration of the PPDU - * \param psdFlag the flag indicating the type of Tx PSD to build */ virtual void StartReceivePreamble (Ptr ppdu, RxPowerWattPerChannelBand rxPowersW, - Time rxDuration, TxPsdFlag psdFlag); + Time rxDuration); /** * Start receiving a given field. * diff --git a/src/wifi/model/spectrum-wifi-phy.cc b/src/wifi/model/spectrum-wifi-phy.cc index a7d2f7875..461642247 100644 --- a/src/wifi/model/spectrum-wifi-phy.cc +++ b/src/wifi/model/spectrum-wifi-phy.cc @@ -31,6 +31,7 @@ #include "ns3/simulator.h" #include "spectrum-wifi-phy.h" #include "wifi-spectrum-phy-interface.h" +#include "wifi-spectrum-signal-parameters.h" #include "wifi-utils.h" #include "he-ppdu.h" //TODO: remove this once code ported to HePhy #include "wifi-psdu.h" @@ -360,7 +361,7 @@ SpectrumWifiPhy::StartRx (Ptr rxParams) NS_LOG_INFO ("Received Wi-Fi signal"); Ptr ppdu = wifiRxParams->ppdu->Copy (); - StartReceivePreamble (ppdu, rxPowerW, rxDuration, wifiRxParams->txPsdFlag); + StartReceivePreamble (ppdu, rxPowerW, rxDuration); } Ptr @@ -386,12 +387,12 @@ SpectrumWifiPhy::CreateWifiSpectrumPhyInterface (Ptr device) } Ptr -SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr ppdu, TxPsdFlag flag /* = PSD_NON_HE_TB */) +SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr ppdu) { WifiTxVector txVector = ppdu->GetTxVector (); uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector); uint16_t channelWidth = txVector.GetChannelWidth (); - NS_LOG_FUNCTION (centerFrequency << channelWidth << txPowerW << flag); + NS_LOG_FUNCTION (centerFrequency << channelWidth << txPowerW); Ptr v; switch (ppdu->GetModulation ()) { @@ -411,26 +412,31 @@ SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr ppdu, m_txMaskInnerBandMinimumRejection, m_txMaskOuterBandMinimumRejection, m_txMaskOuterBandMaximumRejection); break; case WIFI_MOD_CLASS_HE: - if (flag == PSD_HE_TB_OFDMA_PORTION) - { - //TODO Move this to HePhy - const auto hePhy = DynamicCast (GetPhyEntity (WIFI_MOD_CLASS_HE)); - WifiSpectrumBand band = hePhy->GetRuBand (txVector, hePhy->GetStaId (ppdu)); - v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band); - } - else - { - if (flag == PSD_HE_TB_NON_OFDMA_PORTION) - { - //non-OFDMA portion is sent only on the 20 MHz channels covering the RU - uint16_t staId = GetPhyEntity (WIFI_MOD_CLASS_HE)->GetStaId (ppdu); - centerFrequency = GetCenterFrequencyForNonOfdmaPart (txVector, staId); - uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType); - channelWidth = ruWidth < 20 ? 20 : ruWidth; - } - v = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), - m_txMaskInnerBandMinimumRejection, m_txMaskOuterBandMinimumRejection, m_txMaskOuterBandMaximumRejection); - } + { + //TODO: Move this to HePhy + auto hePpdu = DynamicCast (ppdu); + NS_ASSERT (hePpdu); + HePpdu::TxPsdFlag flag = hePpdu->GetTxPsdFlag (); + if (flag == HePpdu::PSD_HE_TB_OFDMA_PORTION) + { + const auto hePhy = DynamicCast (GetPhyEntity (WIFI_MOD_CLASS_HE)); + WifiSpectrumBand band = hePhy->GetRuBand (txVector, hePhy->GetStaId (ppdu)); + v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band); + } + else + { + if (flag == HePpdu::PSD_HE_TB_NON_OFDMA_PORTION) + { + //non-OFDMA portion is sent only on the 20 MHz channels covering the RU + uint16_t staId = GetPhyEntity (WIFI_MOD_CLASS_HE)->GetStaId (ppdu); + centerFrequency = GetCenterFrequencyForNonOfdmaPart (txVector, staId); + uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType); + channelWidth = ruWidth < 20 ? 20 : ruWidth; + } + v = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), + m_txMaskInnerBandMinimumRejection, m_txMaskOuterBandMinimumRejection, m_txMaskOuterBandMaximumRejection); + } + } break; default: NS_FATAL_ERROR ("modulation class unknown"); @@ -458,6 +464,7 @@ uint16_t SpectrumWifiPhy::GetCenterFrequencyForNonOfdmaPart (WifiTxVector txVector, uint16_t staId) const { NS_LOG_FUNCTION (this << txVector << staId); + //TODO Move this to HePhy NS_ASSERT (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB); uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector); uint16_t currentWidth = txVector.GetChannelWidth (); @@ -485,32 +492,32 @@ SpectrumWifiPhy::StartTx (Ptr ppdu, uint8_t txPowerLevel) NS_ASSERT_MSG (m_wifiSpectrumPhyInterface, "SpectrumPhy() is not set; maybe forgot to call CreateWifiSpectrumPhyInterface?"); if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB) { - double txPowerWatts = DbmToW (GetTxPowerForTransmission (txVector, ppdu->GetStaId (), PSD_HE_TB_NON_OFDMA_PORTION) + GetTxGain ()); //enforce power density limit on non-OFDMA part + //TODO Move this to HePhy + double txPowerWatts = DbmToW (GetTxPowerForTransmission (ppdu) + GetTxGain ()); //enforce power density limit on non-OFDMA part NS_LOG_DEBUG ("Start transmission: signal power before antenna gain=" << WToDbm (txPowerWatts) << "dBm"); //non-OFDMA part - //TODO Move this to HePhy auto hePhy = DynamicCast (GetPhyEntity (txVector.GetModulationClass ())); Time nonOfdmaDuration = hePhy->CalculateNonOfdmaDurationForHeTb (txVector); - Ptr txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu, PSD_HE_TB_NON_OFDMA_PORTION); + Ptr txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu); Ptr txParams = Create (); txParams->duration = nonOfdmaDuration; txParams->psd = txPowerSpectrum; txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject (); txParams->txAntenna = m_antenna; txParams->ppdu = ppdu; - txParams->txPsdFlag = PSD_HE_TB_NON_OFDMA_PORTION; NS_LOG_DEBUG ("Starting non-OFDMA transmission with power " << WToDbm (txPowerWatts) << " dBm on channel " << +GetChannelNumber () << " for " << txParams->duration.GetMicroSeconds () << " us"); NS_LOG_DEBUG ("Starting non-OFDMA transmission with integrated spectrum power " << WToDbm (Integral (*txPowerSpectrum)) << " dBm; spectrum model Uid: " << txPowerSpectrum->GetSpectrumModel ()->GetUid ()); Transmit (txParams); //OFDMA part - txPowerWatts = DbmToW (GetTxPowerForTransmission (txVector, ppdu->GetStaId (), PSD_HE_TB_OFDMA_PORTION) + GetTxGain ()); //enforce power density limit since transmission bandwidth of RU is potentially narrower than total PPDU bandwidth - Simulator::Schedule (nonOfdmaDuration, &SpectrumWifiPhy::StartOfdmaTx, this, ppdu, txPowerWatts); + auto hePpdu = DynamicCast (ppdu); + NS_ASSERT (hePpdu); + Simulator::Schedule (nonOfdmaDuration, &SpectrumWifiPhy::StartOfdmaTx, this, hePpdu); } else { - double txPowerWatts = DbmToW (GetTxPowerForTransmission (txVector) + GetTxGain ()); + double txPowerWatts = DbmToW (GetTxPowerForTransmission (ppdu) + GetTxGain ()); NS_LOG_DEBUG ("Start transmission: signal power before antenna gain=" << WToDbm (txPowerWatts) << "dBm"); Ptr txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu); Ptr txParams = Create (); @@ -526,22 +533,23 @@ SpectrumWifiPhy::StartTx (Ptr ppdu, uint8_t txPowerLevel) } void -SpectrumWifiPhy::StartOfdmaTx (Ptr ppdu, double txPowerWatts) +SpectrumWifiPhy::StartOfdmaTx (Ptr ppdu) { - NS_LOG_FUNCTION (this << ppdu << txPowerWatts); + NS_LOG_FUNCTION (this << ppdu); //TODO: Move this to HePhy - NS_ASSERT (DynamicCast (ppdu)->GetType () == WIFI_PPDU_TYPE_UL_MU); - Ptr txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu, PSD_HE_TB_OFDMA_PORTION); + NS_ASSERT (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU); + ppdu->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION); + double txPowerWatts = DbmToW (GetTxPowerForTransmission (ppdu) + GetTxGain ()); //enforce power density limit since transmission bandwidth of RU is potentially narrower than total PPDU bandwidth + + Ptr txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu); Ptr txParams = Create (); WifiTxVector txVector = ppdu->GetTxVector (); - //TODO Move this to HePhy auto hePhy = DynamicCast (GetPhyEntity (txVector.GetModulationClass ())); txParams->duration = ppdu->GetTxDuration () - hePhy->CalculateNonOfdmaDurationForHeTb (txVector); txParams->psd = txPowerSpectrum; txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject (); txParams->txAntenna = m_antenna; txParams->ppdu = ppdu; - txParams->txPsdFlag = PSD_HE_TB_OFDMA_PORTION; NS_LOG_DEBUG ("Starting OFDMA transmission with power " << WToDbm (txPowerWatts) << " dBm on channel " << +GetChannelNumber () << " for " << txParams->duration.GetMicroSeconds () << " us"); NS_LOG_DEBUG ("Starting OFDMA transmission with integrated spectrum power " << WToDbm (Integral (*txPowerSpectrum)) << " dBm; spectrum model Uid: " << txPowerSpectrum->GetSpectrumModel ()->GetUid ()); Transmit (txParams); diff --git a/src/wifi/model/spectrum-wifi-phy.h b/src/wifi/model/spectrum-wifi-phy.h index 522698cfd..1acc39143 100644 --- a/src/wifi/model/spectrum-wifi-phy.h +++ b/src/wifi/model/spectrum-wifi-phy.h @@ -35,7 +35,8 @@ namespace ns3 { class WifiSpectrumPhyInterface; -class WifiPpdu; +struct WifiSpectrumSignalParameters; +class HePpdu; //TODO revert to WifiPpdu once Tx refactoring is finished /** * \brief 802.11 PHY layer model @@ -191,13 +192,12 @@ private: /** * \param txPowerW power in W to spread across the bands * \param ppdu the PPDU that will be transmitted - * \param flag flag indicating the type of Tx PSD to build * \return Pointer to SpectrumValue * * This is a helper function to create the right TX PSD corresponding * to the standard in use. */ - Ptr GetTxPowerSpectralDensity (double txPowerW, Ptr ppdu, TxPsdFlag flag = PSD_NON_HE_TB); + Ptr GetTxPowerSpectralDensity (double txPowerW, Ptr ppdu); /** * \param channelWidth the total channel width (MHz) used for the OFDMA transmission @@ -211,10 +211,9 @@ private: /** * This function is called to send the OFDMA part of a PPDU. * - * \param ppdu the PPDU to send - * \param txPowerWatts the transmit power in watts + * \param ppdu the HE PPDU to send */ - void StartOfdmaTx (Ptr ppdu, double txPowerWatts); + void StartOfdmaTx (Ptr ppdu); /** * This function is sending the signal to the Spectrum channel diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index a63a8ab3c..7cf146c00 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -44,6 +44,7 @@ #include "dsss-phy.h" #include "erp-ofdm-phy.h" #include "he-phy.h" //includes OFDM, HT, and VHT +#include "he-ppdu.h" //TODO: remove this once code ported to HePhy namespace ns3 { @@ -2105,7 +2106,10 @@ WifiPhy::Send (WifiConstPsduMap psdus, WifiTxVector txVector) return; } - double txPowerW = DbmToW (GetTxPowerForTransmission (txVector) + GetTxGain ()); + Ptr ppdu = GetPhyEntity (txVector.GetModulationClass ())->BuildPpdu (psdus, txVector, txDuration); + m_previouslyRxPpduUid = UINT64_MAX; //reset (after creation of PPDU) to use it only once + + double txPowerW = DbmToW (GetTxPowerForTransmission (ppdu) + GetTxGain ()); NotifyTxBegin (psdus, txPowerW); m_phyTxPsduBeginTrace (psdus, txVector, txPowerW); for (auto const& psdu : psdus) @@ -2114,9 +2118,6 @@ WifiPhy::Send (WifiConstPsduMap psdus, WifiTxVector txVector) } m_state->SwitchToTx (txDuration, psdus, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector); - Ptr ppdu = GetPhyEntity (txVector.GetModulationClass ())->BuildPpdu (psdus, txVector, txDuration); - m_previouslyRxPpduUid = UINT64_MAX; //reset (after creation of PPDU) to use it only once - if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhyState::TX) < txDuration) { ppdu->SetTruncatedTx (); @@ -2151,14 +2152,13 @@ WifiPhy::Reset (void) } void -WifiPhy::StartReceivePreamble (Ptr ppdu, RxPowerWattPerChannelBand rxPowersW, - Time rxDuration, TxPsdFlag psdFlag /* = PSD_NON_HE_TB */) +WifiPhy::StartReceivePreamble (Ptr ppdu, RxPowerWattPerChannelBand rxPowersW, Time rxDuration) { WifiModulationClass modulation = ppdu->GetTxVector ().GetModulationClass (); auto it = m_phyEntities.find (modulation); if (it != m_phyEntities.end ()) { - it->second->StartReceivePreamble (ppdu, rxPowersW, rxDuration, psdFlag); + it->second->StartReceivePreamble (ppdu, rxPowersW, rxDuration); } else { @@ -2480,9 +2480,10 @@ WifiPhy::ResetCca (bool powerRestricted, double txPowerMaxSiso, double txPowerMa } double -WifiPhy::GetTxPowerForTransmission (WifiTxVector txVector, uint16_t staId /* = SU_STA_ID */, TxPsdFlag flag /* = PSD_NON_HE_TB */) const +WifiPhy::GetTxPowerForTransmission (Ptr ppdu) const { - NS_LOG_FUNCTION (this << m_powerRestricted << txVector << staId << flag); + NS_LOG_FUNCTION (this << m_powerRestricted << ppdu); + WifiTxVector txVector = ppdu->GetTxVector (); // Get transmit power before antenna gain double txPowerDbm; if (!m_powerRestricted) @@ -2503,17 +2504,21 @@ WifiPhy::GetTxPowerForTransmission (WifiTxVector txVector, uint16_t staId /* = S //Apply power density constraint on EIRP uint16_t channelWidth = txVector.GetChannelWidth (); - if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && staId != SU_STA_ID) + //TODO: Move to HePhy + if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && ppdu->GetStaId () != SU_STA_ID) { - NS_ASSERT (flag > PSD_NON_HE_TB); - uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType); - channelWidth = (flag == PSD_HE_TB_NON_OFDMA_PORTION && ruWidth < 20) ? 20 : ruWidth; - NS_LOG_INFO ("Use channelWidth=" << channelWidth << " MHz for HE TB from " << staId << " for " << flag); + auto hePpdu = DynamicCast (ppdu); + NS_ASSERT (hePpdu); + HePpdu::TxPsdFlag flag = hePpdu->GetTxPsdFlag (); + NS_ASSERT (flag > HePpdu::PSD_NON_HE_TB); + uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (ppdu->GetStaId ()).ruType); + channelWidth = (flag == HePpdu::PSD_HE_TB_NON_OFDMA_PORTION && ruWidth < 20) ? 20 : ruWidth; + NS_LOG_INFO ("Use channelWidth=" << channelWidth << " MHz for HE TB from " << ppdu->GetStaId () << " for " << flag); } double txPowerDbmPerMhz = (txPowerDbm + GetTxGain ()) - RatioToDb (channelWidth); //account for antenna gain since EIRP NS_LOG_INFO ("txPowerDbm=" << txPowerDbm << " with txPowerDbmPerMhz=" << txPowerDbmPerMhz << " over " << channelWidth << " MHz"); txPowerDbm = std::min (txPowerDbmPerMhz, m_powerDensityLimit) + RatioToDb (channelWidth); - txPowerDbm -= GetTxGain(); //remove antenna gain since will be added right afterwards + txPowerDbm -= GetTxGain (); //remove antenna gain since will be added right afterwards NS_LOG_INFO ("txPowerDbm=" << txPowerDbm << " after applying m_powerDensityLimit=" << m_powerDensityLimit); return txPowerDbm; } diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index a08d8fc35..3d9941856 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -121,10 +121,8 @@ public: * \param ppdu the arriving PPDU * \param rxPowersW the receive power in W per band * \param rxDuration the duration of the PPDU - * \param psdFlag the flag indicating the type of Tx PSD to build */ - void StartReceivePreamble (Ptr ppdu, RxPowerWattPerChannelBand rxPowersW, - Time rxDuration, TxPsdFlag psdFlag = PSD_NON_HE_TB); + void StartReceivePreamble (Ptr ppdu, RxPowerWattPerChannelBand rxPowersW, Time rxDuration); /** * Reset PHY at the end of the packet under reception after it has failed the PHY header. @@ -969,12 +967,10 @@ public: * The returned power will satisfy the power density constraints * after addition of antenna gain. * - * \param txVector the TXVECTOR - * \param staId the STA-ID of the transmitting station, only applicable for HE TB PPDU - * \param flag flag indicating the type of Tx PSD to build + * \param ppdu the PPDU to transmit * \return the transmit power in dBm for the next transmission */ - double GetTxPowerForTransmission (WifiTxVector txVector, uint16_t staId = SU_STA_ID, TxPsdFlag flag = PSD_NON_HE_TB) const; + double GetTxPowerForTransmission (Ptr ppdu) const; /** * Notify the PHY that an access to the channel was requested. * This is typically called by the channel access manager to diff --git a/src/wifi/model/wifi-spectrum-signal-parameters.cc b/src/wifi/model/wifi-spectrum-signal-parameters.cc index d598491d5..23f3b1e2e 100644 --- a/src/wifi/model/wifi-spectrum-signal-parameters.cc +++ b/src/wifi/model/wifi-spectrum-signal-parameters.cc @@ -37,7 +37,6 @@ WifiSpectrumSignalParameters::WifiSpectrumSignalParameters (const WifiSpectrumSi { NS_LOG_FUNCTION (this << &p); ppdu = p.ppdu; - txPsdFlag = p.txPsdFlag; } Ptr diff --git a/src/wifi/model/wifi-spectrum-signal-parameters.h b/src/wifi/model/wifi-spectrum-signal-parameters.h index 2738bde93..01f165bf0 100644 --- a/src/wifi/model/wifi-spectrum-signal-parameters.h +++ b/src/wifi/model/wifi-spectrum-signal-parameters.h @@ -28,44 +28,6 @@ namespace ns3 { class WifiPpdu; -/** - * \ingroup wifi - * - * The transmit power spectral density flag, namely used - * to correctly build PSD for HE TB PPDU non-OFDMA and - * OFDMA portions. - */ -enum TxPsdFlag -{ - PSD_NON_HE_TB = 0, //!< non-HE TB PPDU transmissions - PSD_HE_TB_NON_OFDMA_PORTION, //!< preamble of HE TB PPDU, which should only be sent on minimum subset of 20 MHz channels containing RU - PSD_HE_TB_OFDMA_PORTION //!< OFDMA portion of HE TB PPDU, which should only be sent on RU -}; - -/** -* \brief Stream insertion operator. -* -* \param os the stream -* \param flag the transmit power spectral density flag -* \returns a reference to the stream -*/ -inline std::ostream& operator<< (std::ostream& os, TxPsdFlag flag) -{ - switch (flag) - { - case PSD_NON_HE_TB: - return (os << "PSD_NON_HE_TB"); - case PSD_HE_TB_NON_OFDMA_PORTION: - return (os << "PSD_HE_TB_NON_OFDMA_PORTION"); - case PSD_HE_TB_OFDMA_PORTION: - return (os << "PSD_HE_TB_OFDMA_PORTION"); - default: - NS_FATAL_ERROR ("Invalid PSD flag"); - return (os << "INVALID"); - } -} - - /** * \ingroup wifi * @@ -90,7 +52,6 @@ struct WifiSpectrumSignalParameters : public SpectrumSignalParameters WifiSpectrumSignalParameters (const WifiSpectrumSignalParameters& p); Ptr ppdu; ///< The PPDU being transmitted - TxPsdFlag txPsdFlag {PSD_NON_HE_TB}; ///< The transmit power spectral density flag }; } // namespace ns3 diff --git a/src/wifi/model/yans-wifi-phy.cc b/src/wifi/model/yans-wifi-phy.cc index bc356378e..9b661fb29 100644 --- a/src/wifi/model/yans-wifi-phy.cc +++ b/src/wifi/model/yans-wifi-phy.cc @@ -86,7 +86,7 @@ YansWifiPhy::StartTx (Ptr ppdu, uint8_t txPowerLevel) WifiTxVector txVector = ppdu->GetTxVector (); txVector.SetTxPowerLevel (txPowerLevel); NS_LOG_DEBUG ("Start transmission: signal power before antenna gain=" << GetPowerDbm (txVector.GetTxPowerLevel ()) << "dBm"); - m_channel->Send (this, ppdu, GetTxPowerForTransmission (txVector) + GetTxGain ()); + m_channel->Send (this, ppdu, GetTxPowerForTransmission (ppdu) + GetTxGain ()); } } //namespace ns3 diff --git a/src/wifi/test/wifi-phy-ofdma-test.cc b/src/wifi/test/wifi-phy-ofdma-test.cc index e606521e9..bd7616c7f 100644 --- a/src/wifi/test/wifi-phy-ofdma-test.cc +++ b/src/wifi/test/wifi-phy-ofdma-test.cc @@ -1447,7 +1447,8 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo psdus.insert (std::make_pair (staId, psdu)); Time ppduDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand (), staId); - Ptr ppdu = Create (psdus, txVector, ppduDuration, WIFI_PHY_BAND_5GHZ, uid); + Ptr ppdu = Create (psdus, txVector, ppduDuration, WIFI_PHY_BAND_5GHZ, uid, + HePpdu::PSD_HE_TB_NON_OFDMA_PORTION); //Send non-OFDMA part Time nonOfdmaDuration = m_phy->GetHePhy ()->CalculateNonOfdmaDurationForHeTb (txVector); @@ -1460,11 +1461,11 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo rxParams->txPhy = 0; rxParams->duration = nonOfdmaDuration; rxParams->ppdu = ppdu; - rxParams->txPsdFlag = PSD_HE_TB_NON_OFDMA_PORTION; m_phy->StartRx (rxParams); //Schedule OFDMA part + ppdu->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION); WifiSpectrumBand band = m_phy->GetHePhy ()->GetRuBand (txVector, staId); Ptr rxPsdOfdma = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (DEFAULT_FREQUENCY, DEFAULT_CHANNEL_WIDTH, txPowerWatts, DEFAULT_GUARD_WIDTH, band); Ptr rxParamsOfdma = Create (); @@ -1472,7 +1473,6 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo rxParamsOfdma->txPhy = 0; rxParamsOfdma->duration = ppduDuration - nonOfdmaDuration; rxParamsOfdma->ppdu = ppdu; - rxParamsOfdma->txPsdFlag = PSD_HE_TB_OFDMA_PORTION; Simulator::Schedule (nonOfdmaDuration, &TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart, this, rxParamsOfdma); }