diff --git a/examples/wireless/wifi-eht-network.cc b/examples/wireless/wifi-eht-network.cc index 836c211ea..1e5440673 100644 --- a/examples/wireless/wifi-eht-network.cc +++ b/examples/wireless/wifi-eht-network.cc @@ -438,9 +438,8 @@ main(int argc, char* argv[]) Config::Set( "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HeConfiguration/GuardInterval", TimeValue(NanoSeconds(gi))); - Config::Set( - "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HeConfiguration/MpduBufferSize", - UintegerValue(useExtendedBlockAck ? 256 : 64)); + Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MpduBufferSize", + UintegerValue(useExtendedBlockAck ? 256 : 64)); // mobility. MobilityHelper mobility; diff --git a/examples/wireless/wifi-he-network.cc b/examples/wireless/wifi-he-network.cc index fe380dba4..b6058ba9a 100644 --- a/examples/wireless/wifi-he-network.cc +++ b/examples/wireless/wifi-he-network.cc @@ -250,11 +250,8 @@ main(int argc, char* argv[]) StringValue(ossDataMode.str()), "ControlMode", ctrlRate); - // Set guard interval and MPDU buffer size - wifi.ConfigHeOptions("GuardInterval", - TimeValue(NanoSeconds(gi)), - "MpduBufferSize", - UintegerValue(useExtendedBlockAck ? 256 : 64)); + // Set guard interval + wifi.ConfigHeOptions("GuardInterval", TimeValue(NanoSeconds(gi))); Ssid ssid = Ssid("ns3-80211ax"); @@ -277,7 +274,11 @@ main(int argc, char* argv[]) phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO); phy.SetChannel(spectrumChannel); - mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid)); + mac.SetType("ns3::StaWifiMac", + "Ssid", + SsidValue(ssid), + "MpduBufferSize", + UintegerValue(useExtendedBlockAck ? 256 : 64)); phy.Set("ChannelSettings", StringValue(channelStr)); staDevices = wifi.Install(phy, mac, wifiStaNodes); @@ -305,7 +306,11 @@ main(int argc, char* argv[]) phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO); phy.SetChannel(channel.Create()); - mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid)); + mac.SetType("ns3::StaWifiMac", + "Ssid", + SsidValue(ssid), + "MpduBufferSize", + UintegerValue(useExtendedBlockAck ? 256 : 64)); phy.Set("ChannelSettings", StringValue(channelStr)); staDevices = wifi.Install(phy, mac, wifiStaNodes); diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index b7ae4e964..21e3dc63b 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -238,7 +238,8 @@ HtFrameExchangeManager::SendAddBaResponse(const MgtAddBaRequestHeader* reqHdr, auto tid = reqHdr->GetTid(); respHdr.SetTid(tid); - respHdr.SetBufferSize(GetSupportedBaBufferSize()); + auto bufferSize = std::min(m_mac->GetMpduBufferSize(), m_mac->GetMaxBaBufferSize(originator)); + respHdr.SetBufferSize(bufferSize); respHdr.SetTimeout(reqHdr->GetTimeout()); WifiActionHeader actionHdr; diff --git a/src/wifi/model/wifi-mac.cc b/src/wifi/model/wifi-mac.cc index 611529165..076c61564 100644 --- a/src/wifi/model/wifi-mac.cc +++ b/src/wifi/model/wifi-mac.cc @@ -120,6 +120,14 @@ WifiMac::GetTypeId() PointerValue(), MakePointerAccessor(&WifiMac::GetBKQueue), MakePointerChecker()) + .AddAttribute( + "MpduBufferSize", + "The size (in number of MPDUs) of the buffer used for each BlockAck " + "agreement in which this node is a recipient. The provided value is " + "capped to the maximum allowed value based on the supported standard.", + UintegerValue(64), + MakeUintegerAccessor(&WifiMac::GetMpduBufferSize, &WifiMac::SetMpduBufferSize), + MakeUintegerChecker(1, 1024)) .AddAttribute("VO_MaxAmsduSize", "Maximum length in bytes of an A-MSDU for AC_VO access class " "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). " @@ -420,6 +428,11 @@ void WifiMac::SetDevice(const Ptr device) { m_device = device; + if (GetHtSupported()) + { + // the configured BlockAck buffer size can now be capped + m_mpduBufferSize = std::min(m_mpduBufferSize, GetMaxBaBufferSize()); + } } Ptr @@ -1846,6 +1859,21 @@ WifiMac::GetMaxBaBufferSize(std::optional address) const return 64; } +void +WifiMac::SetMpduBufferSize(uint16_t size) +{ + NS_LOG_FUNCTION(this << size); + + // the cap can be computed if the device has been configured + m_mpduBufferSize = m_device ? std::min(size, GetMaxBaBufferSize()) : size; +} + +uint16_t +WifiMac::GetMpduBufferSize() const +{ + return m_mpduBufferSize; +} + void WifiMac::SetVoBlockAckThreshold(uint8_t threshold) { diff --git a/src/wifi/model/wifi-mac.h b/src/wifi/model/wifi-mac.h index e7b75677d..3d8bb4c59 100644 --- a/src/wifi/model/wifi-mac.h +++ b/src/wifi/model/wifi-mac.h @@ -694,6 +694,18 @@ class WifiMac : public Object */ uint16_t GetMaxBaBufferSize(std::optional address = std::nullopt) const; + /** + * \param size the size (in number of MPDUs) of the buffer used for each BlockAck + * agreement in which this node is a recipient + */ + void SetMpduBufferSize(uint16_t size); + + /** + * \return the size (in number of MPDUs) of the buffer used for each BlockAck + * agreement in which this node is a recipient + */ + uint16_t GetMpduBufferSize() const; + /** * Get the TID-to-Link Mapping negotiated with the given MLD (if any) for the given direction. * An empty mapping indicates the default mapping. @@ -1070,6 +1082,8 @@ class WifiMac : public Object uint32_t m_beMaxAmpduSize; ///< maximum A-MPDU size for AC_BE (in bytes) uint32_t m_bkMaxAmpduSize; ///< maximum A-MPDU size for AC_BK (in bytes) + uint16_t m_mpduBufferSize; //!< BlockAck buffer size (in number of MPDUs) + /// @brief DL TID-to-Link Mapping negotiated with an MLD (identified by its MLD address) std::unordered_map m_dlTidLinkMappings; /// @brief UL TID-to-Link Mapping negotiated with an MLD (identified by its MLD address)