From abddcf82a71974b73fc49373d6cfbea70aea738e Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Tue, 28 Feb 2023 20:01:35 +0100 Subject: [PATCH] wifi: Decouple protection and TX plus acknowledgment ...to make it possible, e.g., to use MU-RTS to protect a SU transmission --- src/wifi/model/frame-exchange-manager.cc | 50 +++++++++++------ src/wifi/model/frame-exchange-manager.h | 12 ++++ .../model/he/he-frame-exchange-manager.cc | 56 +++++++++++++------ src/wifi/model/he/he-frame-exchange-manager.h | 2 + .../model/ht/ht-frame-exchange-manager.cc | 27 +++++---- src/wifi/model/ht/ht-frame-exchange-manager.h | 1 + 6 files changed, 102 insertions(+), 46 deletions(-) diff --git a/src/wifi/model/frame-exchange-manager.cc b/src/wifi/model/frame-exchange-manager.cc index 6fe096c21..78b11f9e2 100644 --- a/src/wifi/model/frame-exchange-manager.cc +++ b/src/wifi/model/frame-exchange-manager.cc @@ -414,20 +414,7 @@ FrameExchangeManager::SendMpduWithProtection(Ptr mpdu, WifiTxParameter m_mpdu->SetInFlight(m_linkId); } - switch (m_txParams.m_protection->method) - { - case WifiProtection::RTS_CTS: - SendRts(m_txParams); - break; - case WifiProtection::CTS_TO_SELF: - SendCtsToSelf(m_txParams); - break; - case WifiProtection::NONE: - SendMpdu(); - break; - default: - NS_ABORT_MSG("Unknown protection type"); - } + StartProtection(m_txParams); if (m_txParams.m_acknowledgment->method == WifiAcknowledgment::NONE) { @@ -436,6 +423,35 @@ FrameExchangeManager::SendMpduWithProtection(Ptr mpdu, WifiTxParameter } } +void +FrameExchangeManager::StartProtection(const WifiTxParameters& txParams) +{ + NS_LOG_FUNCTION(this << &txParams); + + switch (txParams.m_protection->method) + { + case WifiProtection::RTS_CTS: + SendRts(txParams); + break; + case WifiProtection::CTS_TO_SELF: + SendCtsToSelf(txParams); + break; + case WifiProtection::NONE: + ProtectionCompleted(); + break; + default: + NS_ABORT_MSG("Unknown protection type: " << txParams.m_protection.get()); + } +} + +void +FrameExchangeManager::ProtectionCompleted() +{ + NS_LOG_FUNCTION(this); + NS_ASSERT(m_mpdu); + SendMpdu(); +} + void FrameExchangeManager::SendMpdu() { @@ -794,7 +810,9 @@ FrameExchangeManager::SendCtsToSelf(const WifiTxParameters& txParams) Time ctsDuration = m_phy->CalculateTxDuration(GetCtsSize(), ctsToSelfProtection->ctsTxVector, m_phy->GetPhyBand()); - Simulator::Schedule(ctsDuration + m_phy->GetSifs(), &FrameExchangeManager::SendMpdu, this); + Simulator::Schedule(ctsDuration + m_phy->GetSifs(), + &FrameExchangeManager::ProtectionCompleted, + this); } void @@ -1269,7 +1287,7 @@ FrameExchangeManager::ReceiveMpdu(Ptr mpdu, m_txTimer.Cancel(); m_channelAccessManager->NotifyCtsTimeoutResetNow(); - Simulator::Schedule(m_phy->GetSifs(), &FrameExchangeManager::SendMpdu, this); + Simulator::Schedule(m_phy->GetSifs(), &FrameExchangeManager::ProtectionCompleted, this); } else if (hdr.IsAck() && m_mpdu && m_txTimer.IsRunning() && m_txTimer.GetReason() == WifiTxTimer::WAIT_NORMAL_ACK) diff --git a/src/wifi/model/frame-exchange-manager.h b/src/wifi/model/frame-exchange-manager.h index eed89318c..00686af36 100644 --- a/src/wifi/model/frame-exchange-manager.h +++ b/src/wifi/model/frame-exchange-manager.h @@ -299,6 +299,18 @@ class FrameExchangeManager : public Object */ void SendMpduWithProtection(Ptr mpdu, WifiTxParameters& txParams); + /** + * Start the protection mechanism indicated by the given TX parameters + * + * \param txParams the TX parameters + */ + virtual void StartProtection(const WifiTxParameters& txParams); + + /** + * Transmit prepared frame upon successful protection mechanism. + */ + virtual void ProtectionCompleted(); + /** * Update the NAV, if needed, based on the Duration/ID of the given psdu. * diff --git a/src/wifi/model/he/he-frame-exchange-manager.cc b/src/wifi/model/he/he-frame-exchange-manager.cc index 5e234e800..fdffc7260 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.cc +++ b/src/wifi/model/he/he-frame-exchange-manager.cc @@ -282,25 +282,39 @@ HeFrameExchangeManager::SendPsduMapWithProtection(WifiPsduMap psduMap, WifiTxPar } } - if (m_txParams.m_protection->method == WifiProtection::RTS_CTS) + StartProtection(m_txParams); +} + +void +HeFrameExchangeManager::StartProtection(const WifiTxParameters& txParams) +{ + NS_LOG_FUNCTION(this << &txParams); + + NS_ABORT_MSG_IF(m_psduMap.size() > 1 && + txParams.m_protection->method == WifiProtection::RTS_CTS, + "Cannot use RTS/CTS with MU PPDUs"); + if (txParams.m_protection->method == WifiProtection::MU_RTS_CTS) { - NS_ABORT_MSG_IF(m_psduMap.size() > 1, "Cannot use RTS/CTS with MU PPDUs"); - SendRts(m_txParams); - } - else if (m_txParams.m_protection->method == WifiProtection::MU_RTS_CTS) - { - SendMuRts(m_txParams); - } - else if (m_txParams.m_protection->method == WifiProtection::NONE) - { - SendPsduMap(); + SendMuRts(txParams); } else { - NS_ABORT_MSG("Unknown or prohibited protection type: " << m_txParams.m_protection.get()); + VhtFrameExchangeManager::StartProtection(txParams); } } +void +HeFrameExchangeManager::ProtectionCompleted() +{ + NS_LOG_FUNCTION(this); + if (!m_psduMap.empty()) + { + SendPsduMap(); + return; + } + VhtFrameExchangeManager::ProtectionCompleted(); +} + Time HeFrameExchangeManager::GetMuRtsDurationId(uint32_t muRtsSize, const WifiTxVector& muRtsTxVector, @@ -387,7 +401,13 @@ HeFrameExchangeManager::CtsAfterMuRtsTimeout(Ptr muRts, const WifiTxVe { NS_LOG_FUNCTION(this << *muRts << txVector); - NS_ASSERT(!m_psduMap.empty()); + if (m_psduMap.empty()) + { + // A CTS Timeout occurred when protecting a single PSDU that is not included + // in a DL MU PPDU is handled by the parent classes + VhtFrameExchangeManager::CtsTimeout(muRts, txVector); + return; + } for (const auto& psdu : m_psduMap) { @@ -2295,9 +2315,11 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr mpdu, m_txTimer.Cancel(); m_channelAccessManager->NotifyCtsTimeoutResetNow(); - Simulator::Schedule(m_phy->GetSifs(), &HeFrameExchangeManager::SendPsduMap, this); + Simulator::Schedule(m_phy->GetSifs(), + &HeFrameExchangeManager::ProtectionCompleted, + this); } - else if (hdr.IsCts() && !m_psduMap.empty() && m_txTimer.IsRunning() && + else if (hdr.IsCts() && m_txTimer.IsRunning() && m_txTimer.GetReason() == WifiTxTimer::WAIT_CTS_AFTER_MU_RTS) { NS_ABORT_MSG_IF(inAmpdu, "Received CTS as part of an A-MPDU"); @@ -2307,7 +2329,9 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr mpdu, m_txTimer.Cancel(); m_channelAccessManager->NotifyCtsTimeoutResetNow(); - Simulator::Schedule(m_phy->GetSifs(), &HeFrameExchangeManager::SendPsduMap, this); + Simulator::Schedule(m_phy->GetSifs(), + &HeFrameExchangeManager::ProtectionCompleted, + this); } else if (hdr.IsAck() && m_txTimer.IsRunning() && m_txTimer.GetReason() == WifiTxTimer::WAIT_NORMAL_ACK_AFTER_DL_MU_PPDU) diff --git a/src/wifi/model/he/he-frame-exchange-manager.h b/src/wifi/model/he/he-frame-exchange-manager.h index 5515c2cde..b21d192c1 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.h +++ b/src/wifi/model/he/he-frame-exchange-manager.h @@ -156,6 +156,8 @@ class HeFrameExchangeManager : public VhtFrameExchangeManager void CtsTimeout(Ptr rts, const WifiTxVector& txVector) override; void UpdateNav(Ptr psdu, const WifiTxVector& txVector) override; void NavResetTimeout() override; + void StartProtection(const WifiTxParameters& txParams) override; + void ProtectionCompleted() override; /** * Clear the TXOP holder if the intra-BSS NAV counted down to zero (includes the case diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index 3d6affe25..7a5bf536f 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -954,22 +954,19 @@ HtFrameExchangeManager::SendPsduWithProtection(Ptr psdu, WifiTxParamet } } - if (m_txParams.m_protection->method == WifiProtection::RTS_CTS) - { - SendRts(m_txParams); - } - else if (m_txParams.m_protection->method == WifiProtection::CTS_TO_SELF) - { - SendCtsToSelf(m_txParams); - } - else if (m_txParams.m_protection->method == WifiProtection::NONE) + StartProtection(m_txParams); +} + +void +HtFrameExchangeManager::ProtectionCompleted() +{ + NS_LOG_FUNCTION(this); + if (m_psdu) { SendPsdu(); + return; } - else - { - NS_ABORT_MSG("Unknown protection type"); - } + QosFrameExchangeManager::ProtectionCompleted(); } void @@ -1552,7 +1549,9 @@ HtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, m_txTimer.Cancel(); m_channelAccessManager->NotifyCtsTimeoutResetNow(); - Simulator::Schedule(m_phy->GetSifs(), &HtFrameExchangeManager::SendPsdu, this); + Simulator::Schedule(m_phy->GetSifs(), + &HtFrameExchangeManager::ProtectionCompleted, + this); } else if (hdr.IsBlockAck() && m_txTimer.IsRunning() && m_txTimer.GetReason() == WifiTxTimer::WAIT_BLOCK_ACK && hdr.GetAddr1() == m_self) diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.h b/src/wifi/model/ht/ht-frame-exchange-manager.h index 1c982c658..21898681d 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.h +++ b/src/wifi/model/ht/ht-frame-exchange-manager.h @@ -200,6 +200,7 @@ class HtFrameExchangeManager : public QosFrameExchangeManager void FinalizeMacHeader(Ptr psdu) override; void CtsTimeout(Ptr rts, const WifiTxVector& txVector) override; void TransmissionSucceeded() override; + void ProtectionCompleted() override; /** * Get a PSDU containing the given MPDU