From 46cda10f706c1803010e71a9ec427f78b8da67c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Sat, 24 Aug 2024 13:14:16 +0200 Subject: [PATCH] wifi: Add ability to select whether the NAV protection should cover the entire TXOP or only the current frame exchange --- RELEASE_NOTES.md | 1 + .../model/he/he-frame-exchange-manager.cc | 39 +++++++--- .../model/ht/ht-frame-exchange-manager.cc | 17 ++++- src/wifi/model/qos-frame-exchange-manager.cc | 73 ++++++++++++++----- src/wifi/model/qos-frame-exchange-manager.h | 3 + 5 files changed, 99 insertions(+), 34 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c21c11f6f..8085d1c3c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -34,6 +34,7 @@ The required Doxygen version for documentation generation is now version 1.13. - (dsr) !2403 - Reformatted documentation and added a new concept figure. - (flow-monitor) !2387 - Reformatted documentation and added a new concept figure. +- (wifi) Added the `ProtectSingleExchange` attribute to the `QosFrameExchangeManager` to choose whether the NAV protection should cover the entire TXOP or only the current frame exchange when the TXOP limit is non-zero. In that case, the Duration/ID field in frames establishing the protection is set to the time remaining until the end of the current frame exchange. ### Bugs fixed diff --git a/src/wifi/model/he/he-frame-exchange-manager.cc b/src/wifi/model/he/he-frame-exchange-manager.cc index baaaf7a46..604e999dc 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.cc +++ b/src/wifi/model/he/he-frame-exchange-manager.cc @@ -334,20 +334,31 @@ HeFrameExchangeManager::GetMuRtsDurationId(uint32_t muRtsSize, { NS_LOG_FUNCTION(this << muRtsSize << muRtsTxVector << txDuration << response); + WifiTxVector txVector; + txVector.SetMode(GetCtsModeAfterMuRts()); + const auto singleDurationId = + VhtFrameExchangeManager::GetRtsDurationId(txVector, txDuration, response); + if (m_edca->GetTxopLimit(m_linkId).IsZero()) { - WifiTxVector txVector; - txVector.SetMode(GetCtsModeAfterMuRts()); - return VhtFrameExchangeManager::GetRtsDurationId(txVector, txDuration, response); + return singleDurationId; } // under multiple protection settings, if the TXOP limit is not null, Duration/ID // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016). // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8 // of 802.11-2016) - return std::max(m_edca->GetRemainingTxop(m_linkId) - - WifiPhy::CalculateTxDuration(muRtsSize, muRtsTxVector, m_phy->GetPhyBand()), - Seconds(0)); + auto duration = + std::max(m_edca->GetRemainingTxop(m_linkId) - + WifiPhy::CalculateTxDuration(muRtsSize, muRtsTxVector, m_phy->GetPhyBand()), + Seconds(0)); + + if (m_protectSingleExchange) + { + duration = std::min(duration, singleDurationId); + } + + return duration; } void @@ -1724,15 +1735,19 @@ HeFrameExchangeManager::SendMultiStaBlockAck(const WifiTxParameters& txParams, T * settings defined in 9.2.5.2. (Sec. 9.2.5.7 of 802.11ax-2021) */ NS_ASSERT(m_edca); - if (m_edca->GetTxopLimit(m_linkId).IsZero()) + const auto singleDurationId = Max(durationId - m_phy->GetSifs() - txDuration, Seconds(0)); + if (m_edca->GetTxopLimit(m_linkId).IsZero()) // single protection settings { - // single protection settings - psdu->SetDuration(Max(durationId - m_phy->GetSifs() - txDuration, Seconds(0))); + psdu->SetDuration(singleDurationId); } - else + else // multiple protection settings { - // multiple protection settings - psdu->SetDuration(Max(m_edca->GetRemainingTxop(m_linkId) - txDuration, Seconds(0))); + auto duration = Max(m_edca->GetRemainingTxop(m_linkId) - txDuration, Seconds(0)); + if (m_protectSingleExchange) + { + duration = std::min(duration, singleDurationId); + } + psdu->SetDuration(duration); } psdu->GetPayload(0)->AddPacketTag(m_muSnrTag); diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index 56e84ab97..1cd33d2e2 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -1034,19 +1034,28 @@ HtFrameExchangeManager::GetPsduDurationId(Time txDuration, const WifiTxParameter NS_LOG_FUNCTION(this << txDuration << &txParams); NS_ASSERT(m_edca); + NS_ASSERT(txParams.m_acknowledgment && + txParams.m_acknowledgment->acknowledgmentTime.has_value()); + + const auto singleDurationId = *txParams.m_acknowledgment->acknowledgmentTime; if (m_edca->GetTxopLimit(m_linkId).IsZero()) { - NS_ASSERT(txParams.m_acknowledgment && - txParams.m_acknowledgment->acknowledgmentTime.has_value()); - return *txParams.m_acknowledgment->acknowledgmentTime; + return singleDurationId; } // under multiple protection settings, if the TXOP limit is not null, Duration/ID // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016). // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8 // of 802.11-2016) - return std::max(m_edca->GetRemainingTxop(m_linkId) - txDuration, Seconds(0)); + auto duration = std::max(m_edca->GetRemainingTxop(m_linkId) - txDuration, Seconds(0)); + + if (m_protectSingleExchange) + { + duration = std::min(duration, singleDurationId); + } + + return duration; } void diff --git a/src/wifi/model/qos-frame-exchange-manager.cc b/src/wifi/model/qos-frame-exchange-manager.cc index f8ea1feb8..0f6a5643b 100644 --- a/src/wifi/model/qos-frame-exchange-manager.cc +++ b/src/wifi/model/qos-frame-exchange-manager.cc @@ -44,6 +44,13 @@ QosFrameExchangeManager::GetTypeId() "of QoS data frames sent by non-AP stations", BooleanValue(false), MakeBooleanAccessor(&QosFrameExchangeManager::m_setQosQueueSize), + MakeBooleanChecker()) + .AddAttribute("ProtectSingleExchange", + "Whether the Duration/ID field in frames establishing protection only " + "covers the immediate frame exchange instead of rest of the TXOP limit " + "when the latter is non-zero", + BooleanValue(false), + MakeBooleanAccessor(&QosFrameExchangeManager::m_protectSingleExchange), MakeBooleanChecker()); return tid; } @@ -471,15 +478,18 @@ QosFrameExchangeManager::GetFrameDurationId(const WifiMacHeader& header, { NS_LOG_FUNCTION(this << header << size << &txParams << fragmentedPacket); + const auto singleDurationId = + FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket); + // TODO This will be removed once no Txop is installed on a QoS station if (!m_edca) { - return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket); + return singleDurationId; } if (m_edca->GetTxopLimit(m_linkId).IsZero()) { - return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket); + return singleDurationId; } NS_ASSERT(txParams.m_acknowledgment && @@ -489,10 +499,17 @@ QosFrameExchangeManager::GetFrameDurationId(const WifiMacHeader& header, // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016). // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8 // of 802.11-2016) - return std::max( - m_edca->GetRemainingTxop(m_linkId) - - WifiPhy::CalculateTxDuration(size, txParams.m_txVector, m_phy->GetPhyBand()), - *txParams.m_acknowledgment->acknowledgmentTime); + auto duration = + std::max(m_edca->GetRemainingTxop(m_linkId) - + WifiPhy::CalculateTxDuration(size, txParams.m_txVector, m_phy->GetPhyBand()), + *txParams.m_acknowledgment->acknowledgmentTime); + + if (m_protectSingleExchange) + { + duration = std::min(duration, singleDurationId); + } + + return duration; } Time @@ -502,25 +519,35 @@ QosFrameExchangeManager::GetRtsDurationId(const WifiTxVector& rtsTxVector, { NS_LOG_FUNCTION(this << rtsTxVector << txDuration << response); + const auto singleDurationId = + FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response); + // TODO This will be removed once no Txop is installed on a QoS station if (!m_edca) { - return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response); + return singleDurationId; } if (m_edca->GetTxopLimit(m_linkId).IsZero()) { - return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response); + return singleDurationId; } // under multiple protection settings, if the TXOP limit is not null, Duration/ID // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016). // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8 // of 802.11-2016) - return std::max( - m_edca->GetRemainingTxop(m_linkId) - - WifiPhy::CalculateTxDuration(GetRtsSize(), rtsTxVector, m_phy->GetPhyBand()), - Seconds(0)); + auto duration = + std::max(m_edca->GetRemainingTxop(m_linkId) - + WifiPhy::CalculateTxDuration(GetRtsSize(), rtsTxVector, m_phy->GetPhyBand()), + Seconds(0)); + + if (m_protectSingleExchange) + { + duration = std::min(duration, singleDurationId); + } + + return duration; } Time @@ -530,25 +557,35 @@ QosFrameExchangeManager::GetCtsToSelfDurationId(const WifiTxVector& ctsTxVector, { NS_LOG_FUNCTION(this << ctsTxVector << txDuration << response); + const auto singleDurationId = + FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response); + // TODO This will be removed once no Txop is installed on a QoS station if (!m_edca) { - return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response); + return singleDurationId; } if (m_edca->GetTxopLimit(m_linkId).IsZero()) { - return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response); + return singleDurationId; } // under multiple protection settings, if the TXOP limit is not null, Duration/ID // is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016). // The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8 // of 802.11-2016) - return std::max( - m_edca->GetRemainingTxop(m_linkId) - - WifiPhy::CalculateTxDuration(GetCtsSize(), ctsTxVector, m_phy->GetPhyBand()), - Seconds(0)); + auto duration = + std::max(m_edca->GetRemainingTxop(m_linkId) - + WifiPhy::CalculateTxDuration(GetCtsSize(), ctsTxVector, m_phy->GetPhyBand()), + Seconds(0)); + + if (m_protectSingleExchange) + { + duration = std::min(duration, singleDurationId); + } + + return duration; } void diff --git a/src/wifi/model/qos-frame-exchange-manager.h b/src/wifi/model/qos-frame-exchange-manager.h index a34370078..0543710f9 100644 --- a/src/wifi/model/qos-frame-exchange-manager.h +++ b/src/wifi/model/qos-frame-exchange-manager.h @@ -191,6 +191,9 @@ class QosFrameExchangeManager : public FrameExchangeManager std::optional m_txopHolder; //!< MAC address of the TXOP holder bool m_setQosQueueSize; /**< whether to set the Queue Size subfield of the QoS Control field of QoS data frames */ + bool m_protectSingleExchange; /**< true if the Duration/ID field in frames establishing + protection only covers the immediate frame exchange instead of + rest of the TXOP limit when the latter is non-zero */ private: /**