diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 3047013fb..eb8f76fe0 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -31,6 +31,7 @@ been tested on Linux. The latest known version to work with ns-3 is cppyy==3.1.2 - (lr-wpan) !1927 - Adds standard version comments to MLME-GET.request function - (lr-wpan) !1926 - Adds namespace lrwpan and prefix shortening - (wifi) - The `WifiMacHelper` provides a `SetDcf` and a `SetEdca` methods to configure attributes of `Txop` and `QosTxop` objects, respectively +- (wifi) - The `ApWifiMac` provides new attributes (`CwMinsForSta`, `CwMaxsForSta`, `AifsnsForSta` and `TxopLimitsForSta`) to define the EDCA access parameters to include in the EDCA Parameter Set advertised to associated stations ### Bugs fixed diff --git a/src/wifi/model/ap-wifi-mac.cc b/src/wifi/model/ap-wifi-mac.cc index 1d427f1cb..ea7f8583c 100644 --- a/src/wifi/model/ap-wifi-mac.cc +++ b/src/wifi/model/ap-wifi-mac.cc @@ -97,6 +97,70 @@ ApWifiMac::GetTypeId() TimeValue(MilliSeconds(20)), MakeTimeAccessor(&ApWifiMac::m_bsrLifetime), MakeTimeChecker()) + .AddAttribute( + "CwMinsForSta", + "The CW min values that the AP advertises in EDCA Parameter Set elements and the " + "associated stations will use. The value of this attribute is an AC-indexed map " + "containing the CW min values for given ACs for all the links (sorted in " + "increasing order of link ID). If no values are provided for an AC, the same " + "values used by the AP are advertised. In case a string is used to set this " + "attribute, the string shall contain the pairs separated by a semicolon (;); " + "in every pair, the AC index and the list of values are separated by a blank " + "space, and the values of a list are separated by a comma (,) without spaces. " + "E.g. \"BE 31,31,31; VI 15,15,15\" defines the CW min values for AC BE and AC VI " + "for an AP MLD having three links.", + StringValue(""), + MakeAttributeContainerAccessor( + &ApWifiMac::m_cwMinsForSta), + GetUintAccessParamsChecker()) + .AddAttribute( + "CwMaxsForSta", + "The CW max values that the AP advertises in EDCA Parameter Set elements and the " + "associated stations will use. The value of this attribute is an AC-indexed map " + "containing the CW max values for given ACs for all the links (sorted in " + "increasing order of link ID). If no values are provided for an AC, the same " + "values used by the AP are advertised. In case a string is used to set this " + "attribute, the string shall contain the pairs separated by a semicolon (;); " + "in every pair, the AC index and the list of values are separated by a blank " + "space, and the values of a list are separated by a comma (,) without spaces. " + "E.g. \"BE 31,31,31; VI 15,15,15\" defines the CW max values for AC BE and AC VI " + "for an AP MLD having three links.", + StringValue(""), + MakeAttributeContainerAccessor( + &ApWifiMac::m_cwMaxsForSta), + GetUintAccessParamsChecker()) + .AddAttribute( + "AifsnsForSta", + "The AIFSN values that the AP advertises in EDCA Parameter Set elements and the " + "associated stations will use. The value of this attribute is an AC-indexed map " + "containing the AIFSN values for given ACs for all the links (sorted in " + "increasing order of link ID). If no values are provided for an AC, the same " + "values used by the AP are advertised. In case a string is used to set this " + "attribute, the string shall contain the pairs separated by a semicolon (;); " + "in every pair, the AC index and the list of values are separated by a blank " + "space, and the values of a list are separated by a comma (,) without spaces. " + "E.g. \"BE 3,3,3; VI 2,2,2\" defines the AIFSN values for AC BE and AC VI " + "for an AP MLD having three links.", + StringValue(""), + MakeAttributeContainerAccessor( + &ApWifiMac::m_aifsnsForSta), + GetUintAccessParamsChecker()) + .AddAttribute( + "TxopLimitsForSta", + "The TXOP limit values that the AP advertises in EDCA Parameter Set elements and " + "the associated stations will use. The value of this attribute is an AC-indexed " + "map containing the TXOP limit values for given ACs for all the links (sorted in " + "increasing order of link ID). If no values are provided for an AC, the same " + "values used by the AP are advertised. In case a string is used to set this " + "attribute, the string shall contain the pairs separated by a semicolon (;); " + "in every pair, the AC index and the list of values are separated by a blank " + "space, and the values of a list are separated by a comma (,) without spaces. " + "E.g. \"BE 3200us,3200us,3200us; VI 2400us,2400us,2400us\" defines the TXOP limit " + "values for AC BE and AC VI for an AP MLD having three links.", + StringValue(""), + MakeAttributeContainerAccessor( + &ApWifiMac::m_txopLimitsForSta), + GetTimeAccessParamsChecker()) .AddTraceSource("AssociatedSta", "A station associated with this access point.", MakeTraceSourceAccessor(&ApWifiMac::m_assocLogger), @@ -108,6 +172,27 @@ ApWifiMac::GetTypeId() return tid; } +template +Ptr +ApWifiMac::GetUintAccessParamsChecker() +{ + return MakeAttributeContainerChecker( + MakePairChecker, + AttributeContainerValue>( + MakeEnumChecker(AC_BE, "BE", AC_BK, "BK", AC_VI, "VI", AC_VO, "VO"), + MakeAttributeContainerChecker( + MakeUintegerChecker()))); +} + +Ptr +ApWifiMac::GetTimeAccessParamsChecker() +{ + return MakeAttributeContainerChecker( + MakePairChecker, AttributeContainerValue>( + MakeEnumChecker(AC_BE, "BE", AC_BK, "BK", AC_VI, "VI", AC_VO, "VO"), + MakeAttributeContainerChecker(MakeTimeChecker()))); +} + ApWifiMac::ApWifiMac() : m_enableBeaconGeneration(false) { @@ -525,35 +610,51 @@ ApWifiMac::GetEdcaParameterSet(uint8_t linkId) const Time txopLimit; edca = GetQosTxop(AC_BE); - txopLimit = edca->GetTxopLimit(linkId); edcaParameters.SetBeAci(0); - edcaParameters.SetBeCWmin(edca->GetMinCw(linkId)); - edcaParameters.SetBeCWmax(edca->GetMaxCw(linkId)); - edcaParameters.SetBeAifsn(edca->GetAifsn(linkId)); + edcaParameters.SetBeCWmin(m_cwMinsForSta.contains(AC_BE) ? m_cwMinsForSta.at(AC_BE).at(linkId) + : edca->GetMinCw(linkId)); + edcaParameters.SetBeCWmax(m_cwMaxsForSta.contains(AC_BE) ? m_cwMaxsForSta.at(AC_BE).at(linkId) + : edca->GetMaxCw(linkId)); + edcaParameters.SetBeAifsn(m_aifsnsForSta.contains(AC_BE) ? m_aifsnsForSta.at(AC_BE).at(linkId) + : edca->GetAifsn(linkId)); + txopLimit = m_txopLimitsForSta.contains(AC_BE) ? m_txopLimitsForSta.at(AC_BE).at(linkId) + : edca->GetTxopLimit(linkId); edcaParameters.SetBeTxopLimit(static_cast(txopLimit.GetMicroSeconds() / 32)); edca = GetQosTxop(AC_BK); - txopLimit = edca->GetTxopLimit(linkId); edcaParameters.SetBkAci(1); - edcaParameters.SetBkCWmin(edca->GetMinCw(linkId)); - edcaParameters.SetBkCWmax(edca->GetMaxCw(linkId)); - edcaParameters.SetBkAifsn(edca->GetAifsn(linkId)); + edcaParameters.SetBkCWmin(m_cwMinsForSta.contains(AC_BK) ? m_cwMinsForSta.at(AC_BK).at(linkId) + : edca->GetMinCw(linkId)); + edcaParameters.SetBkCWmax(m_cwMaxsForSta.contains(AC_BK) ? m_cwMaxsForSta.at(AC_BK).at(linkId) + : edca->GetMaxCw(linkId)); + edcaParameters.SetBkAifsn(m_aifsnsForSta.contains(AC_BK) ? m_aifsnsForSta.at(AC_BK).at(linkId) + : edca->GetAifsn(linkId)); + txopLimit = m_txopLimitsForSta.contains(AC_BK) ? m_txopLimitsForSta.at(AC_BK).at(linkId) + : edca->GetTxopLimit(linkId); edcaParameters.SetBkTxopLimit(static_cast(txopLimit.GetMicroSeconds() / 32)); edca = GetQosTxop(AC_VI); - txopLimit = edca->GetTxopLimit(linkId); edcaParameters.SetViAci(2); - edcaParameters.SetViCWmin(edca->GetMinCw(linkId)); - edcaParameters.SetViCWmax(edca->GetMaxCw(linkId)); - edcaParameters.SetViAifsn(edca->GetAifsn(linkId)); + edcaParameters.SetViCWmin(m_cwMinsForSta.contains(AC_VI) ? m_cwMinsForSta.at(AC_VI).at(linkId) + : edca->GetMinCw(linkId)); + edcaParameters.SetViCWmax(m_cwMaxsForSta.contains(AC_VI) ? m_cwMaxsForSta.at(AC_VI).at(linkId) + : edca->GetMaxCw(linkId)); + edcaParameters.SetViAifsn(m_aifsnsForSta.contains(AC_VI) ? m_aifsnsForSta.at(AC_VI).at(linkId) + : edca->GetAifsn(linkId)); + txopLimit = m_txopLimitsForSta.contains(AC_VI) ? m_txopLimitsForSta.at(AC_VI).at(linkId) + : edca->GetTxopLimit(linkId); edcaParameters.SetViTxopLimit(static_cast(txopLimit.GetMicroSeconds() / 32)); edca = GetQosTxop(AC_VO); - txopLimit = edca->GetTxopLimit(linkId); edcaParameters.SetVoAci(3); - edcaParameters.SetVoCWmin(edca->GetMinCw(linkId)); - edcaParameters.SetVoCWmax(edca->GetMaxCw(linkId)); - edcaParameters.SetVoAifsn(edca->GetAifsn(linkId)); + edcaParameters.SetVoCWmin(m_cwMinsForSta.contains(AC_VO) ? m_cwMinsForSta.at(AC_VO).at(linkId) + : edca->GetMinCw(linkId)); + edcaParameters.SetVoCWmax(m_cwMaxsForSta.contains(AC_VO) ? m_cwMaxsForSta.at(AC_VO).at(linkId) + : edca->GetMaxCw(linkId)); + edcaParameters.SetVoAifsn(m_aifsnsForSta.contains(AC_VO) ? m_aifsnsForSta.at(AC_VO).at(linkId) + : edca->GetAifsn(linkId)); + txopLimit = m_txopLimitsForSta.contains(AC_VO) ? m_txopLimitsForSta.at(AC_VO).at(linkId) + : edca->GetTxopLimit(linkId); edcaParameters.SetVoTxopLimit(static_cast(txopLimit.GetMicroSeconds() / 32)); edcaParameters.SetQosInfo(0); diff --git a/src/wifi/model/ap-wifi-mac.h b/src/wifi/model/ap-wifi-mac.h index fa3ada3c6..5ae087f7d 100644 --- a/src/wifi/model/ap-wifi-mac.h +++ b/src/wifi/model/ap-wifi-mac.h @@ -25,6 +25,10 @@ #include "wifi-mac-header.h" #include "wifi-mac.h" +#include "ns3/attribute-container.h" +#include "ns3/enum.h" +#include "ns3/pair.h" + #include #include @@ -161,6 +165,65 @@ class ApWifiMac : public WifiMac */ uint8_t GetMaxBufferStatus(Mac48Address address) const; + /// ACI-indexed map of access parameters of type unsigned integer (CWmin, CWmax and AIFSN) + using UintAccessParamsMap = std::map>; + + /// ACI-indexed map of access parameters of type Time (TxopLimit) + using TimeAccessParamsMap = std::map>; + + /// AttributeValue type of a pair (ACI, access parameters of type unsigned integer) + using UintAccessParamsPairValue = + PairValue, AttributeContainerValue>; + + /// AttributeValue type of a pair (ACI, access parameters of type Time) + using TimeAccessParamsPairValue = + PairValue, AttributeContainerValue>; + + /// AttributeValue type of an ACI-indexed map of access parameters of type unsigned integer + using UintAccessParamsMapValue = AttributeContainerValue; + + /// AttributeValue type of ACI-indexed map of access parameters of type Time + using TimeAccessParamsMapValue = AttributeContainerValue; + + /** + * Get a checker for the CwMinsForSta, CwMaxsForSta and AifsnsForSta attributes, which can + * be used to deserialize an ACI-indexed map of access parameters of type unsigned integer + * (CWmin, CWmax and AIFSN) from a string: + * + * \code + * ApWifiMac::UintAccessParamsMapValue value; + * value.DeserializeFromString("BE 31,31; VO 15,15", + * ApWifiMac::GetUintAccessParamsChecker()); + * auto map = value.Get(); + * \endcode + * + * The type of \p map is ApWifiMac::UintAccessParamsMapValue::result_type, which is + * std::list>>. + * + * \tparam T \explicit the type of the unsigned integer access parameter + * \return a checker for the CwMinsForSta, CwMaxsForSta and AifsnsForSta attributes + */ + template + static Ptr GetUintAccessParamsChecker(); + + /** + * Get a checker for the TxopLimitsForSta attribute, which can be used to deserialize an + * ACI-indexed map of access parameters of type Time (TxopLimit) from a string: + * + * \code + * ApWifiMac::TimeAccessParamsMapValue value; + * value.DeserializeFromString("BE 3200us; VO 3232us", + * ApWifiMac::GetTimeAccessParamsChecker()); + * auto map = value.Get(); + * \endcode + * + * The type of \p map is ApWifiMac::TimeAccessParamsMapValue::result_type, which is + * std::list>>. + * + * \return a checker for the TxopLimitsForSta attribute + */ + static Ptr GetTimeAccessParamsChecker(); + protected: /** * Structure holding information specific to a single link. Here, the meaning of @@ -518,6 +581,11 @@ class ApWifiMac : public WifiMac /// transition timeout events running for EMLSR clients std::map m_transitionTimeoutEvents; + UintAccessParamsMap m_cwMinsForSta; //!< Per-AC CW min values to advertise to stations + UintAccessParamsMap m_cwMaxsForSta; //!< Per-AC CW max values to advertise to stations + UintAccessParamsMap m_aifsnsForSta; //!< Per-AC AIFS values to advertise to stations + TimeAccessParamsMap m_txopLimitsForSta; //!< Per-AC TXOP limits values to advertise to stations + /// store value and timestamp for each Buffer Status Report struct BsrType {