From d7cc8c33216008f2d22bb147d10d277155be8cbb Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 25 Nov 2020 17:00:09 +0100 Subject: [PATCH] wifi: APs store buffer status reports carried by QoS frames --- src/wifi/model/ap-wifi-mac.cc | 54 +++++++++++++++++++++++++++++++++++ src/wifi/model/ap-wifi-mac.h | 42 +++++++++++++++++++++++++++ src/wifi/model/qos-utils.cc | 21 ++++++++++++++ src/wifi/model/qos-utils.h | 19 ++++++++++++ 4 files changed, 136 insertions(+) diff --git a/src/wifi/model/ap-wifi-mac.cc b/src/wifi/model/ap-wifi-mac.cc index 76650ec3b..43f7ba6e8 100644 --- a/src/wifi/model/ap-wifi-mac.cc +++ b/src/wifi/model/ap-wifi-mac.cc @@ -83,6 +83,11 @@ ApWifiMac::GetTypeId (void) BooleanValue (true), MakeBooleanAccessor (&ApWifiMac::m_enableNonErpProtection), MakeBooleanChecker ()) + .AddAttribute ("BsrLifetime", + "Lifetime of Buffer Status Reports received from stations.", + TimeValue (MilliSeconds (20)), + MakeTimeAccessor (&ApWifiMac::m_bsrLifetime), + MakeTimeChecker ()) ; return tid; } @@ -1614,4 +1619,53 @@ ApWifiMac::IncrementPollingListIterator (void) } } +uint8_t +ApWifiMac::GetBufferStatus (uint8_t tid, Mac48Address address) const +{ + auto it = m_bufferStatus.find (WifiAddressTidPair (address, tid)); + if (it == m_bufferStatus.end () + || it->second.timestamp + m_bsrLifetime < Simulator::Now ()) + { + return 255; + } + return it->second.value; +} + +void +ApWifiMac::SetBufferStatus (uint8_t tid, Mac48Address address, uint8_t size) +{ + if (size == 255) + { + // no point in storing an unspecified size + m_bufferStatus.erase (WifiAddressTidPair (address, tid)); + } + else + { + m_bufferStatus[WifiAddressTidPair (address, tid)] = {size, Simulator::Now ()}; + } +} + +uint8_t +ApWifiMac::GetMaxBufferStatus (Mac48Address address) const +{ + uint8_t maxSize = 0; + bool found = false; + + for (uint8_t tid = 0; tid < 8; tid++) + { + uint8_t size = GetBufferStatus (tid, address); + if (size != 255) + { + maxSize = std::max (maxSize, size); + found = true; + } + } + + if (found) + { + return maxSize; + } + return 255; +} + } //namespace ns3 diff --git a/src/wifi/model/ap-wifi-mac.h b/src/wifi/model/ap-wifi-mac.h index 5d79e8f8d..9d81c300c 100644 --- a/src/wifi/model/ap-wifi-mac.h +++ b/src/wifi/model/ap-wifi-mac.h @@ -24,6 +24,7 @@ #define AP_WIFI_MAC_H #include "infrastructure-wifi-mac.h" +#include namespace ns3 { @@ -121,6 +122,42 @@ public: */ int64_t AssignStreams (int64_t stream); + /** + * Return the value of the Queue Size subfield of the last QoS Data or QoS Null + * frame received from the station with the given MAC address and belonging to + * the given TID. + * + * The Queue Size value is the total size, rounded up to the nearest multiple + * of 256 octets and expressed in units of 256 octets, of all MSDUs and A-MSDUs + * buffered at the STA (excluding the MSDU or A-MSDU of the present QoS Data frame). + * A queue size value of 254 is used for all sizes greater than 64 768 octets. + * A queue size value of 255 is used to indicate an unspecified or unknown size. + * See Section 9.2.4.5.6 of 802.11-2016 + * + * \param tid the given TID + * \param address the given MAC address + * \return the value of the Queue Size subfield + */ + uint8_t GetBufferStatus (uint8_t tid, Mac48Address address) const; + /** + * Store the value of the Queue Size subfield of the last QoS Data or QoS Null + * frame received from the station with the given MAC address and belonging to + * the given TID. + * + * \param tid the given TID + * \param address the given MAC address + * \param size the value of the Queue Size subfield + */ + void SetBufferStatus (uint8_t tid, Mac48Address address, uint8_t size); + /** + * Return the maximum among the values of the Queue Size subfield of the last + * QoS Data or QoS Null frames received from the station with the given MAC address + * and belonging to any TID. + * + * \param address the given MAC address + * \return the maximum among the values of the Queue Size subfields + */ + uint8_t GetMaxBufferStatus (Mac48Address address) const; private: void Receive (Ptr mpdu); @@ -298,6 +335,11 @@ private: std::list m_cfPollingList; //!< List of all PCF stations currently associated to the AP std::list::iterator m_itCfPollingList; //!< Iterator to the list of all PCF stations currently associated to the AP bool m_enableNonErpProtection; //!< Flag whether protection mechanism is used or not when non-ERP STAs are present within the BSS + Time m_bsrLifetime; //!< Lifetime of Buffer Status Reports + //!< store value and timestamp for each Buffer Status Report + typedef struct { uint8_t value; Time timestamp; } bsrType; + //!< Per (MAC address, TID) buffer status reports + std::unordered_map m_bufferStatus; }; } //namespace ns3 diff --git a/src/wifi/model/qos-utils.cc b/src/wifi/model/qos-utils.cc index f106ced86..ad59b41c4 100644 --- a/src/wifi/model/qos-utils.cc +++ b/src/wifi/model/qos-utils.cc @@ -28,6 +28,27 @@ namespace ns3 { +std::size_t +WifiAddressTidHash::operator()(const WifiAddressTidPair& addressTidPair) const +{ + uint8_t buffer[7]; + addressTidPair.first.CopyTo (buffer); + buffer[6] = addressTidPair.second; + + std::string s (buffer, buffer + 7); + return std::hash{} (s); +} + +std::size_t +WifiAddressHash::operator()(const Mac48Address& address) const +{ + uint8_t buffer[6]; + address.CopyTo (buffer); + + std::string s (buffer, buffer + 6); + return std::hash{} (s); +} + AcIndex QosUtilsMapTidToAc (uint8_t tid) { diff --git a/src/wifi/model/qos-utils.h b/src/wifi/model/qos-utils.h index 6a557656e..d4909b085 100644 --- a/src/wifi/model/qos-utils.h +++ b/src/wifi/model/qos-utils.h @@ -28,6 +28,25 @@ namespace ns3 { class Packet; class WifiMacHeader; class QueueItem; +class Mac48Address; + +typedef std::pair WifiAddressTidPair; //!< (MAC address, TID) pair + +/** + * Function object to compute the hash of a (MAC address, TID) pair + */ +struct WifiAddressTidHash +{ + std::size_t operator() (const WifiAddressTidPair& addressTidPair) const; +}; + +/** + * Function object to compute the hash of a MAC address + */ +struct WifiAddressHash +{ + std::size_t operator() (const Mac48Address& address) const; +}; /** * \ingroup wifi