From ce6f794dc73a952ff8c186f38617cc72a38fa6df Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Tue, 12 Jul 2022 20:06:09 +0200 Subject: [PATCH] wifi: Make VHT Operation IE optional in mgt frames --- src/wifi/model/ap-wifi-mac.cc | 61 ++++++++++++++--------------- src/wifi/model/mgt-headers.cc | 20 +++++----- src/wifi/model/mgt-headers.h | 16 ++++---- src/wifi/model/sta-wifi-mac.cc | 2 +- src/wifi/model/vht/vht-operation.cc | 44 +++------------------ src/wifi/model/vht/vht-operation.h | 16 -------- 6 files changed, 55 insertions(+), 104 deletions(-) diff --git a/src/wifi/model/ap-wifi-mac.cc b/src/wifi/model/ap-wifi-mac.cc index 3fd63d105..317fabe18 100644 --- a/src/wifi/model/ap-wifi-mac.cc +++ b/src/wifi/model/ap-wifi-mac.cc @@ -757,44 +757,43 @@ VhtOperation ApWifiMac::GetVhtOperation (void) const { NS_LOG_FUNCTION (this); + NS_ASSERT (GetVhtSupported ()); VhtOperation operation; - if (GetVhtSupported ()) + + const uint16_t bssBandwidth = GetWifiPhy ()->GetChannelWidth (); + // Set to 0 for 20 MHz or 40 MHz BSS bandwidth. + // Set to 1 for 80 MHz, 160 MHz or 80+80 MHz BSS bandwidth. + operation.SetChannelWidth ((bssBandwidth > 40) ? 1 : 0); + // For 20, 40, or 80 MHz BSS bandwidth, indicates the channel center frequency + // index for the 20, 40, or 80 MHz channel on which the VHT BSS operates. + // For 160 MHz BSS bandwidth and the Channel Width subfield equal to 1, + // indicates the channel center frequency index of the 80 MHz channel + // segment that contains the primary channel. + operation.SetChannelCenterFrequencySegment0 ((bssBandwidth == 160) ? + GetWifiPhy ()->GetOperatingChannel ().GetPrimaryChannelNumber (80, WIFI_STANDARD_80211ac) : + GetWifiPhy ()->GetChannelNumber ()); + // For a 20, 40, or 80 MHz BSS bandwidth, this subfield is set to 0. + // For a 160 MHz BSS bandwidth and the Channel Width subfield equal to 1, + // indicates the channel center frequency index of the 160 MHz channel on + // which the VHT BSS operates. + operation.SetChannelCenterFrequencySegment1 ((bssBandwidth == 160) ? GetWifiPhy ()->GetChannelNumber () : 0); + uint8_t maxSpatialStream = GetWifiPhy ()->GetMaxSupportedRxSpatialStreams (); + for (const auto& sta : GetLink (SINGLE_LINK_OP_ID).staList) { - operation.SetVhtSupported (1); - const uint16_t bssBandwidth = GetWifiPhy ()->GetChannelWidth (); - // Set to 0 for 20 MHz or 40 MHz BSS bandwidth. - // Set to 1 for 80 MHz, 160 MHz or 80+80 MHz BSS bandwidth. - operation.SetChannelWidth ((bssBandwidth > 40) ? 1 : 0); - // For 20, 40, or 80 MHz BSS bandwidth, indicates the channel center frequency - // index for the 20, 40, or 80 MHz channel on which the VHT BSS operates. - // For 160 MHz BSS bandwidth and the Channel Width subfield equal to 1, - // indicates the channel center frequency index of the 80 MHz channel - // segment that contains the primary channel. - operation.SetChannelCenterFrequencySegment0 ((bssBandwidth == 160) ? - GetWifiPhy ()->GetOperatingChannel ().GetPrimaryChannelNumber (80, WIFI_STANDARD_80211ac) : - GetWifiPhy ()->GetChannelNumber ()); - // For a 20, 40, or 80 MHz BSS bandwidth, this subfield is set to 0. - // For a 160 MHz BSS bandwidth and the Channel Width subfield equal to 1, - // indicates the channel center frequency index of the 160 MHz channel on - // which the VHT BSS operates. - operation.SetChannelCenterFrequencySegment1 ((bssBandwidth == 160) ? GetWifiPhy ()->GetChannelNumber () : 0); - uint8_t maxSpatialStream = GetWifiPhy ()->GetMaxSupportedRxSpatialStreams (); - for (const auto& sta : GetLink (SINGLE_LINK_OP_ID).staList) + if (GetWifiRemoteStationManager ()->GetVhtSupported (sta.second)) { - if (GetWifiRemoteStationManager ()->GetVhtSupported (sta.second)) + if (GetWifiRemoteStationManager ()->GetNumberOfSupportedStreams (sta.second) < maxSpatialStream) { - if (GetWifiRemoteStationManager ()->GetNumberOfSupportedStreams (sta.second) < maxSpatialStream) - { - maxSpatialStream = GetWifiRemoteStationManager ()->GetNumberOfSupportedStreams (sta.second); - } + maxSpatialStream = GetWifiRemoteStationManager ()->GetNumberOfSupportedStreams (sta.second); } } - for (uint8_t nss = 1; nss <= maxSpatialStream; nss++) - { - uint8_t maxMcs = 9; //TBD: hardcode to 9 for now since we assume all MCS values are supported - operation.SetMaxVhtMcsPerNss (nss, maxMcs); - } } + for (uint8_t nss = 1; nss <= maxSpatialStream; nss++) + { + uint8_t maxMcs = 9; //TBD: hardcode to 9 for now since we assume all MCS values are supported + operation.SetMaxVhtMcsPerNss (nss, maxMcs); + } + return operation; } diff --git a/src/wifi/model/mgt-headers.cc b/src/wifi/model/mgt-headers.cc index 57de5036c..f11c6c219 100644 --- a/src/wifi/model/mgt-headers.cc +++ b/src/wifi/model/mgt-headers.cc @@ -376,7 +376,7 @@ MgtProbeResponseHeader::SetVhtOperation (VhtOperation&& vhtOperation) m_vhtOperation = std::move (vhtOperation); } -const VhtOperation& +const std::optional& MgtProbeResponseHeader::GetVhtOperation (void) const { return m_vhtOperation; @@ -596,7 +596,7 @@ MgtProbeResponseHeader::GetSerializedSize (void) const if (m_htCapability.has_value ()) size += m_htCapability->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_vhtOperation.has_value ()) size += m_vhtOperation->GetSerializedSize (); if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize (); size += m_heOperation.GetSerializedSize (); size += m_muEdcaParameterSet.GetSerializedSize (); @@ -616,7 +616,7 @@ MgtProbeResponseHeader::Print (std::ostream &os) const if (m_htCapability.has_value ()) os << "HT Capabilities=" << *m_htCapability << " , "; 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_vhtOperation.has_value ()) os << "VHT Operation=" << *m_vhtOperation << " , "; if (m_heCapability.has_value ()) os << "HE Capabilities=" << *m_heCapability << " , "; os << "HE Operation=" << m_heOperation << " , "; if (m_ehtCapability.has_value ()) os << "EHT Capabilities=" << *m_ehtCapability; @@ -639,7 +639,7 @@ MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const if (m_htCapability.has_value ()) i = m_htCapability->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_vhtOperation.has_value ()) i = m_vhtOperation->Serialize (i); if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i); i = m_heOperation.Serialize (i); i = m_muEdcaParameterSet.Serialize (i); @@ -666,7 +666,7 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start) i = WifiInformationElement::DeserializeIfPresent (m_htCapability, i); i = WifiInformationElement::DeserializeIfPresent (m_htOperation, i); i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i); - i = m_vhtOperation.DeserializeIfPresent (i); + i = WifiInformationElement::DeserializeIfPresent (m_vhtOperation, i); i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i); i = m_heOperation.DeserializeIfPresent (i); i = m_muEdcaParameterSet.DeserializeIfPresent (i); @@ -1392,7 +1392,7 @@ MgtAssocResponseHeader::SetVhtOperation (VhtOperation&& vhtOperation) m_vhtOperation = std::move (vhtOperation); } -const VhtOperation& +const std::optional& MgtAssocResponseHeader::GetVhtOperation (void) const { return m_vhtOperation; @@ -1562,7 +1562,7 @@ MgtAssocResponseHeader::GetSerializedSize (void) const if (m_htCapability.has_value ()) size += m_htCapability->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_vhtOperation.has_value ()) size += m_vhtOperation->GetSerializedSize (); if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize (); size += m_heOperation.GetSerializedSize (); size += m_muEdcaParameterSet.GetSerializedSize (); @@ -1582,7 +1582,7 @@ MgtAssocResponseHeader::Print (std::ostream &os) const if (m_htCapability.has_value ()) os << "HT Capabilities=" << *m_htCapability << " , "; 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_vhtOperation.has_value ()) os << "VHT Operation=" << *m_vhtOperation << " , "; if (m_heCapability.has_value ()) os << "HE Capabilities=" << *m_heCapability << " , "; os << "HE Operation=" << m_heOperation << " , "; if (m_ehtCapability.has_value ()) os << "EHT Capabilities=" << *m_ehtCapability; @@ -1603,7 +1603,7 @@ MgtAssocResponseHeader::Serialize (Buffer::Iterator start) const if (m_htCapability.has_value ()) i = m_htCapability->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_vhtOperation.has_value ()) i = m_vhtOperation->Serialize (i); if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i); i = m_heOperation.Serialize (i); i = m_muEdcaParameterSet.Serialize (i); @@ -1626,7 +1626,7 @@ MgtAssocResponseHeader::Deserialize (Buffer::Iterator start) i = WifiInformationElement::DeserializeIfPresent (m_htCapability, i); i = WifiInformationElement::DeserializeIfPresent (m_htOperation, i); i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i); - i = m_vhtOperation.DeserializeIfPresent (i); + i = WifiInformationElement::DeserializeIfPresent (m_vhtOperation, i); i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i); i = m_heOperation.DeserializeIfPresent (i); i = m_muEdcaParameterSet.DeserializeIfPresent (i); diff --git a/src/wifi/model/mgt-headers.h b/src/wifi/model/mgt-headers.h index b8e30de38..9b9b8cdb9 100644 --- a/src/wifi/model/mgt-headers.h +++ b/src/wifi/model/mgt-headers.h @@ -490,11 +490,11 @@ public: */ const std::optional& GetVhtCapabilities (void) const; /** - * Return the VHT operation. + * Return the VHT operation, if present. * - * \return VHT operation + * \return VHT operation, if present */ - const VhtOperation& GetVhtOperation (void) const; + const std::optional& GetVhtOperation (void) const; /** * Return the HE capabilities, if present. * @@ -717,7 +717,7 @@ private: std::optional m_htCapability; //!< HT capabilities std::optional m_htOperation; //!< HT operation std::optional m_vhtCapability; //!< VHT capabilities - VhtOperation m_vhtOperation; //!< VHT operation + std::optional m_vhtOperation; //!< VHT operation ErpInformation m_erpInformation; //!< ERP information EdcaParameterSet m_edcaParameterSet; //!< EDCA Parameter Set std::optional m_heCapability; //!< HE capabilities @@ -944,11 +944,11 @@ public: */ const std::optional& GetVhtCapabilities (void) const; /** - * Return the VHT operation. + * Return the VHT operation, if present. * - * \return VHT operation + * \return VHT operation, if present */ - const VhtOperation& GetVhtOperation (void) const; + const std::optional& GetVhtOperation (void) const; /** * Return the HE capabilities, if present. * @@ -1199,7 +1199,7 @@ private: std::optional m_htCapability; //!< HT capabilities std::optional m_htOperation; //!< HT operation std::optional m_vhtCapability; //!< VHT capabilities - VhtOperation m_vhtOperation; //!< VHT operation + std::optional m_vhtOperation; //!< VHT operation std::optional m_heCapability; //!< HE capabilities HeOperation m_heOperation; //!< HE operation ErpInformation m_erpInformation; //!< ERP information diff --git a/src/wifi/model/sta-wifi-mac.cc b/src/wifi/model/sta-wifi-mac.cc index b20375b28..5e3224d38 100644 --- a/src/wifi/model/sta-wifi-mac.cc +++ b/src/wifi/model/sta-wifi-mac.cc @@ -1136,7 +1136,7 @@ StaWifiMac::UpdateApInfo (const MgtFrameType& frame, const Mac48Address& apAddr, if (vhtCapabilities.has_value () && vhtCapabilities->GetRxHighestSupportedLgiDataRate () > 0) { GetWifiRemoteStationManager (linkId)->AddStationVhtCapabilities (apAddr, *vhtCapabilities); - VhtOperation vhtOperation = frame.GetVhtOperation (); + // const auto& vhtOperation = frame.GetVhtOperation (); for (const auto & mcs : GetWifiPhy (linkId)->GetMcsList (WIFI_MOD_CLASS_VHT)) { if (vhtCapabilities->IsSupportedRxMcs (mcs.GetMcsValue ())) diff --git a/src/wifi/model/vht/vht-operation.cc b/src/wifi/model/vht/vht-operation.cc index 897477a1c..f1346d6a3 100644 --- a/src/wifi/model/vht/vht-operation.cc +++ b/src/wifi/model/vht/vht-operation.cc @@ -26,8 +26,7 @@ VhtOperation::VhtOperation () : m_channelWidth (0), m_channelCenterFrequencySegment0 (0), m_channelCenterFrequencySegment1 (0), - m_basicVhtMcsAndNssSet (0), - m_vhtSupported (0) + m_basicVhtMcsAndNssSet (0) { } @@ -37,17 +36,9 @@ VhtOperation::ElementId () const return IE_VHT_OPERATION; } -void -VhtOperation::SetVhtSupported (uint8_t vhtSupported) -{ - m_vhtSupported = vhtSupported; -} - uint8_t VhtOperation::GetInformationFieldSize () const { - //we should not be here if VHT is not supported - NS_ASSERT (m_vhtSupported > 0); return 5; } @@ -113,37 +104,14 @@ VhtOperation::GetBasicVhtMcsAndNssSet (void) const return m_basicVhtMcsAndNssSet; } -Buffer::Iterator -VhtOperation::Serialize (Buffer::Iterator i) const -{ - if (m_vhtSupported < 1) - { - return i; - } - return WifiInformationElement::Serialize (i); -} - -uint16_t -VhtOperation::GetSerializedSize () const -{ - if (m_vhtSupported < 1) - { - return 0; - } - return WifiInformationElement::GetSerializedSize (); -} - void VhtOperation::SerializeInformationField (Buffer::Iterator start) const { - if (m_vhtSupported == 1) - { - //write the corresponding value for each bit - start.WriteU8 (GetChannelWidth ()); - start.WriteU8 (GetChannelCenterFrequencySegment0 ()); - start.WriteU8 (GetChannelCenterFrequencySegment1 ()); - start.WriteU16 (GetBasicVhtMcsAndNssSet ()); - } + //write the corresponding value for each bit + start.WriteU8 (GetChannelWidth ()); + start.WriteU8 (GetChannelCenterFrequencySegment0 ()); + start.WriteU8 (GetChannelCenterFrequencySegment1 ()); + start.WriteU16 (GetBasicVhtMcsAndNssSet ()); } uint8_t diff --git a/src/wifi/model/vht/vht-operation.h b/src/wifi/model/vht/vht-operation.h index e9ddd96e6..d2a053f9c 100644 --- a/src/wifi/model/vht/vht-operation.h +++ b/src/wifi/model/vht/vht-operation.h @@ -42,19 +42,6 @@ public: uint8_t GetInformationFieldSize () const override; 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 a VHT 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 VHT supported information element. - * - * \param vhtSupported the VHT supported information element - */ - void SetVhtSupported (uint8_t vhtSupported); /** * Set the Channel Width field in the VHT Operation information element. @@ -123,9 +110,6 @@ private: //Basic VHT-MCS and NSS Set uint16_t m_basicVhtMcsAndNssSet; ///< basic VHT MCS NSS set - - /// This is used to decide whether this element should be added to the frame or not - uint8_t m_vhtSupported; }; /**