From 2610957d0a1e45c358790fcd47a2d2f4bb77e595 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Tue, 12 Jul 2022 19:08:44 +0200 Subject: [PATCH] wifi: Make HT Operation IE optional in mgt frames --- src/wifi/model/ap-wifi-mac.cc | 157 +++++++++++++++--------------- src/wifi/model/ht/ht-operation.cc | 48 ++------- src/wifi/model/ht/ht-operation.h | 16 --- src/wifi/model/mgt-headers.cc | 20 ++-- src/wifi/model/mgt-headers.h | 16 +-- src/wifi/test/wifi-test.cc | 4 +- 6 files changed, 106 insertions(+), 155 deletions(-) diff --git a/src/wifi/model/ap-wifi-mac.cc b/src/wifi/model/ap-wifi-mac.cc index fdefe9f5d..3fd63d105 100644 --- a/src/wifi/model/ap-wifi-mac.cc +++ b/src/wifi/model/ap-wifi-mac.cc @@ -669,88 +669,87 @@ HtOperation ApWifiMac::GetHtOperation (void) const { NS_LOG_FUNCTION (this); + NS_ASSERT (GetHtSupported ()); HtOperation operation; - if (GetHtSupported ()) + + operation.SetPrimaryChannel (GetWifiPhy ()->GetPrimaryChannelNumber (20)); + operation.SetRifsMode (false); + operation.SetNonGfHtStasPresent (true); + if (GetWifiPhy ()->GetChannelWidth () > 20) { - operation.SetHtSupported (1); - operation.SetPrimaryChannel (GetWifiPhy ()->GetPrimaryChannelNumber (20)); - operation.SetRifsMode (false); - operation.SetNonGfHtStasPresent (true); - if (GetWifiPhy ()->GetChannelWidth () > 20) - { - operation.SetSecondaryChannelOffset (1); - operation.SetStaChannelWidth (1); - } - if (m_numNonHtStations == 0) - { - operation.SetHtProtection (NO_PROTECTION); - } - else - { - operation.SetHtProtection (MIXED_MODE_PROTECTION); - } - uint64_t maxSupportedRate = 0; //in bit/s - for (const auto & mcs : GetWifiPhy ()->GetMcsList (WIFI_MOD_CLASS_HT)) - { - uint8_t nss = (mcs.GetMcsValue () / 8) + 1; - NS_ASSERT (nss > 0 && nss < 5); - uint64_t dataRate = mcs.GetDataRate (GetWifiPhy ()->GetChannelWidth (), GetHtConfiguration ()->GetShortGuardIntervalSupported () ? 400 : 800, nss); - if (dataRate > maxSupportedRate) - { - maxSupportedRate = dataRate; - NS_LOG_DEBUG ("Updating maxSupportedRate to " << maxSupportedRate); - } - } - uint8_t maxSpatialStream = GetWifiPhy ()->GetMaxSupportedTxSpatialStreams (); - auto mcsList = GetWifiPhy ()->GetMcsList (WIFI_MOD_CLASS_HT); - uint8_t nMcs = mcsList.size (); - for (const auto& sta : GetLink (SINGLE_LINK_OP_ID).staList) - { - if (GetWifiRemoteStationManager ()->GetHtSupported (sta.second)) - { - uint64_t maxSupportedRateByHtSta = 0; //in bit/s - auto itMcs = mcsList.begin (); - for (uint8_t j = 0; j < (std::min (nMcs, GetWifiRemoteStationManager ()->GetNMcsSupported (sta.second))); j++) - { - WifiMode mcs = *itMcs++; - uint8_t nss = (mcs.GetMcsValue () / 8) + 1; - NS_ASSERT (nss > 0 && nss < 5); - uint64_t dataRate = mcs.GetDataRate (GetWifiRemoteStationManager ()->GetChannelWidthSupported (sta.second), - GetWifiRemoteStationManager ()->GetShortGuardIntervalSupported (sta.second) ? 400 : 800, nss); - if (dataRate > maxSupportedRateByHtSta) - { - maxSupportedRateByHtSta = dataRate; - } - } - if (maxSupportedRateByHtSta < maxSupportedRate) - { - maxSupportedRate = maxSupportedRateByHtSta; - } - if (GetWifiRemoteStationManager ()->GetNMcsSupported (sta.second) < nMcs) - { - nMcs = GetWifiRemoteStationManager ()->GetNMcsSupported (sta.second); - } - if (GetWifiRemoteStationManager ()->GetNumberOfSupportedStreams (sta.second) < maxSpatialStream) - { - maxSpatialStream = GetWifiRemoteStationManager ()->GetNumberOfSupportedStreams (sta.second); - } - } - } - operation.SetRxHighestSupportedDataRate (static_cast (maxSupportedRate / 1e6)); //in Mbit/s - operation.SetTxMcsSetDefined (nMcs > 0); - operation.SetTxMaxNSpatialStreams (maxSpatialStream); - //To be filled in once supported - operation.SetObssNonHtStasPresent (0); - operation.SetDualBeacon (0); - operation.SetDualCtsProtection (0); - operation.SetStbcBeacon (0); - operation.SetLSigTxopProtectionFullSupport (0); - operation.SetPcoActive (0); - operation.SetPhase (0); - operation.SetRxMcsBitmask (0); - operation.SetTxRxMcsSetUnequal (0); - operation.SetTxUnequalModulation (0); + operation.SetSecondaryChannelOffset (1); + operation.SetStaChannelWidth (1); } + if (m_numNonHtStations == 0) + { + operation.SetHtProtection (NO_PROTECTION); + } + else + { + operation.SetHtProtection (MIXED_MODE_PROTECTION); + } + uint64_t maxSupportedRate = 0; //in bit/s + for (const auto & mcs : GetWifiPhy ()->GetMcsList (WIFI_MOD_CLASS_HT)) + { + uint8_t nss = (mcs.GetMcsValue () / 8) + 1; + NS_ASSERT (nss > 0 && nss < 5); + uint64_t dataRate = mcs.GetDataRate (GetWifiPhy ()->GetChannelWidth (), GetHtConfiguration ()->GetShortGuardIntervalSupported () ? 400 : 800, nss); + if (dataRate > maxSupportedRate) + { + maxSupportedRate = dataRate; + NS_LOG_DEBUG ("Updating maxSupportedRate to " << maxSupportedRate); + } + } + uint8_t maxSpatialStream = GetWifiPhy ()->GetMaxSupportedTxSpatialStreams (); + auto mcsList = GetWifiPhy ()->GetMcsList (WIFI_MOD_CLASS_HT); + uint8_t nMcs = mcsList.size (); + for (const auto& sta : GetLink (SINGLE_LINK_OP_ID).staList) + { + if (GetWifiRemoteStationManager ()->GetHtSupported (sta.second)) + { + uint64_t maxSupportedRateByHtSta = 0; //in bit/s + auto itMcs = mcsList.begin (); + for (uint8_t j = 0; j < (std::min (nMcs, GetWifiRemoteStationManager ()->GetNMcsSupported (sta.second))); j++) + { + WifiMode mcs = *itMcs++; + uint8_t nss = (mcs.GetMcsValue () / 8) + 1; + NS_ASSERT (nss > 0 && nss < 5); + uint64_t dataRate = mcs.GetDataRate (GetWifiRemoteStationManager ()->GetChannelWidthSupported (sta.second), + GetWifiRemoteStationManager ()->GetShortGuardIntervalSupported (sta.second) ? 400 : 800, nss); + if (dataRate > maxSupportedRateByHtSta) + { + maxSupportedRateByHtSta = dataRate; + } + } + if (maxSupportedRateByHtSta < maxSupportedRate) + { + maxSupportedRate = maxSupportedRateByHtSta; + } + if (GetWifiRemoteStationManager ()->GetNMcsSupported (sta.second) < nMcs) + { + nMcs = GetWifiRemoteStationManager ()->GetNMcsSupported (sta.second); + } + if (GetWifiRemoteStationManager ()->GetNumberOfSupportedStreams (sta.second) < maxSpatialStream) + { + maxSpatialStream = GetWifiRemoteStationManager ()->GetNumberOfSupportedStreams (sta.second); + } + } + } + operation.SetRxHighestSupportedDataRate (static_cast (maxSupportedRate / 1e6)); //in Mbit/s + operation.SetTxMcsSetDefined (nMcs > 0); + operation.SetTxMaxNSpatialStreams (maxSpatialStream); + //To be filled in once supported + operation.SetObssNonHtStasPresent (0); + operation.SetDualBeacon (0); + operation.SetDualCtsProtection (0); + operation.SetStbcBeacon (0); + operation.SetLSigTxopProtectionFullSupport (0); + operation.SetPcoActive (0); + operation.SetPhase (0); + operation.SetRxMcsBitmask (0); + operation.SetTxRxMcsSetUnequal (0); + operation.SetTxUnequalModulation (0); + return operation; } diff --git a/src/wifi/model/ht/ht-operation.cc b/src/wifi/model/ht/ht-operation.cc index 3a7a30fdd..8891f1a66 100644 --- a/src/wifi/model/ht/ht-operation.cc +++ b/src/wifi/model/ht/ht-operation.cc @@ -48,8 +48,7 @@ HtOperation::HtOperation () m_txRxMcsSetUnequal (0), m_txMaxNSpatialStreams (0), m_txUnequalModulation (0), - m_reservedMcsSet3 (0), - m_htSupported (0) + m_reservedMcsSet3 (0) { for (uint8_t k = 0; k < MAX_SUPPORTED_MCS; k++) { @@ -63,17 +62,9 @@ HtOperation::ElementId () const return IE_HT_OPERATION; } -void -HtOperation::SetHtSupported (uint8_t htSupported) -{ - m_htSupported = htSupported; -} - uint8_t HtOperation::GetInformationFieldSize () const { - //we should not be here if HT is not supported - NS_ASSERT (m_htSupported > 0); return 22; } @@ -309,26 +300,6 @@ HtOperation::GetTxUnequalModulation (void) const return m_txUnequalModulation; } -Buffer::Iterator -HtOperation::Serialize (Buffer::Iterator i) const -{ - if (m_htSupported < 1) - { - return i; - } - return WifiInformationElement::Serialize (i); -} - -uint16_t -HtOperation::GetSerializedSize () const -{ - if (m_htSupported < 1) - { - return 0; - } - return WifiInformationElement::GetSerializedSize (); -} - uint8_t HtOperation::GetInformationSubset1 (void) const { @@ -458,16 +429,13 @@ HtOperation::GetBasicMcsSet2 (void) const void HtOperation::SerializeInformationField (Buffer::Iterator start) const { - if (m_htSupported == 1) - { - //write the corresponding value for each bit - start.WriteU8 (GetPrimaryChannel ()); - start.WriteU8 (GetInformationSubset1 ()); - start.WriteU16 (GetInformationSubset2 ()); - start.WriteU16 (GetInformationSubset3 ()); - start.WriteHtolsbU64 (GetBasicMcsSet1 ()); - start.WriteHtolsbU64 (GetBasicMcsSet2 ()); - } + //write the corresponding value for each bit + start.WriteU8 (GetPrimaryChannel ()); + start.WriteU8 (GetInformationSubset1 ()); + start.WriteU16 (GetInformationSubset2 ()); + start.WriteU16 (GetInformationSubset3 ()); + start.WriteHtolsbU64 (GetBasicMcsSet1 ()); + start.WriteHtolsbU64 (GetBasicMcsSet2 ()); } uint8_t diff --git a/src/wifi/model/ht/ht-operation.h b/src/wifi/model/ht/ht-operation.h index f2752db4b..16d144835 100644 --- a/src/wifi/model/ht/ht-operation.h +++ b/src/wifi/model/ht/ht-operation.h @@ -58,19 +58,6 @@ public: void SerializeInformationField (Buffer::Iterator start) const override; uint8_t DeserializeInformationField (Buffer::Iterator start, uint8_t length) override; - /* This information element is a bit special in that it is only - included if the STA is an HT STA. To support this we - override the Serialize and GetSerializedSize methods of - WifiInformationElement. */ - Buffer::Iterator Serialize (Buffer::Iterator start) const override; - uint16_t GetSerializedSize () const override; - - /** - * Set the HT Supported. - * - * \param htSupported the HT Supported flag - */ - void SetHtSupported (uint8_t htSupported); /** * Set the Primary Channel field in the HT Operation information element. @@ -404,9 +391,6 @@ private: uint8_t m_txUnequalModulation; ///< transmit unequal modulation uint32_t m_reservedMcsSet3; ///< reserved MCS set 3 uint8_t m_rxMcsBitmask[MAX_SUPPORTED_MCS]; ///< receive MCS bitmask - - /// This is used to decide whether this element should be added to the frame or not - uint8_t m_htSupported; }; /** diff --git a/src/wifi/model/mgt-headers.cc b/src/wifi/model/mgt-headers.cc index d2fa5d971..57de5036c 100644 --- a/src/wifi/model/mgt-headers.cc +++ b/src/wifi/model/mgt-headers.cc @@ -340,7 +340,7 @@ MgtProbeResponseHeader::SetHtOperation (HtOperation&& htOperation) m_htOperation = std::move (htOperation); } -const HtOperation& +const std::optional& MgtProbeResponseHeader::GetHtOperation (void) const { return m_htOperation; @@ -594,7 +594,7 @@ MgtProbeResponseHeader::GetSerializedSize (void) const size += m_edcaParameterSet.GetSerializedSize (); size += m_extendedCapability.GetSerializedSize (); if (m_htCapability.has_value ()) size += m_htCapability->GetSerializedSize (); - size += m_htOperation.GetSerializedSize (); + if (m_htOperation.has_value ()) size += m_htOperation->GetSerializedSize (); if (m_vhtCapability.has_value ()) size += m_vhtCapability->GetSerializedSize (); size += m_vhtOperation.GetSerializedSize (); if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize (); @@ -614,7 +614,7 @@ MgtProbeResponseHeader::Print (std::ostream &os) const << "ERP information=" << m_erpInformation << ", " << "Extended Capabilities=" << m_extendedCapability << " , "; if (m_htCapability.has_value ()) os << "HT Capabilities=" << *m_htCapability << " , "; - os << "HT Operation=" << m_htOperation << " , "; + if (m_htOperation.has_value ()) os << "HT Operation=" << *m_htOperation << " , "; if (m_vhtCapability.has_value ()) os << "VHT Capabilities=" << *m_vhtCapability << " , "; os << "VHT Operation=" << m_vhtOperation << " , "; if (m_heCapability.has_value ()) os << "HE Capabilities=" << *m_heCapability << " , "; @@ -637,7 +637,7 @@ MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const i = m_edcaParameterSet.Serialize (i); i = m_extendedCapability.Serialize (i); if (m_htCapability.has_value ()) i = m_htCapability->Serialize (i); - i = m_htOperation.Serialize (i); + if (m_htOperation.has_value ()) i = m_htOperation->Serialize (i); if (m_vhtCapability.has_value ()) i = m_vhtCapability->Serialize (i); i = m_vhtOperation.Serialize (i); if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i); @@ -664,7 +664,7 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start) i = m_edcaParameterSet.DeserializeIfPresent (i); i = m_extendedCapability.DeserializeIfPresent (i); i = WifiInformationElement::DeserializeIfPresent (m_htCapability, i); - i = m_htOperation.DeserializeIfPresent (i); + i = WifiInformationElement::DeserializeIfPresent (m_htOperation, i); i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i); i = m_vhtOperation.DeserializeIfPresent (i); i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i); @@ -1356,7 +1356,7 @@ MgtAssocResponseHeader::SetHtOperation (HtOperation&& htOperation) m_htOperation = std::move (htOperation); } -const HtOperation& +const std::optional& MgtAssocResponseHeader::GetHtOperation (void) const { return m_htOperation; @@ -1560,7 +1560,7 @@ MgtAssocResponseHeader::GetSerializedSize (void) const size += m_edcaParameterSet.GetSerializedSize (); size += m_extendedCapability.GetSerializedSize (); if (m_htCapability.has_value ()) size += m_htCapability->GetSerializedSize (); - size += m_htOperation.GetSerializedSize (); + if (m_htOperation.has_value ()) size += m_htOperation->GetSerializedSize (); if (m_vhtCapability.has_value ()) size += m_vhtCapability->GetSerializedSize (); size += m_vhtOperation.GetSerializedSize (); if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize (); @@ -1580,7 +1580,7 @@ MgtAssocResponseHeader::Print (std::ostream &os) const << "ERP information=" << m_erpInformation << ", " << "Extended Capabilities=" << m_extendedCapability << " , "; if (m_htCapability.has_value ()) os << "HT Capabilities=" << *m_htCapability << " , "; - os << "HT Operation=" << m_htOperation << " , "; + if (m_htOperation.has_value ()) os << "HT Operation=" << *m_htOperation << " , "; if (m_vhtCapability.has_value ()) os << "VHT Capabilities=" << *m_vhtCapability << " , "; os << "VHT Operation=" << m_vhtOperation << " , "; if (m_heCapability.has_value ()) os << "HE Capabilities=" << *m_heCapability << " , "; @@ -1601,7 +1601,7 @@ MgtAssocResponseHeader::Serialize (Buffer::Iterator start) const i = m_edcaParameterSet.Serialize (i); i = m_extendedCapability.Serialize (i); if (m_htCapability.has_value ()) i = m_htCapability->Serialize (i); - i = m_htOperation.Serialize (i); + if (m_htOperation.has_value ()) i = m_htOperation->Serialize (i); if (m_vhtCapability.has_value ()) i = m_vhtCapability->Serialize (i); i = m_vhtOperation.Serialize (i); if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i); @@ -1624,7 +1624,7 @@ MgtAssocResponseHeader::Deserialize (Buffer::Iterator start) i = m_edcaParameterSet.DeserializeIfPresent (i); i = m_extendedCapability.DeserializeIfPresent (i); i = WifiInformationElement::DeserializeIfPresent (m_htCapability, i); - i = m_htOperation.DeserializeIfPresent (i); + i = WifiInformationElement::DeserializeIfPresent (m_htOperation, i); i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i); i = m_vhtOperation.DeserializeIfPresent (i); i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i); diff --git a/src/wifi/model/mgt-headers.h b/src/wifi/model/mgt-headers.h index 41524b447..b8e30de38 100644 --- a/src/wifi/model/mgt-headers.h +++ b/src/wifi/model/mgt-headers.h @@ -478,11 +478,11 @@ public: */ const std::optional& GetHtCapabilities (void) const; /** - * Return the HT operation. + * Return the HT operation, if present. * - * \return HT operation + * \return HT operation, if present */ - const HtOperation& GetHtOperation (void) const; + const std::optional& GetHtOperation (void) const; /** * Return the VHT capabilities, if present. * @@ -715,7 +715,7 @@ private: uint16_t m_aid; //!< AID ExtendedCapabilities m_extendedCapability; //!< extended capabilities std::optional m_htCapability; //!< HT capabilities - HtOperation m_htOperation; //!< HT operation + std::optional m_htOperation; //!< HT operation std::optional m_vhtCapability; //!< VHT capabilities VhtOperation m_vhtOperation; //!< VHT operation ErpInformation m_erpInformation; //!< ERP information @@ -932,11 +932,11 @@ public: */ const std::optional& GetHtCapabilities (void) const; /** - * Return the HT operation. + * Return the HT operation, if present. * - * \return HT operation + * \return HT operation, if present */ - const HtOperation& GetHtOperation (void) const; + const std::optional& GetHtOperation (void) const; /** * Return the VHT capabilities, if present. * @@ -1197,7 +1197,7 @@ private: DsssParameterSet m_dsssParameterSet; //!< DSSS Parameter Set ExtendedCapabilities m_extendedCapability; //!< extended capabilities std::optional m_htCapability; //!< HT capabilities - HtOperation m_htOperation; //!< HT operation + std::optional m_htOperation; //!< HT operation std::optional m_vhtCapability; //!< VHT capabilities VhtOperation m_vhtOperation; //!< VHT operation std::optional m_heCapability; //!< HE capabilities diff --git a/src/wifi/test/wifi-test.cc b/src/wifi/test/wifi-test.cc index ce8688cf3..5a94efe67 100644 --- a/src/wifi/test/wifi-test.cc +++ b/src/wifi/test/wifi-test.cc @@ -1715,8 +1715,8 @@ Bug2831TestCase::RxCallback (std::string context, Ptr p, RxPowerWa { MgtBeaconHeader beacon; packet->RemoveHeader (beacon); - HtOperation htOperation = beacon.GetHtOperation (); - if (htOperation.GetStaChannelWidth () > 0) + const auto& htOperation = beacon.GetHtOperation (); + if (htOperation.has_value () && htOperation->GetStaChannelWidth () > 0) { m_countOperationalChannelWidth40++; }