diff --git a/src/wifi/model/he/he-phy.cc b/src/wifi/model/he/he-phy.cc index 360d69c27..a554a5016 100644 --- a/src/wifi/model/he/he-phy.cc +++ b/src/wifi/model/he/he-phy.cc @@ -1773,6 +1773,20 @@ HePhy::CanStartRx(Ptr ppdu) const return PhyEntity::CanStartRx(ppdu); } +Ptr +HePhy::GetRxPpduFromTxPpdu(Ptr ppdu) +{ + // We only copy if the AP that is expecting a HE TB PPDU, since the content + // of the TXVECTOR is reconstructed from the TRIGVECTOR, hence the other RX + // PHYs should not have this information. + if ((ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU) && + (Simulator::Now() <= m_trigVectorExpirationTime)) + { + return ppdu->Copy(); + } + return PhyEntity::GetRxPpduFromTxPpdu(ppdu); +} + } // namespace ns3 namespace diff --git a/src/wifi/model/he/he-phy.h b/src/wifi/model/he/he-phy.h index 1e447dc6f..12b6127f0 100644 --- a/src/wifi/model/he/he-phy.h +++ b/src/wifi/model/he/he-phy.h @@ -115,6 +115,7 @@ class HePhy : public VhtPhy Time duration, WifiChannelListType channelType) override; bool CanStartRx(Ptr ppdu) const override; + Ptr GetRxPpduFromTxPpdu(Ptr ppdu) override; /** * \return the BSS color of this PHY. diff --git a/src/wifi/model/phy-entity.cc b/src/wifi/model/phy-entity.cc index 4cfa1524b..38790b453 100644 --- a/src/wifi/model/phy-entity.cc +++ b/src/wifi/model/phy-entity.cc @@ -1352,4 +1352,10 @@ PhyEntity::CanStartRx(Ptr ppdu) const return ppdu->DoesCoverChannel(p20MinFreq, p20MaxFreq); } +Ptr +PhyEntity::GetRxPpduFromTxPpdu(Ptr ppdu) +{ + return ppdu; +} + } // namespace ns3 diff --git a/src/wifi/model/phy-entity.h b/src/wifi/model/phy-entity.h index b6ae2d651..a3768e0bb 100644 --- a/src/wifi/model/phy-entity.h +++ b/src/wifi/model/phy-entity.h @@ -527,6 +527,17 @@ class PhyEntity : public SimpleRefCount virtual double GetCcaThreshold(const Ptr ppdu, WifiChannelListType channelType) const; + /** + * The WifiPpdu from the TX PHY is received by each RX PHY attached to the same channel. + * By default and for performance reasons, all RX PHYs will work on the same WifiPpdu instance + * from TX instead of a copy of it. Child classes can change that behavior and do a copy and/or + * change the content of the parameters stored in WifiPpdu. + * + * \param ppdu the WifiPpdu transmitted by the TX PHY + * \return the WifiPpdu to be used by the RX PHY + */ + virtual Ptr GetRxPpduFromTxPpdu(Ptr ppdu); + protected: /** * A map of PPDU field elements per preamble type. diff --git a/src/wifi/model/spectrum-wifi-phy.cc b/src/wifi/model/spectrum-wifi-phy.cc index 18096b81f..14a128566 100644 --- a/src/wifi/model/spectrum-wifi-phy.cc +++ b/src/wifi/model/spectrum-wifi-phy.cc @@ -392,7 +392,7 @@ SpectrumWifiPhy::StartRx(Ptr rxParams) // Do no further processing if signal is too weak // Current implementation assumes constant RX power over the PPDU duration // Compare received TX power per MHz to normalized RX sensitivity - const auto& ppdu = wifiRxParams->ppdu; + const auto& ppdu = GetRxPpduFromTxPpdu(wifiRxParams->ppdu); const auto& txVector = ppdu->GetTxVector(); uint16_t txWidth = ppdu->GetTransmissionChannelWidth(); if (totalRxPowerW < DbmToW(GetRxSensitivity()) * (txWidth / 20.0)) @@ -418,6 +418,12 @@ SpectrumWifiPhy::StartRx(Ptr rxParams) StartReceivePreamble(ppdu, rxPowerW, rxDuration); } +Ptr +SpectrumWifiPhy::GetRxPpduFromTxPpdu(Ptr ppdu) +{ + return GetLatestPhyEntity()->GetRxPpduFromTxPpdu(ppdu); +} + Ptr SpectrumWifiPhy::GetAntenna() const { diff --git a/src/wifi/model/spectrum-wifi-phy.h b/src/wifi/model/spectrum-wifi-phy.h index 7182319be..875665443 100644 --- a/src/wifi/model/spectrum-wifi-phy.h +++ b/src/wifi/model/spectrum-wifi-phy.h @@ -152,6 +152,14 @@ class SpectrumWifiPhy : public WifiPhy */ void Transmit(Ptr txParams); + /** + * Determine the WifiPpdu to be used by the RX PHY based on the WifiPpdu sent by the TX PHY. + * + * \param ppdu the WifiPpdu transmitted by the TX PHY + * \return the WifiPpdu to be used by the RX PHY + */ + Ptr GetRxPpduFromTxPpdu(Ptr ppdu); + protected: void DoDispose() override; void DoInitialize() override;