From dd49dbfac8a1f8f4066f07b364c6895f8403b2df Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 27 Mar 2024 16:10:06 +0100 Subject: [PATCH] wifi: (fixes #1072) Enable using Txop attributes to set DCF/EDCA access parameters --- RELEASE_NOTES.md | 1 + src/wifi/model/txop.cc | 109 ++++++++++++++++++++++++++++++------- src/wifi/model/txop.h | 62 +++++++++++++++------ src/wifi/model/wifi-mac.cc | 42 ++++++++------ 4 files changed, 161 insertions(+), 53 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f7da6a6c8..3047013fb 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -43,6 +43,7 @@ been tested on Linux. The latest known version to work with ns-3 is cppyy==3.1.2 - (bindings, core) - Introduced a helper class to manage static initialization of Time as a workaround for Cppyy3 static initialization problems. - (bindings, lte, wifi) - Relocated statically initialized variables from header files to source files for Cppyy3 compatibility. - (tests) - Enhanced error handling in test.py to avoid attempts to open non-existent XML files following early test termination by sanitizers. +- (wifi) #1072 - Support configuration of custom EDCA parameters via Txop attributes before device installation Release 3.41 ------------ diff --git a/src/wifi/model/txop.cc b/src/wifi/model/txop.cc index f3b7ed2ca..cfcee0237 100644 --- a/src/wifi/model/txop.cc +++ b/src/wifi/model/txop.cc @@ -87,8 +87,11 @@ Txop::GetTypeId() "Use MinCws attribute instead of MinCw") .AddAttribute( "MinCws", - "The minimum values of the contention window for all the links", - TypeId::ATTR_GET | TypeId::ATTR_SET, // do not set at construction time + "The minimum values of the contention window for all the links (sorted in " + "increasing order of link ID). An empty vector is ignored and the default value " + "as per Table 9-155 of the IEEE 802.11-2020 standard will be used. Note that, if " + "this is a non-AP STA, these values could be overridden by values advertised by " + "the AP through EDCA Parameter Set elements.", AttributeContainerValue(), MakeAttributeContainerAccessor(&Txop::SetMinCws, &Txop::GetMinCws), MakeAttributeContainerChecker(MakeUintegerChecker())) @@ -104,8 +107,11 @@ Txop::GetTypeId() "Use MaxCws attribute instead of MaxCw") .AddAttribute( "MaxCws", - "The maximum values of the contention window for all the links", - TypeId::ATTR_GET | TypeId::ATTR_SET, // do not set at construction time + "The maximum values of the contention window for all the links (sorted in " + "increasing order of link ID). An empty vector is ignored and the default value " + "as per Table 9-155 of the IEEE 802.11-2020 standard will be used. Note that, if " + "this is a non-AP STA, these values could be overridden by values advertised by " + "the AP through EDCA Parameter Set elements.", AttributeContainerValue(), MakeAttributeContainerAccessor(&Txop::SetMaxCws, &Txop::GetMaxCws), MakeAttributeContainerChecker(MakeUintegerChecker())) @@ -122,8 +128,11 @@ Txop::GetTypeId() "Use Aifsns attribute instead of Aifsn") .AddAttribute( "Aifsns", - "The values of AIFSN for all the links", - TypeId::ATTR_GET | TypeId::ATTR_SET, // do not set at construction time + "The values of AIFSN for all the links (sorted in increasing order " + "of link ID). An empty vector is ignored and the default value as per " + "Table 9-155 of the IEEE 802.11-2020 standard will be used. Note that, if " + "this is a non-AP STA, these values could be overridden by values advertised by " + "the AP through EDCA Parameter Set elements.", AttributeContainerValue(), MakeAttributeContainerAccessor(&Txop::SetAifsns, &Txop::GetAifsns), MakeAttributeContainerChecker(MakeUintegerChecker())) @@ -137,13 +146,17 @@ Txop::GetTypeId() MakeTimeChecker(), TypeId::OBSOLETE, "Use TxopLimits attribute instead of TxopLimit") - .AddAttribute("TxopLimits", - "The values of TXOP limit for all the links", - TypeId::ATTR_GET | TypeId::ATTR_SET, // do not set at construction time - AttributeContainerValue(), - MakeAttributeContainerAccessor(&Txop::SetTxopLimits, - &Txop::GetTxopLimits), - MakeAttributeContainerChecker(MakeTimeChecker())) + .AddAttribute( + "TxopLimits", + "The values of TXOP limit for all the links (sorted in increasing order " + "of link ID). An empty vector is ignored and the default value as per " + "Table 9-155 of the IEEE 802.11-2020 standard will be used. Note that, if " + "this is a non-AP STA, these values could be overridden by values advertised by " + "the AP through EDCA Parameter Set elements.", + AttributeContainerValue(), + MakeAttributeContainerAccessor(&Txop::SetTxopLimits, + &Txop::GetTxopLimits), + MakeAttributeContainerChecker(MakeTimeChecker())) .AddAttribute("Queue", "The WifiMacQueue object", PointerValue(), @@ -270,9 +283,20 @@ Txop::SetMinCw(uint32_t minCw) } void -Txop::SetMinCws(std::vector minCws) +Txop::SetMinCws(const std::vector& minCws) { - NS_ABORT_IF(minCws.size() != m_links.size()); + if (minCws.empty()) + { + // an empty vector is passed to use the default values specified by the standard + return; + } + + NS_ABORT_MSG_IF(!m_links.empty() && minCws.size() != m_links.size(), + "The size of the given vector (" << minCws.size() + << ") does not match the number of links (" + << m_links.size() << ")"); + m_userAccessParams.cwMins = minCws; + std::size_t i = 0; for (const auto& [id, link] : m_links) { @@ -284,6 +308,8 @@ void Txop::SetMinCw(uint32_t minCw, uint8_t linkId) { NS_LOG_FUNCTION(this << minCw << linkId); + NS_ASSERT_MSG(!m_links.empty(), + "This function can only be called after that links have been created"); auto& link = GetLink(linkId); bool changed = (link.cwMin != minCw); link.cwMin = minCw; @@ -300,9 +326,20 @@ Txop::SetMaxCw(uint32_t maxCw) } void -Txop::SetMaxCws(std::vector maxCws) +Txop::SetMaxCws(const std::vector& maxCws) { - NS_ABORT_IF(maxCws.size() != m_links.size()); + if (maxCws.empty()) + { + // an empty vector is passed to use the default values specified by the standard + return; + } + + NS_ABORT_MSG_IF(!m_links.empty() && maxCws.size() != m_links.size(), + "The size of the given vector (" << maxCws.size() + << ") does not match the number of links (" + << m_links.size() << ")"); + m_userAccessParams.cwMaxs = maxCws; + std::size_t i = 0; for (const auto& [id, link] : m_links) { @@ -314,6 +351,8 @@ void Txop::SetMaxCw(uint32_t maxCw, uint8_t linkId) { NS_LOG_FUNCTION(this << maxCw << linkId); + NS_ASSERT_MSG(!m_links.empty(), + "This function can only be called after that links have been created"); auto& link = GetLink(linkId); bool changed = (link.cwMax != maxCw); link.cwMax = maxCw; @@ -398,9 +437,20 @@ Txop::SetAifsn(uint8_t aifsn) } void -Txop::SetAifsns(std::vector aifsns) +Txop::SetAifsns(const std::vector& aifsns) { - NS_ABORT_IF(aifsns.size() != m_links.size()); + if (aifsns.empty()) + { + // an empty vector is passed to use the default values specified by the standard + return; + } + + NS_ABORT_MSG_IF(!m_links.empty() && aifsns.size() != m_links.size(), + "The size of the given vector (" << aifsns.size() + << ") does not match the number of links (" + << m_links.size() << ")"); + m_userAccessParams.aifsns = aifsns; + std::size_t i = 0; for (const auto& [id, link] : m_links) { @@ -412,6 +462,8 @@ void Txop::SetAifsn(uint8_t aifsn, uint8_t linkId) { NS_LOG_FUNCTION(this << aifsn << linkId); + NS_ASSERT_MSG(!m_links.empty(), + "This function can only be called after that links have been created"); GetLink(linkId).aifsn = aifsn; } @@ -424,10 +476,18 @@ Txop::SetTxopLimit(Time txopLimit) void Txop::SetTxopLimits(const std::vector