wifi: Make VHT Operation IE optional in mgt frames
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -376,7 +376,7 @@ MgtProbeResponseHeader::SetVhtOperation (VhtOperation&& vhtOperation)
|
||||
m_vhtOperation = std::move (vhtOperation);
|
||||
}
|
||||
|
||||
const VhtOperation&
|
||||
const std::optional<VhtOperation>&
|
||||
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<VhtOperation>&
|
||||
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);
|
||||
|
||||
@@ -490,11 +490,11 @@ public:
|
||||
*/
|
||||
const std::optional<VhtCapabilities>& 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<VhtOperation>& GetVhtOperation (void) const;
|
||||
/**
|
||||
* Return the HE capabilities, if present.
|
||||
*
|
||||
@@ -717,7 +717,7 @@ private:
|
||||
std::optional<HtCapabilities> m_htCapability; //!< HT capabilities
|
||||
std::optional<HtOperation> m_htOperation; //!< HT operation
|
||||
std::optional<VhtCapabilities> m_vhtCapability; //!< VHT capabilities
|
||||
VhtOperation m_vhtOperation; //!< VHT operation
|
||||
std::optional<VhtOperation> m_vhtOperation; //!< VHT operation
|
||||
ErpInformation m_erpInformation; //!< ERP information
|
||||
EdcaParameterSet m_edcaParameterSet; //!< EDCA Parameter Set
|
||||
std::optional<HeCapabilities> m_heCapability; //!< HE capabilities
|
||||
@@ -944,11 +944,11 @@ public:
|
||||
*/
|
||||
const std::optional<VhtCapabilities>& 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<VhtOperation>& GetVhtOperation (void) const;
|
||||
/**
|
||||
* Return the HE capabilities, if present.
|
||||
*
|
||||
@@ -1199,7 +1199,7 @@ private:
|
||||
std::optional<HtCapabilities> m_htCapability; //!< HT capabilities
|
||||
std::optional<HtOperation> m_htOperation; //!< HT operation
|
||||
std::optional<VhtCapabilities> m_vhtCapability; //!< VHT capabilities
|
||||
VhtOperation m_vhtOperation; //!< VHT operation
|
||||
std::optional<VhtOperation> m_vhtOperation; //!< VHT operation
|
||||
std::optional<HeCapabilities> m_heCapability; //!< HE capabilities
|
||||
HeOperation m_heOperation; //!< HE operation
|
||||
ErpInformation m_erpInformation; //!< ERP information
|
||||
|
||||
@@ -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 ()))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user