diff --git a/src/wifi/model/he-phy.cc b/src/wifi/model/he-phy.cc index 1d465c991..7e675cbc3 100644 --- a/src/wifi/model/he-phy.cc +++ b/src/wifi/model/he-phy.cc @@ -871,6 +871,54 @@ HePhy::StartTx (Ptr ppdu) } } +uint16_t +HePhy::GetTransmissionChannelWidth (Ptr ppdu) const +{ + WifiTxVector txVector = ppdu->GetTxVector (); + if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && ppdu->GetStaId () != SU_STA_ID) + { + 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); + uint16_t 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); + return channelWidth; + } + else + { + return PhyEntity::GetTransmissionChannelWidth (ppdu); + } +} + +Time +HePhy::CalculateTxDuration (WifiConstPsduMap psduMap, WifiTxVector txVector, WifiPhyBand band) const +{ + if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB) + { + return ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (), txVector, band); + } + + Time maxDuration = Seconds (0); + for (auto & staIdPsdu : psduMap) + { + if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU) + { + WifiTxVector::HeMuUserInfoMap userInfoMap = txVector.GetHeMuUserInfoMap (); + NS_ABORT_MSG_IF (userInfoMap.find (staIdPsdu.first) == userInfoMap.end (), "STA-ID in psduMap (" << staIdPsdu.first << ") should be referenced in txVector"); + } + Time current = WifiPhy::CalculateTxDuration (staIdPsdu.second->GetSize (), txVector, band, + staIdPsdu.first); + if (current > maxDuration) + { + maxDuration = current; + } + } + NS_ASSERT (maxDuration.IsStrictlyPositive ()); + return maxDuration; +} + void HePhy::InitializeModes (void) { diff --git a/src/wifi/model/he-phy.h b/src/wifi/model/he-phy.h index 3b149656c..6709991ca 100644 --- a/src/wifi/model/he-phy.h +++ b/src/wifi/model/he-phy.h @@ -79,6 +79,8 @@ public: virtual uint16_t GetStaId (const Ptr ppdu) const override; uint16_t GetMeasurementChannelWidth (const Ptr ppdu) const override; void StartTx (Ptr ppdu) override; + uint16_t GetTransmissionChannelWidth (Ptr ppdu) const override; + Time CalculateTxDuration (WifiConstPsduMap psduMap, WifiTxVector txVector, WifiPhyBand band) const override; /** * \return the BSS color of this PHY. diff --git a/src/wifi/model/interference-helper.cc b/src/wifi/model/interference-helper.cc index 576729b40..1a10b611c 100644 --- a/src/wifi/model/interference-helper.cc +++ b/src/wifi/model/interference-helper.cc @@ -28,7 +28,6 @@ #include "wifi-phy.h" #include "error-rate-model.h" #include "wifi-utils.h" -#include "he-ppdu.h" //TODO: remove this once code ported to HePhy #include "wifi-psdu.h" namespace ns3 { diff --git a/src/wifi/model/phy-entity.cc b/src/wifi/model/phy-entity.cc index 39b8fd2e7..f3235b407 100644 --- a/src/wifi/model/phy-entity.cc +++ b/src/wifi/model/phy-entity.cc @@ -1065,4 +1065,18 @@ PhyEntity::GetTxMaskRejectionParams (void) const return m_wifiPhy->GetTxMaskRejectionParams (); } +uint16_t +PhyEntity::GetTransmissionChannelWidth (Ptr ppdu) const +{ + return ppdu->GetTxVector ().GetChannelWidth (); +} + +Time +PhyEntity::CalculateTxDuration (WifiConstPsduMap psduMap, WifiTxVector txVector, WifiPhyBand band) const +{ + NS_ASSERT (psduMap.size () == 1); + const auto & it = psduMap.begin (); + return WifiPhy::CalculateTxDuration (it->second->GetSize (), txVector, band, it->first); +} + } //namespace ns3 diff --git a/src/wifi/model/phy-entity.h b/src/wifi/model/phy-entity.h index 9c6e5b726..b74c7bbf1 100644 --- a/src/wifi/model/phy-entity.h +++ b/src/wifi/model/phy-entity.h @@ -443,6 +443,24 @@ public: */ void Transmit (Time txDuration, Ptr ppdu, std::string type); + /** + * Get the channel width over which the PPDU will be effectively + * be transmitted. + * + * \param ppdu the PPDU to send + * \return the effective channel width (in MHz) used for the tranmsission + */ + virtual uint16_t GetTransmissionChannelWidth (Ptr ppdu) const; + + /** + * \param psduMap the PSDU(s) to transmit indexed by STA-ID + * \param txVector the TXVECTOR used for the transmission of the PPDU + * \param band the frequency band being used + * + * \return the total amount of time this PHY will stay busy for the transmission of the PPDU + */ + virtual Time CalculateTxDuration (WifiConstPsduMap psduMap, WifiTxVector txVector, WifiPhyBand band) const; + protected: /** * A map of PPDU field elements per preamble type. diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index 8fd939731..94c17c743 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -44,7 +44,6 @@ #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 { @@ -1879,28 +1878,7 @@ WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txVector, WifiPhyBand Time WifiPhy::CalculateTxDuration (WifiConstPsduMap psduMap, WifiTxVector txVector, WifiPhyBand band) { - //TODO: Move this logic to HePhy - if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB) - { - return HePhy::ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (), txVector, band); - } - - Time maxDuration = Seconds (0); - for (auto & staIdPsdu : psduMap) - { - if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU) - { - WifiTxVector::HeMuUserInfoMap userInfoMap = txVector.GetHeMuUserInfoMap (); - NS_ABORT_MSG_IF (userInfoMap.find (staIdPsdu.first) == userInfoMap.end (), "STA-ID in psduMap (" << staIdPsdu.first << ") should be referenced in txVector"); - } - Time current = CalculateTxDuration (staIdPsdu.second->GetSize (), txVector, band, staIdPsdu.first); - if (current > maxDuration) - { - maxDuration = current; - } - } - NS_ASSERT (maxDuration.IsStrictlyPositive ()); - return maxDuration; + return GetStaticPhyEntity (txVector.GetModulationClass ())->CalculateTxDuration (psduMap, txVector, band); } void @@ -2503,18 +2481,7 @@ WifiPhy::GetTxPowerForTransmission (Ptr ppdu) const } //Apply power density constraint on EIRP - uint16_t channelWidth = txVector.GetChannelWidth (); - //TODO: Move to HePhy - if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && ppdu->GetStaId () != SU_STA_ID) - { - 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); - } + uint16_t channelWidth = GetPhyEntity (txVector.GetModulationClass ())->GetTransmissionChannelWidth (ppdu); 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);