From b651bee25996bd5338cd34d1bcf5b0e6c337ca39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Wed, 9 Nov 2022 22:18:36 +0100 Subject: [PATCH] wifi: Add PHY support for MU-RTS procedure --- src/wifi/model/he/he-phy.cc | 74 ++++++++++++++++++++++++------- src/wifi/model/non-ht/ofdm-phy.cc | 14 +++--- src/wifi/model/phy-entity.cc | 10 ++--- src/wifi/model/phy-entity.h | 18 ++++---- src/wifi/model/wifi-phy.cc | 2 +- 5 files changed, 81 insertions(+), 37 deletions(-) diff --git a/src/wifi/model/he/he-phy.cc b/src/wifi/model/he/he-phy.cc index 1b34d10c3..40869e3c1 100644 --- a/src/wifi/model/he/he-phy.cc +++ b/src/wifi/model/he/he-phy.cc @@ -447,19 +447,35 @@ HePhy::DoGetEvent(Ptr ppdu, RxPowerWattPerChannelBand& rxPowersW // detection window. If a preamble is received after the preamble detection window, it is stored // anyway because this is needed for HE TB PPDUs in order to properly update the received power // in InterferenceHelper. The map is cleaned anyway at the end of the current reception. - if (ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU) + auto uidPreamblePair = std::make_pair(ppdu->GetUid(), ppdu->GetPreamble()); + const auto& currentPreambleEvents = GetCurrentPreambleEvents(); + auto it = currentPreambleEvents.find(uidPreamblePair); + bool isResponseToTrigger = (m_previouslyTxPpduUid == ppdu->GetUid()); + if (ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU || isResponseToTrigger) { - auto uidPreamblePair = std::make_pair(ppdu->GetUid(), ppdu->GetPreamble()); const auto& txVector = ppdu->GetTxVector(); - Time rxDuration = CalculateNonOfdmaDurationForHeTb( - txVector); // the OFDMA part of the transmission will be added later on - const auto& currentPreambleEvents = GetCurrentPreambleEvents(); - auto it = currentPreambleEvents.find(uidPreamblePair); + Time rxDuration; + if (ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU) + { + rxDuration = CalculateNonOfdmaDurationForHeTb( + txVector); // the OFDMA part of the transmission will be added later on + } + else + { + rxDuration = ppdu->GetTxDuration(); + } if (it != currentPreambleEvents.end()) { - NS_LOG_DEBUG("Received another HE TB PPDU for UID " - << ppdu->GetUid() << " from STA-ID " << ppdu->GetStaId() - << " and BSS color " << +txVector.GetBssColor()); + if (ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU) + { + NS_LOG_DEBUG("Received another HE TB PPDU for UID " + << ppdu->GetUid() << " from STA-ID " << ppdu->GetStaId() + << " and BSS color " << +txVector.GetBssColor()); + } + else + { + NS_LOG_DEBUG("Received another response to a trigger frame " << ppdu->GetUid()); + } event = it->second; auto heConfiguration = m_wifiPhy->GetDevice()->GetHeConfiguration(); @@ -490,18 +506,33 @@ HePhy::DoGetEvent(Ptr ppdu, RxPowerWattPerChannelBand& rxPowersW UpdateInterferenceEvent(event, rxPowersW); } - if (GetCurrentEvent() && (GetCurrentEvent()->GetPpdu()->GetUid() != ppdu->GetUid())) + if (ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU && GetCurrentEvent() && + (GetCurrentEvent()->GetPpdu()->GetUid() != ppdu->GetUid())) { NS_LOG_DEBUG("Drop packet because already receiving another HE TB PPDU"); m_wifiPhy->NotifyRxDrop(GetAddressedPsduInPpdu(ppdu), RXING); } + else if (isResponseToTrigger && GetCurrentEvent() && + (GetCurrentEvent()->GetPpdu()->GetUid() != ppdu->GetUid())) + { + NS_LOG_DEBUG( + "Drop packet because already receiving another response to a trigger frame"); + m_wifiPhy->NotifyRxDrop(GetAddressedPsduInPpdu(ppdu), RXING); + } return nullptr; } else { - NS_LOG_DEBUG("Received a new HE TB PPDU for UID " - << ppdu->GetUid() << " from STA-ID " << ppdu->GetStaId() - << " and BSS color " << +txVector.GetBssColor()); + if (ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU) + { + NS_LOG_DEBUG("Received a new HE TB PPDU for UID " + << ppdu->GetUid() << " from STA-ID " << ppdu->GetStaId() + << " and BSS color " << +txVector.GetBssColor()); + } + else + { + NS_LOG_DEBUG("Received response to a trigger frame for UID " << ppdu->GetUid()); + } event = CreateInterferenceEvent(ppdu, txVector, rxDuration, rxPowersW); AddPreambleEvent(event); } @@ -516,7 +547,19 @@ HePhy::DoGetEvent(Ptr ppdu, RxPowerWattPerChannelBand& rxPowersW } else { - event = PhyEntity::DoGetEvent(ppdu, rxPowersW); + if (it == currentPreambleEvents.end()) + { + event = PhyEntity::DoGetEvent(ppdu, rxPowersW); + } + else + { + NS_LOG_DEBUG( + "Update received power of the event associated to these UL transmissions with UID " + << ppdu->GetUid()); + event = it->second; + UpdateInterferenceEvent(event, rxPowersW); + return nullptr; + } } return event; } @@ -1243,9 +1286,8 @@ HePhy::ObtainNextUid(const WifiTxVector& txVector) { NS_LOG_FUNCTION(this << txVector); uint64_t uid; - if (txVector.IsUlMu()) + if (txVector.IsUlMu() || txVector.IsTriggerResponding()) { - NS_ASSERT(txVector.GetModulationClass() >= WIFI_MOD_CLASS_HE); // Use UID of PPDU containing trigger frame to identify resulting HE TB PPDUs, since the // latter should immediately follow the former uid = m_wifiPhy->GetPreviouslyRxPpduUid(); diff --git a/src/wifi/model/non-ht/ofdm-phy.cc b/src/wifi/model/non-ht/ofdm-phy.cc index 7eaf385bb..ba49d7da2 100644 --- a/src/wifi/model/non-ht/ofdm-phy.cc +++ b/src/wifi/model/non-ht/ofdm-phy.cc @@ -295,12 +295,14 @@ OfdmPhy::BuildPpdu(const WifiConstPsduMap& psdus, Time /* ppduDuration */) { NS_LOG_FUNCTION(this << psdus << txVector); - return Create(psdus.begin()->second, - txVector, - m_wifiPhy->GetOperatingChannel().GetPrimaryChannelCenterFrequency( - txVector.GetChannelWidth()), - m_wifiPhy->GetPhyBand(), - ObtainNextUid(txVector)); + return Create( + psdus.begin()->second, + txVector, + m_wifiPhy->GetOperatingChannel().GetPrimaryChannelCenterFrequency( + txVector.GetChannelWidth()), + m_wifiPhy->GetPhyBand(), + m_wifiPhy->GetLatestPhyEntity()->ObtainNextUid( + txVector)); // use latest PHY entity to handle MU-RTS sent with non-HT rate } PhyEntity::PhyFieldRxStatus diff --git a/src/wifi/model/phy-entity.cc b/src/wifi/model/phy-entity.cc index 9270e8f42..d41f64c1b 100644 --- a/src/wifi/model/phy-entity.cc +++ b/src/wifi/model/phy-entity.cc @@ -239,11 +239,9 @@ PhyEntity::GetPhyHeaderSections(const WifiTxVector& txVector, Time ppduStart) co } Ptr -PhyEntity::BuildPpdu(const WifiConstPsduMap& psdus, - const WifiTxVector& txVector, - Time /* ppduDuration */) +PhyEntity::BuildPpdu(const WifiConstPsduMap& psdus, const WifiTxVector& txVector, Time ppduDuration) { - NS_LOG_FUNCTION(this << psdus << txVector); + NS_LOG_FUNCTION(this << psdus << txVector << ppduDuration); NS_FATAL_ERROR("This method is unsupported for the base PhyEntity class. Use the overloaded " "version in the amendment-specific subclasses instead!"); return Create(psdus.begin()->second, @@ -410,7 +408,9 @@ PhyEntity::StartReceivePreamble(Ptr ppdu, const std::pair& p2) { return p1.second < p2.second; }); NS_LOG_FUNCTION(this << ppdu << it->second); - Ptr event = DoGetEvent(ppdu, rxPowersW); + Ptr event = m_wifiPhy->GetPhyEntityForPpdu(ppdu)->DoGetEvent( + ppdu, + rxPowersW); // use latest PHY entity to handle MU-RTS sent with non-HT rate if (!event) { // PPDU should be simply considered as interference (once it has been accounted for in diff --git a/src/wifi/model/phy-entity.h b/src/wifi/model/phy-entity.h index 6fb4f9081..69e502f3f 100644 --- a/src/wifi/model/phy-entity.h +++ b/src/wifi/model/phy-entity.h @@ -539,6 +539,15 @@ class PhyEntity : public SimpleRefCount */ virtual Ptr GetRxPpduFromTxPpdu(Ptr ppdu); + /** + * Obtain the next UID for the PPDU to transmit. + * Note that the global UID counter could be incremented. + * + * \param txVector the transmission parameters + * \return the UID to use for the PPDU to transmit + */ + virtual uint64_t ObtainNextUid(const WifiTxVector& txVector); + protected: /** * A map of PPDU field elements per preamble type. @@ -840,15 +849,6 @@ class PhyEntity : public SimpleRefCount */ void NotifyInterferenceRxEndAndClear(bool reset); - /** - * Obtain the next UID for the PPDU to transmit. - * Note that the global UID counter could be incremented. - * - * \param txVector the transmission parameters - * \return the UID to use for the PPDU to transmit - */ - virtual uint64_t ObtainNextUid(const WifiTxVector& txVector); - /** * \param txPowerW power in W to spread across the bands * \param ppdu the PPDU that will be transmitted diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index 95008379b..1b5c20796 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -2166,7 +2166,7 @@ Ptr WifiPhy::GetAddressedPsduInPpdu(Ptr ppdu) const { // TODO: wrapper. See if still needed - return GetLatestPhyEntity()->GetAddressedPsduInPpdu(ppdu); + return GetPhyEntityForPpdu(ppdu)->GetAddressedPsduInPpdu(ppdu); } WifiSpectrumBand