From e7b50e81445ec1fc468710db572bb454acc91ae1 Mon Sep 17 00:00:00 2001 From: Rami Abdallah Date: Tue, 27 Feb 2024 12:04:14 +0100 Subject: [PATCH] wifi: Add HE 6GHz Band Capabilities information element --- src/wifi/CMakeLists.txt | 2 + .../model/he/he-6ghz-band-capabilities.cc | 148 ++++++++++++++++++ src/wifi/model/he/he-6ghz-band-capabilities.h | 94 +++++++++++ src/wifi/model/mgt-headers.h | 5 + src/wifi/model/wifi-information-element.h | 2 + src/wifi/test/wifi-he-info-elems-test.cc | 39 +++++ 6 files changed, 290 insertions(+) create mode 100644 src/wifi/model/he/he-6ghz-band-capabilities.cc create mode 100644 src/wifi/model/he/he-6ghz-band-capabilities.h diff --git a/src/wifi/CMakeLists.txt b/src/wifi/CMakeLists.txt index f49ce8e1c..54a0079de 100644 --- a/src/wifi/CMakeLists.txt +++ b/src/wifi/CMakeLists.txt @@ -42,6 +42,7 @@ set(source_files model/frame-capture-model.cc model/frame-exchange-manager.cc model/he/constant-obss-pd-algorithm.cc + model/he/he-6ghz-band-capabilities.cc model/he/he-capabilities.cc model/he/he-configuration.cc model/he/he-frame-exchange-manager.cc @@ -197,6 +198,7 @@ set(header_files model/frame-capture-model.h model/frame-exchange-manager.h model/he/constant-obss-pd-algorithm.h + model/he/he-6ghz-band-capabilities.h model/he/he-capabilities.h model/he/he-configuration.h model/he/he-frame-exchange-manager.h diff --git a/src/wifi/model/he/he-6ghz-band-capabilities.cc b/src/wifi/model/he/he-6ghz-band-capabilities.cc new file mode 100644 index 000000000..ca6485fed --- /dev/null +++ b/src/wifi/model/he/he-6ghz-band-capabilities.cc @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2024 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Rami Abdallah + */ + +#include "he-6ghz-band-capabilities.h" + +namespace ns3 +{ + +He6GhzBandCapabilities::He6GhzBandCapabilities() + : m_capabilitiesInfo{} +{ +} + +WifiInformationElementId +He6GhzBandCapabilities::ElementId() const +{ + return IE_EXTENSION; +} + +WifiInformationElementId +He6GhzBandCapabilities::ElementIdExt() const +{ + return IE_EXT_HE_6GHZ_CAPABILITIES; +} + +uint16_t +He6GhzBandCapabilities::GetInformationFieldSize() const +{ + // Return size of Element ID Extension and + // Capabilities Information field in octets + return 1 + /* Element ID Ext */ +2 /* Capabilities Information */; +} + +void +He6GhzBandCapabilities::SetMaxAmpduLength(uint32_t maxAmpduLength) +{ + for (uint8_t i = 0; i <= 7; i++) + { + if ((1UL << (13 + i)) - 1 == maxAmpduLength) + { + m_capabilitiesInfo.m_maxAmpduLengthExponent = i; + return; + } + } + NS_ABORT_MSG("Invalid A-MPDU Max Length value"); +} + +uint32_t +He6GhzBandCapabilities::GetMaxAmpduLength() const +{ + return (1UL << (13 + m_capabilitiesInfo.m_maxAmpduLengthExponent)) - 1; +} + +void +He6GhzBandCapabilities::SetMaxMpduLength(uint16_t length) +{ + NS_ABORT_MSG_IF(length != 3895 && length != 7991 && length != 11454, + "Invalid MPDU Max Length value"); + if (length == 11454) + { + m_capabilitiesInfo.m_maxMpduLength = 2; + } + else if (length == 7991) + { + m_capabilitiesInfo.m_maxMpduLength = 1; + } + else + { + m_capabilitiesInfo.m_maxMpduLength = 0; + } +} + +uint16_t +He6GhzBandCapabilities::GetMaxMpduLength() const +{ + if (m_capabilitiesInfo.m_maxMpduLength == 0) + { + return 3895; + } + if (m_capabilitiesInfo.m_maxMpduLength == 1) + { + return 7991; + } + if (m_capabilitiesInfo.m_maxMpduLength == 2) + { + return 11454; + } + NS_ABORT_MSG("The value 3 is reserved"); +} + +void +He6GhzBandCapabilities::SerializeInformationField(Buffer::Iterator start) const +{ + uint16_t twoBytes = m_capabilitiesInfo.m_minMpduStartSpacing | + (m_capabilitiesInfo.m_maxAmpduLengthExponent << 3) | + (m_capabilitiesInfo.m_maxMpduLength << 6) | + (m_capabilitiesInfo.m_smPowerSave << 9) | + (m_capabilitiesInfo.m_rdResponder << 11) | + (m_capabilitiesInfo.m_rxAntennaPatternConsistency << 12) | + (m_capabilitiesInfo.m_txAntennaPatternConsistency << 13); + start.WriteHtolsbU16(twoBytes); +} + +uint16_t +He6GhzBandCapabilities::DeserializeInformationField(Buffer::Iterator start, uint16_t length) +{ + Buffer::Iterator tmp = start; + uint16_t twoBytes = start.ReadLsbtohU16(); + m_capabilitiesInfo.m_minMpduStartSpacing = twoBytes & 0x07; + m_capabilitiesInfo.m_maxAmpduLengthExponent = (twoBytes >> 3) & 0x07; + m_capabilitiesInfo.m_maxMpduLength = (twoBytes >> 6) & 0x03; + m_capabilitiesInfo.m_smPowerSave = (twoBytes >> 9) & 0x03; + m_capabilitiesInfo.m_rdResponder = (twoBytes >> 11) & 0x01; + m_capabilitiesInfo.m_rxAntennaPatternConsistency = (twoBytes >> 12) & 0x01; + m_capabilitiesInfo.m_txAntennaPatternConsistency = (twoBytes >> 13) & 0x01; + return start.GetDistanceFrom(tmp); +} + +void +He6GhzBandCapabilities::Print(std::ostream& os) const +{ + os << "HE 6GHz Band Capabilities=[Capabilities Information|" + << " Min MPDU start spacing: " << +m_capabilitiesInfo.m_minMpduStartSpacing + << " Max A-MPDU Length Exp: " << +m_capabilitiesInfo.m_maxAmpduLengthExponent + << " Max MPDU Length: " << +m_capabilitiesInfo.m_maxMpduLength + << " SM Power Save: " << +m_capabilitiesInfo.m_smPowerSave + << " RD Responder: " << +m_capabilitiesInfo.m_rdResponder + << " RX Antenna Pattern: " << +m_capabilitiesInfo.m_rxAntennaPatternConsistency + << " TX Antenna Pattern: " << +m_capabilitiesInfo.m_txAntennaPatternConsistency << "]"; +} + +} // namespace ns3 diff --git a/src/wifi/model/he/he-6ghz-band-capabilities.h b/src/wifi/model/he/he-6ghz-band-capabilities.h new file mode 100644 index 000000000..b8d1ccac5 --- /dev/null +++ b/src/wifi/model/he/he-6ghz-band-capabilities.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Rami Abdallah + */ + +#ifndef HE_6GHZ_BAND_CAPABILITIES_H +#define HE_6GHZ_BAND_CAPABILITIES_H + +#include "ns3/wifi-information-element.h" + +namespace ns3 +{ + +/** + * \ingroup wifi + * + * The HE 6 GHz Band Capabilities (IEEE 802.11ax-2021 9.4.2.263) + */ +class He6GhzBandCapabilities : public WifiInformationElement +{ + public: + He6GhzBandCapabilities(); + + WifiInformationElementId ElementId() const override; + WifiInformationElementId ElementIdExt() const override; + void Print(std::ostream& os) const override; + + /// Capabilities Information field + struct CapabilitiesInfo + { + uint8_t m_minMpduStartSpacing : 3; ///< Minimum MPDU Start Spacing + uint8_t m_maxAmpduLengthExponent : 3; ///< Maximum A-MPDU Length Exponent (can + ///< also be set via convenient methods) + uint8_t m_maxMpduLength : 2; ///< Maximum MPDU Length (can also + ///< be set via convenient methods) + uint8_t : 1; ///< Reserved Bits + uint8_t m_smPowerSave : 2; ///< SM Power Save + uint8_t m_rdResponder : 1; ///< RD Responder + uint8_t m_rxAntennaPatternConsistency : 1; ///< Receive Antenna Pattern Consistency + uint8_t m_txAntennaPatternConsistency : 1; ///< Transmit Antenna Pattern Consistency + uint8_t : 2; ///< Reserved Bits + }; + + CapabilitiesInfo m_capabilitiesInfo; ///< capabilities field + + /** + * Set the maximum AMPDU length. + * + * \param maxAmpduLength 2^(13 + x) - 1, x in the range 0 to 7 + */ + void SetMaxAmpduLength(uint32_t maxAmpduLength); + /** + * Return the maximum A-MPDU length. + * + * \return the maximum A-MPDU length in bytes + */ + uint32_t GetMaxAmpduLength() const; + + /** + * Set the maximum MPDU length. + * + * \param length the maximum MPDU length (3895, 7991 or 11454) + */ + void SetMaxMpduLength(uint16_t length); + /** + * Get the maximum MPDU length. + * + * \return the maximum MPDU length in bytes + */ + uint16_t GetMaxMpduLength() const; + + private: + uint16_t GetInformationFieldSize() const override; + void SerializeInformationField(Buffer::Iterator start) const override; + uint16_t DeserializeInformationField(Buffer::Iterator start, uint16_t length) override; +}; + +} // namespace ns3 + +#endif /* HE_6GHZ_BAND_CAPABILITY_H */ diff --git a/src/wifi/model/mgt-headers.h b/src/wifi/model/mgt-headers.h index 64385b1d6..846d03203 100644 --- a/src/wifi/model/mgt-headers.h +++ b/src/wifi/model/mgt-headers.h @@ -35,6 +35,7 @@ #include "ns3/eht-capabilities.h" #include "ns3/eht-operation.h" #include "ns3/erp-information.h" +#include "ns3/he-6ghz-band-capabilities.h" #include "ns3/he-capabilities.h" #include "ns3/he-operation.h" #include "ns3/ht-capabilities.h" @@ -96,6 +97,7 @@ using ProbeRequestElems = std::tuple, std::optional, std::optional, + std::optional, std::optional>; /// List of Information Elements included in Probe Response frames @@ -114,6 +116,7 @@ using ProbeResponseElems = std::tuple, std::optional, std::optional, + std::optional, std::optional, std::optional, std::optional, @@ -127,6 +130,7 @@ using AssocRequestElems = std::tuple, std::optional, std::optional, + std::optional, std::optional, std::optional, std::vector>; @@ -143,6 +147,7 @@ using AssocResponseElems = std::tuple, std::optional, std::optional, + std::optional, std::optional, std::optional, std::optional, diff --git a/src/wifi/model/wifi-information-element.h b/src/wifi/model/wifi-information-element.h index e1629a7de..15910d8b7 100644 --- a/src/wifi/model/wifi-information-element.h +++ b/src/wifi/model/wifi-information-element.h @@ -235,6 +235,8 @@ typedef uint8_t WifiInformationElementId; #define IE_EXT_NON_INHERITANCE ((WifiInformationElementId)56) +#define IE_EXT_HE_6GHZ_CAPABILITIES ((WifiInformationElementId)59) + #define IE_EXT_EHT_OPERATION ((WifiInformationElementId)106) #define IE_EXT_MULTI_LINK_ELEMENT ((WifiInformationElementId)107) #define IE_EXT_EHT_CAPABILITIES ((WifiInformationElementId)108) diff --git a/src/wifi/test/wifi-he-info-elems-test.cc b/src/wifi/test/wifi-he-info-elems-test.cc index ae378a9bb..4d6e27dc0 100644 --- a/src/wifi/test/wifi-he-info-elems-test.cc +++ b/src/wifi/test/wifi-he-info-elems-test.cc @@ -17,6 +17,7 @@ * Author: Stefano Avallone */ +#include "ns3/he-6ghz-band-capabilities.h" #include "ns3/he-operation.h" #include "ns3/header-serialization-test.h" #include "ns3/log.h" @@ -80,6 +81,43 @@ HeOperationElementTest::DoRun() TestHeaderSerialization(heOperation); } +/** + * \ingroup wifi-test + * \ingroup tests + * + * \brief Test HE 6 GHz Band Capabilities information element serialization and deserialization + */ +class He6GhzBandCapabilitiesTest : public HeaderSerializationTestCase +{ + public: + He6GhzBandCapabilitiesTest(); + + private: + void DoRun() override; +}; + +He6GhzBandCapabilitiesTest::He6GhzBandCapabilitiesTest() + : HeaderSerializationTestCase( + "Check serialization and deserialization of HE 6 GHz Band Capabilities elements") +{ +} + +void +He6GhzBandCapabilitiesTest::DoRun() +{ + He6GhzBandCapabilities he6GhzBandCapabilities; + + he6GhzBandCapabilities.m_capabilitiesInfo.m_minMpduStartSpacing = 5; + he6GhzBandCapabilities.SetMaxAmpduLength((static_cast(1) << 18) - 1); + he6GhzBandCapabilities.SetMaxMpduLength(11454); + he6GhzBandCapabilities.m_capabilitiesInfo.m_smPowerSave = 3; + he6GhzBandCapabilities.m_capabilitiesInfo.m_rdResponder = 1; + he6GhzBandCapabilities.m_capabilitiesInfo.m_rxAntennaPatternConsistency = 1; + he6GhzBandCapabilities.m_capabilitiesInfo.m_txAntennaPatternConsistency = 1; + + TestHeaderSerialization(he6GhzBandCapabilities); +} + /** * \ingroup wifi-test * \ingroup tests @@ -96,6 +134,7 @@ WifiHeInfoElemsTestSuite::WifiHeInfoElemsTestSuite() : TestSuite("wifi-he-info-elems", Type::UNIT) { AddTestCase(new HeOperationElementTest, TestCase::Duration::QUICK); + AddTestCase(new He6GhzBandCapabilitiesTest, TestCase::Duration::QUICK); } static WifiHeInfoElemsTestSuite g_wifiHeInfoElemsTestSuite; ///< the test suite