From ea0166feae203b52ca134b21ebdd2b6b710b01ad Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Fri, 19 Jul 2024 19:54:55 +0200 Subject: [PATCH] wifi: Store per-STA/per-AC SSRC/QSRC in the Txop class and fix CW update --- src/wifi/model/txop.cc | 31 ++++++++++++++++++++++---- src/wifi/model/txop.h | 50 +++++++++++++++++++++++++++--------------- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/wifi/model/txop.cc b/src/wifi/model/txop.cc index bae65cfb9..abf999b71 100644 --- a/src/wifi/model/txop.cc +++ b/src/wifi/model/txop.cc @@ -358,6 +358,12 @@ Txop::GetCw(uint8_t linkId) const return GetLink(linkId).cw; } +std::size_t +Txop::GetStaRetryCount(uint8_t linkId) const +{ + return GetLink(linkId).staRetryCount; +} + void Txop::ResetCw(uint8_t linkId) { @@ -365,6 +371,7 @@ Txop::ResetCw(uint8_t linkId) auto& link = GetLink(linkId); link.cw = GetMinCw(linkId); m_cwTrace(link.cw, linkId); + link.staRetryCount = 0; } void @@ -372,10 +379,26 @@ Txop::UpdateFailedCw(uint8_t linkId) { NS_LOG_FUNCTION(this << linkId); auto& link = GetLink(linkId); - // see 802.11-2012, section 9.19.2.5 - link.cw = std::min(2 * (link.cw + 1) - 1, GetMaxCw(linkId)); - // if the MU EDCA timer is running, CW cannot be less than MU CW min - link.cw = std::max(link.cw, GetMinCw(linkId)); + + if (link.staRetryCount < m_mac->GetFrameRetryLimit()) + { + // If QSRC[AC] is less than dot11ShortRetryLimit, + // - QSRC[AC] shall be incremented by 1. + // - CW[AC] shall be set to the lesser of CWmax[AC] and 2^QSRC[AC] × (CWmin[AC] + 1) – 1. + // (Section 10.23.2.2 of 802.11-2020) + ++link.staRetryCount; + link.cw = + std::min(GetMaxCw(linkId), (1 << link.staRetryCount) * (GetMinCw(linkId) + 1) - 1); + } + else + { + // Else + // - QSRC[AC] shall be set to 0. + // - CW[AC] shall be set to CWmin[AC]. + link.staRetryCount = 0; + link.cw = GetMinCw(linkId); + } + m_cwTrace(link.cw, linkId); } diff --git a/src/wifi/model/txop.h b/src/wifi/model/txop.h index cf0fba64d..186f634a3 100644 --- a/src/wifi/model/txop.h +++ b/src/wifi/model/txop.h @@ -304,6 +304,25 @@ class Txop : public Object */ void UpdateFailedCw(uint8_t linkId); + /** + * Get the current value of the CW variable for the given link. The initial + * value is minCw. + * + * @param linkId the ID of the given link + * @return the current value of the CW variable for the given link + */ + uint32_t GetCw(uint8_t linkId) const; + + /** + * Get the Station Short Retry Count (SSRC) maintained by non-QoS stations or the QoS STA + * Retry Count (QSRC) maintained by QoS STAs for each AC on the given link. + * + * @param linkId the ID of the given link + * @return the Station Short Retry Count (SSRC) maintained by non-QoS stations or the QoS STA + * Retry Count (QSRC) maintained by QoS STAs for each AC on the given link + */ + std::size_t GetStaRetryCount(uint8_t linkId) const; + /** * Notify that the given link switched to sleep mode. * @@ -475,14 +494,6 @@ class Txop : public Object */ void RequestAccess(uint8_t linkId); - /** - * Get the current value of the CW variable for the given link. The initial - * value is minCw. - * - * @param linkId the ID of the given link - * @return the current value of the CW variable for the given link - */ - uint32_t GetCw(uint8_t linkId) const; /** * Return the current number of backoff slots on the given link. * @@ -516,16 +527,19 @@ class Txop : public Object /// Destructor (a virtual method is needed to make this struct polymorphic) virtual ~LinkEntity() = default; - uint32_t backoffSlots{0}; //!< the number of backoff slots - Time backoffStart{0}; /**< the backoffStart variable is used to keep - track of the time at which a backoff was - started or the time at which the backoff - counter was last updated */ - uint32_t cw{0}; //!< the current contention window - uint32_t cwMin{0}; //!< the minimum contention window - uint32_t cwMax{0}; //!< the maximum contention window - uint8_t aifsn{0}; //!< the AIFSN - Time txopLimit{0}; //!< the TXOP limit time + uint32_t backoffSlots{0}; //!< the number of backoff slots + Time backoffStart{0}; /**< the backoffStart variable is used to keep + track of the time at which a backoff was + started or the time at which the backoff + counter was last updated */ + uint32_t cw{0}; //!< the current contention window + uint32_t cwMin{0}; //!< the minimum contention window + uint32_t cwMax{0}; //!< the maximum contention window + uint8_t aifsn{0}; //!< the AIFSN + Time txopLimit{0}; //!< the TXOP limit time + std::size_t staRetryCount{0}; //!< the Station Short Retry Count (SSRC) maintained by + //!< non-QoS stations or the QoS STA Retry Count (QSRC) + //!< maintained by QoS STAs for each AC ChannelAccessStatus access{NOT_REQUESTED}; //!< channel access status mutable class