wifi: Make HE Capabilities IE optional in mgt frames

This commit is contained in:
Stefano Avallone
2022-07-12 18:42:34 +02:00
parent b0250e32b7
commit eeaadc4cbd
7 changed files with 117 additions and 165 deletions

View File

@@ -1462,13 +1462,13 @@ ApWifiMac::ReceiveAssocRequest (const AssocReqRefVariant& assoc, const Mac48Addr
if (GetHeSupported ())
{
//check whether the HE STA supports all MCSs in Basic MCS Set
const HeCapabilities& heCapabilities = frame.GetHeCapabilities ();
if (heCapabilities.GetSupportedMcsAndNss () != 0)
const auto& heCapabilities = frame.GetHeCapabilities ();
if (heCapabilities.has_value () && heCapabilities->GetSupportedMcsAndNss () != 0)
{
for (uint8_t i = 0; i < remoteStationManager->GetNBasicMcs (); i++)
{
WifiMode mcs = remoteStationManager->GetBasicMcs (i);
if (!heCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
if (!heCapabilities->IsSupportedTxMcs (mcs.GetMcsValue ()))
{
return failure ("HE STA does not support all MCSs in Basic MCS Set");
}
@@ -1526,13 +1526,13 @@ ApWifiMac::ReceiveAssocRequest (const AssocReqRefVariant& assoc, const Mac48Addr
}
if (GetHeSupported ())
{
const HeCapabilities& heCapabilities = frame.GetHeCapabilities ();
if (heCapabilities.GetSupportedMcsAndNss () != 0)
const auto& heCapabilities = frame.GetHeCapabilities ();
if (heCapabilities.has_value () && heCapabilities->GetSupportedMcsAndNss () != 0)
{
remoteStationManager->AddStationHeCapabilities (from, heCapabilities);
remoteStationManager->AddStationHeCapabilities (from, *heCapabilities);
for (const auto & mcs : phy->GetMcsList (WIFI_MOD_CLASS_HE))
{
if (heCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
if (heCapabilities->IsSupportedTxMcs (mcs.GetMcsValue ()))
{
remoteStationManager->AddSupportedMcs (from, mcs);
//here should add a control to add basic MCS when it is implemented

View File

@@ -117,8 +117,7 @@ HeCapabilities::HeCapabilities ()
m_nominalPacketPadding (0),
m_maxHeLtfRxInHeMuMoreThanOneRu (0),
m_highestNssSupportedM1 (0),
m_highestMcsSupported (0),
m_heSupported (0)
m_highestMcsSupported (0)
{
m_txBwMap.resize (8,0);
m_rxBwMap.resize (8,0);
@@ -136,17 +135,9 @@ HeCapabilities::ElementIdExt () const
return IE_EXT_HE_CAPABILITIES;
}
void
HeCapabilities::SetHeSupported (uint8_t heSupported)
{
m_heSupported = heSupported;
}
uint8_t
HeCapabilities::GetInformationFieldSize () const
{
//we should not be here if HE is not supported
NS_ASSERT (m_heSupported > 0);
// IEEE 802.11ax-2021 9.4.2.248 HE Capabilities element
// Element ID Extension (1) + HE MAC Capabilities Information (6)
// + HE PHY Capabilities Information (11) + Supported HE-MCS And NSS Set (4)
@@ -155,41 +146,18 @@ HeCapabilities::GetInformationFieldSize () const
return 22;
}
Buffer::Iterator
HeCapabilities::Serialize (Buffer::Iterator i) const
{
if (m_heSupported < 1)
{
return i;
}
return WifiInformationElement::Serialize (i);
}
uint16_t
HeCapabilities::GetSerializedSize () const
{
if (m_heSupported < 1)
{
return 0;
}
return WifiInformationElement::GetSerializedSize ();
}
void
HeCapabilities::SerializeInformationField (Buffer::Iterator start) const
{
if (m_heSupported == 1)
{
//write the corresponding value for each bit
start.WriteHtolsbU32 (GetHeMacCapabilitiesInfo1 ());
start.WriteU16 (GetHeMacCapabilitiesInfo2 ());
start.WriteHtolsbU64 (GetHePhyCapabilitiesInfo1 ());
start.WriteHtolsbU16 (GetHePhyCapabilitiesInfo2 ());
start.WriteU8 (GetHePhyCapabilitiesInfo3 ());
start.WriteHtolsbU32 (GetSupportedMcsAndNss ());
// TODO: add another 32-bits field if 160 MHz channel is supported (variable length)
// TODO: optional PPE Threshold field (variable length)
}
//write the corresponding value for each bit
start.WriteHtolsbU32 (GetHeMacCapabilitiesInfo1 ());
start.WriteU16 (GetHeMacCapabilitiesInfo2 ());
start.WriteHtolsbU64 (GetHePhyCapabilitiesInfo1 ());
start.WriteHtolsbU16 (GetHePhyCapabilitiesInfo2 ());
start.WriteU8 (GetHePhyCapabilitiesInfo3 ());
start.WriteHtolsbU32 (GetSupportedMcsAndNss ());
// TODO: add another 32-bits field if 160 MHz channel is supported (variable length)
// TODO: optional PPE Threshold field (variable length)
}
uint8_t

View File

@@ -41,18 +41,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 an HE 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 HE supported
* \param heSupported the HE supported indicator
*/
void SetHeSupported (uint8_t heSupported);
/**
* Set the HE MAC Capabilities Info field in the HE Capabilities information element.
@@ -325,9 +313,6 @@ private:
uint8_t m_highestMcsSupported; //!< highest MCS support
std::vector<uint8_t> m_txBwMap; //!< transmit BW map
std::vector<uint8_t> m_rxBwMap; //!< receive BW map
/// This is used to decide if this element should be added to the frame or not
uint8_t m_heSupported;
};
/**

View File

@@ -132,7 +132,7 @@ MgtProbeRequestHeader::SetHeCapabilities (HeCapabilities&& heCapabilities)
m_heCapability = std::move (heCapabilities);
}
const HeCapabilities&
const std::optional<HeCapabilities>&
MgtProbeRequestHeader::GetHeCapabilities (void) const
{
return m_heCapability;
@@ -172,7 +172,7 @@ MgtProbeRequestHeader::GetSerializedSize (void) const
size += m_extendedCapability.GetSerializedSize ();
if (m_htCapability.has_value ()) size += m_htCapability->GetSerializedSize ();
if (m_vhtCapability.has_value ()) size += m_vhtCapability->GetSerializedSize ();
size += m_heCapability.GetSerializedSize ();
if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize ();
size += m_ehtCapability.GetSerializedSize ();
return size;
}
@@ -202,8 +202,8 @@ MgtProbeRequestHeader::Print (std::ostream &os) const
<< "Extended Capabilities=" << m_extendedCapability << " , ";
if (m_htCapability.has_value ()) os << "HT Capabilities=" << *m_htCapability << " , ";
if (m_vhtCapability.has_value ()) os << "VHT Capabilities=" << *m_vhtCapability << " , ";
os << "HE Capabilities=" << m_heCapability << " , "
<< "EHT Capabilities=" << m_ehtCapability;
if (m_heCapability.has_value ()) os << "HE Capabilities=" << *m_heCapability << " , ";
os << "EHT Capabilities=" << m_ehtCapability;
}
void
@@ -216,7 +216,7 @@ MgtProbeRequestHeader::Serialize (Buffer::Iterator start) const
i = m_extendedCapability.Serialize (i);
if (m_htCapability.has_value ()) i = m_htCapability->Serialize (i);
if (m_vhtCapability.has_value ()) i = m_vhtCapability->Serialize (i);
i = m_heCapability.Serialize (i);
if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i);
i = m_ehtCapability.Serialize (i);
}
@@ -230,7 +230,7 @@ MgtProbeRequestHeader::Deserialize (Buffer::Iterator start)
i = m_extendedCapability.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_htCapability, i);
i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i);
i = m_heCapability.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i);
i = m_ehtCapability.DeserializeIfPresent (i);
return i.GetDistanceFrom (start);
}
@@ -394,7 +394,7 @@ MgtProbeResponseHeader::SetHeCapabilities (HeCapabilities&& heCapabilities)
m_heCapability = std::move (heCapabilities);
}
const HeCapabilities&
const std::optional<HeCapabilities>&
MgtProbeResponseHeader::GetHeCapabilities (void) const
{
return m_heCapability;
@@ -597,7 +597,7 @@ MgtProbeResponseHeader::GetSerializedSize (void) const
size += m_htOperation.GetSerializedSize ();
if (m_vhtCapability.has_value ()) size += m_vhtCapability->GetSerializedSize ();
size += m_vhtOperation.GetSerializedSize ();
size += m_heCapability.GetSerializedSize ();
if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize ();
size += m_heOperation.GetSerializedSize ();
size += m_muEdcaParameterSet.GetSerializedSize ();
size += m_ehtCapability.GetSerializedSize ();
@@ -616,9 +616,9 @@ MgtProbeResponseHeader::Print (std::ostream &os) const
if (m_htCapability.has_value ()) os << "HT Capabilities=" << *m_htCapability << " , ";
os << "HT Operation=" << m_htOperation << " , ";
if (m_vhtCapability.has_value ()) os << "VHT Capabilities=" << *m_vhtCapability << " , ";
os << "VHT Operation=" << m_vhtOperation << " , "
<< "HE Capabilities=" << m_heCapability << " , "
<< "HE Operation=" << m_heOperation << " , "
os << "VHT Operation=" << m_vhtOperation << " , ";
if (m_heCapability.has_value ()) os << "HE Capabilities=" << *m_heCapability << " , ";
os << "HE Operation=" << m_heOperation << " , "
<< "EHT Capabilities=" << m_ehtCapability;
}
@@ -640,7 +640,7 @@ MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const
i = m_htOperation.Serialize (i);
if (m_vhtCapability.has_value ()) i = m_vhtCapability->Serialize (i);
i = m_vhtOperation.Serialize (i);
i = m_heCapability.Serialize (i);
if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i);
i = m_heOperation.Serialize (i);
i = m_muEdcaParameterSet.Serialize (i);
i = m_ehtCapability.Serialize (i);
@@ -667,7 +667,7 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start)
i = m_htOperation.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i);
i = m_vhtOperation.DeserializeIfPresent (i);
i = m_heCapability.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i);
i = m_heOperation.DeserializeIfPresent (i);
i = m_muEdcaParameterSet.DeserializeIfPresent (i);
i = m_ehtCapability.DeserializeIfPresent (i);
@@ -828,7 +828,7 @@ MgtAssocRequestHeader::SetHeCapabilities (HeCapabilities&& heCapabilities)
m_heCapability = std::move (heCapabilities);
}
const HeCapabilities&
const std::optional<HeCapabilities>&
MgtAssocRequestHeader::GetHeCapabilities (void) const
{
return m_heCapability;
@@ -911,7 +911,7 @@ MgtAssocRequestHeader::GetSerializedSize (void) const
size += m_extendedCapability.GetSerializedSize ();
if (m_htCapability.has_value ()) size += m_htCapability->GetSerializedSize ();
if (m_vhtCapability.has_value ()) size += m_vhtCapability->GetSerializedSize ();
size += m_heCapability.GetSerializedSize ();
if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize ();
size += m_ehtCapability.GetSerializedSize ();
if (m_multiLinkElement != nullptr) size += m_multiLinkElement->GetSerializedSize ();
return size;
@@ -925,8 +925,8 @@ MgtAssocRequestHeader::Print (std::ostream &os) const
<< "Extended Capabilities=" << m_extendedCapability << " , ";
if (m_htCapability.has_value ()) os << "HT Capabilities=" << *m_htCapability << " , ";
if (m_vhtCapability.has_value ()) os << "VHT Capabilities=" << *m_vhtCapability << " , ";
os << "HE Capabilities=" << m_heCapability << " , "
<< "EHT Capabilities=" << m_ehtCapability;
if (m_heCapability.has_value ()) os << "HE Capabilities=" << *m_heCapability << " , ";
os << "EHT Capabilities=" << m_ehtCapability;
}
void
@@ -941,7 +941,7 @@ MgtAssocRequestHeader::Serialize (Buffer::Iterator start) const
i = m_extendedCapability.Serialize (i);
if (m_htCapability.has_value ()) i = m_htCapability->Serialize (i);
if (m_vhtCapability.has_value ()) i = m_vhtCapability->Serialize (i);
i = m_heCapability.Serialize (i);
if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i);
i = m_ehtCapability.Serialize (i);
if (m_multiLinkElement != nullptr) i = m_multiLinkElement->Serialize (i);
}
@@ -958,7 +958,7 @@ MgtAssocRequestHeader::Deserialize (Buffer::Iterator start)
i = m_extendedCapability.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_htCapability, i);
i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i);
i = m_heCapability.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i);
i = m_ehtCapability.DeserializeIfPresent (i);
m_multiLinkElement = Create<MultiLinkElement> (WIFI_MAC_MGT_ASSOCIATION_REQUEST);
i = m_multiLinkElement->DeserializeIfPresent (tmp = i);
@@ -1096,7 +1096,7 @@ MgtReassocRequestHeader::SetHeCapabilities (HeCapabilities&& heCapabilities)
m_heCapability = std::move (heCapabilities);
}
const HeCapabilities&
const std::optional<HeCapabilities>&
MgtReassocRequestHeader::GetHeCapabilities (void) const
{
return m_heCapability;
@@ -1186,7 +1186,7 @@ MgtReassocRequestHeader::GetSerializedSize (void) const
size += m_extendedCapability.GetSerializedSize ();
if (m_htCapability.has_value ()) size += m_htCapability->GetSerializedSize ();
if (m_vhtCapability.has_value ()) size += m_vhtCapability->GetSerializedSize ();
size += m_heCapability.GetSerializedSize ();
if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize ();
size += m_ehtCapability.GetSerializedSize ();
if (m_multiLinkElement != nullptr) size += m_multiLinkElement->GetSerializedSize ();
return size;
@@ -1201,8 +1201,8 @@ MgtReassocRequestHeader::Print (std::ostream &os) const
<< "Extended Capabilities=" << m_extendedCapability << " , ";
if (m_htCapability.has_value ()) os << "HT Capabilities=" << *m_htCapability << " , ";
if (m_vhtCapability.has_value ()) os << "VHT Capabilities=" << *m_vhtCapability << " , ";
os << "HE Capabilities=" << m_heCapability << " , "
<< "EHT Capabilities=" << m_ehtCapability;
if (m_heCapability.has_value ()) os << "HE Capabilities=" << *m_heCapability << " , ";
os << "EHT Capabilities=" << m_ehtCapability;
}
void
@@ -1218,7 +1218,7 @@ MgtReassocRequestHeader::Serialize (Buffer::Iterator start) const
i = m_extendedCapability.Serialize (i);
if (m_htCapability.has_value ()) i = m_htCapability->Serialize (i);
if (m_vhtCapability.has_value ()) i = m_vhtCapability->Serialize (i);
i = m_heCapability.Serialize (i);
if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i);
i = m_ehtCapability.Serialize (i);
if (m_multiLinkElement != nullptr) i = m_multiLinkElement->Serialize (i);
}
@@ -1236,7 +1236,7 @@ MgtReassocRequestHeader::Deserialize (Buffer::Iterator start)
i = m_extendedCapability.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_htCapability, i);
i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i);
i = m_heCapability.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i);
i = m_ehtCapability.DeserializeIfPresent (i);
m_multiLinkElement = Create<MultiLinkElement> (WIFI_MAC_MGT_REASSOCIATION_REQUEST);
i = m_multiLinkElement->DeserializeIfPresent (tmp = i);
@@ -1410,7 +1410,7 @@ MgtAssocResponseHeader::SetHeCapabilities (HeCapabilities&& heCapabilities)
m_heCapability = std::move (heCapabilities);
}
const HeCapabilities&
const std::optional<HeCapabilities>&
MgtAssocResponseHeader::GetHeCapabilities (void) const
{
return m_heCapability;
@@ -1563,7 +1563,7 @@ MgtAssocResponseHeader::GetSerializedSize (void) const
size += m_htOperation.GetSerializedSize ();
if (m_vhtCapability.has_value ()) size += m_vhtCapability->GetSerializedSize ();
size += m_vhtOperation.GetSerializedSize ();
size += m_heCapability.GetSerializedSize ();
if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize ();
size += m_heOperation.GetSerializedSize ();
size += m_muEdcaParameterSet.GetSerializedSize ();
size += m_ehtCapability.GetSerializedSize ();
@@ -1582,9 +1582,9 @@ MgtAssocResponseHeader::Print (std::ostream &os) const
if (m_htCapability.has_value ()) os << "HT Capabilities=" << *m_htCapability << " , ";
os << "HT Operation=" << m_htOperation << " , ";
if (m_vhtCapability.has_value ()) os << "VHT Capabilities=" << *m_vhtCapability << " , ";
os << "VHT Operation=" << m_vhtOperation << " , "
<< "HE Capabilities=" << m_heCapability << " , "
<< "HE Operation=" << m_heOperation << " , "
os << "VHT Operation=" << m_vhtOperation << " , ";
if (m_heCapability.has_value ()) os << "HE Capabilities=" << *m_heCapability << " , ";
os << "HE Operation=" << m_heOperation << " , "
<< "EHT Capabilities=" << m_ehtCapability;
}
@@ -1604,7 +1604,7 @@ MgtAssocResponseHeader::Serialize (Buffer::Iterator start) const
i = m_htOperation.Serialize (i);
if (m_vhtCapability.has_value ()) i = m_vhtCapability->Serialize (i);
i = m_vhtOperation.Serialize (i);
i = m_heCapability.Serialize (i);
if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i);
i = m_heOperation.Serialize (i);
i = m_muEdcaParameterSet.Serialize (i);
i = m_ehtCapability.Serialize (i);
@@ -1627,7 +1627,7 @@ MgtAssocResponseHeader::Deserialize (Buffer::Iterator start)
i = m_htOperation.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_vhtCapability, i);
i = m_vhtOperation.DeserializeIfPresent (i);
i = m_heCapability.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i);
i = m_heOperation.DeserializeIfPresent (i);
i = m_muEdcaParameterSet.DeserializeIfPresent (i);
i = m_ehtCapability.DeserializeIfPresent (i);

View File

@@ -173,11 +173,11 @@ public:
*/
const std::optional<VhtCapabilities>& GetVhtCapabilities (void) const;
/**
* Return the HE capabilities.
* Return the HE capabilities, if present.
*
* \return HE capabilities
* \return HE capabilities, if present
*/
const HeCapabilities& GetHeCapabilities (void) const;
const std::optional<HeCapabilities>& GetHeCapabilities (void) const;
/**
* Return the EHT capabilities.
*
@@ -231,7 +231,7 @@ private:
ExtendedCapabilities m_extendedCapability; //!< Extended capabilities
std::optional<HtCapabilities> m_htCapability; //!< HT capabilities
std::optional<VhtCapabilities> m_vhtCapability; //!< VHT capabilities
HeCapabilities m_heCapability; //!< HE capabilities
std::optional<HeCapabilities> m_heCapability; //!< HE capabilities
uint16_t m_listenInterval; //!< listen interval
EhtCapabilities m_ehtCapability; //!< EHT capabilities
Ptr<MultiLinkElement> m_multiLinkElement; //!< Multi-Link Element
@@ -366,11 +366,11 @@ public:
*/
const std::optional<VhtCapabilities>& GetVhtCapabilities (void) const;
/**
* Return the HE capabilities.
* Return the HE capabilities, if present.
*
* \return HE capabilities
* \return HE capabilities, if present
*/
const HeCapabilities& GetHeCapabilities (void) const;
const std::optional<HeCapabilities>& GetHeCapabilities (void) const;
/**
* Return the EHT capabilities.
*
@@ -430,7 +430,7 @@ private:
ExtendedCapabilities m_extendedCapability; //!< Extended capabilities
std::optional<HtCapabilities> m_htCapability; //!< HT capabilities
std::optional<VhtCapabilities> m_vhtCapability; //!< VHT capabilities
HeCapabilities m_heCapability; //!< HE capabilities
std::optional<HeCapabilities> m_heCapability; //!< HE capabilities
uint16_t m_listenInterval; //!< listen interval
EhtCapabilities m_ehtCapability; //!< EHT capabilities
Ptr<MultiLinkElement> m_multiLinkElement; //!< Multi-Link Element
@@ -496,11 +496,11 @@ public:
*/
const VhtOperation& GetVhtOperation (void) const;
/**
* Return the HE capabilities.
* Return the HE capabilities, if present.
*
* \return HE capabilities
* \return HE capabilities, if present
*/
const HeCapabilities& GetHeCapabilities (void) const;
const std::optional<HeCapabilities>& GetHeCapabilities (void) const;
/**
* Return the HE operation.
*
@@ -720,7 +720,7 @@ private:
VhtOperation m_vhtOperation; //!< VHT operation
ErpInformation m_erpInformation; //!< ERP information
EdcaParameterSet m_edcaParameterSet; //!< EDCA Parameter Set
HeCapabilities m_heCapability; //!< HE capabilities
std::optional<HeCapabilities> m_heCapability; //!< HE capabilities
HeOperation m_heOperation; //!< HE operation
MuEdcaParameterSet m_muEdcaParameterSet; //!< MU EDCA Parameter Set
EhtCapabilities m_ehtCapability; //!< EHT capabilities
@@ -843,11 +843,11 @@ public:
const std::optional<VhtCapabilities>& GetVhtCapabilities (void) const;
/**
* Return the HE capabilities.
* Return the HE capabilities, if present.
*
* \return HE capabilities
* \return HE capabilities, if present
*/
const HeCapabilities& GetHeCapabilities (void) const;
const std::optional<HeCapabilities>& GetHeCapabilities (void) const;
/**
* Return the EHT capabilities.
@@ -874,7 +874,7 @@ private:
ExtendedCapabilities m_extendedCapability; //!< extended capabilities
std::optional<HtCapabilities> m_htCapability; //!< HT capabilities
std::optional<VhtCapabilities> m_vhtCapability; //!< VHT capabilities
HeCapabilities m_heCapability; //!< HE capabilities
std::optional<HeCapabilities> m_heCapability; //!< HE capabilities
EhtCapabilities m_ehtCapability; //!< EHT capabilities
};
@@ -950,11 +950,11 @@ public:
*/
const VhtOperation& GetVhtOperation (void) const;
/**
* Return the HE capabilities.
* Return the HE capabilities, if present.
*
* \return HE capabilities
* \return HE capabilities, if present
*/
const HeCapabilities& GetHeCapabilities (void) const;
const std::optional<HeCapabilities>& GetHeCapabilities (void) const;
/**
* Return the HE operation.
*
@@ -1200,7 +1200,7 @@ private:
HtOperation m_htOperation; //!< HT operation
std::optional<VhtCapabilities> m_vhtCapability; //!< VHT capabilities
VhtOperation m_vhtOperation; //!< VHT operation
HeCapabilities m_heCapability; //!< HE capabilities
std::optional<HeCapabilities> m_heCapability; //!< HE capabilities
HeOperation m_heOperation; //!< HE operation
ErpInformation m_erpInformation; //!< ERP information
EdcaParameterSet m_edcaParameterSet; //!< EDCA Parameter Set

View File

@@ -1149,14 +1149,14 @@ StaWifiMac::UpdateApInfo (const MgtFrameType& frame, const Mac48Address& apAddr,
if (!GetHeSupported ()) return;
/* HE station */
const HeCapabilities& heCapabilities = frame.GetHeCapabilities ();
if (heCapabilities.GetSupportedMcsAndNss () != 0)
const auto& heCapabilities = frame.GetHeCapabilities ();
if (heCapabilities.has_value () && heCapabilities->GetSupportedMcsAndNss () != 0)
{
GetWifiRemoteStationManager (linkId)->AddStationHeCapabilities (apAddr, heCapabilities);
GetWifiRemoteStationManager (linkId)->AddStationHeCapabilities (apAddr, *heCapabilities);
HeOperation heOperation = frame.GetHeOperation ();
for (const auto & mcs : GetWifiPhy (linkId)->GetMcsList (WIFI_MOD_CLASS_HE))
{
if (heCapabilities.IsSupportedRxMcs (mcs.GetMcsValue ()))
if (heCapabilities->IsSupportedRxMcs (mcs.GetMcsValue ()))
{
GetWifiRemoteStationManager (linkId)->AddSupportedMcs (apAddr, mcs);
}

View File

@@ -1464,54 +1464,53 @@ HeCapabilities
WifiMac::GetHeCapabilities (void) const
{
NS_LOG_FUNCTION (this);
NS_ASSERT (GetHeSupported ());
HeCapabilities capabilities;
if (GetHeSupported ())
Ptr<WifiPhy> phy = GetLink (SINGLE_LINK_OP_ID).phy;
Ptr<HtConfiguration> htConfiguration = GetHtConfiguration ();
Ptr<HeConfiguration> heConfiguration = GetHeConfiguration ();
uint8_t channelWidthSet = 0;
if ((phy->GetChannelWidth () >= 40) && (phy->GetPhyBand () == WIFI_PHY_BAND_2_4GHZ))
{
Ptr<WifiPhy> phy = GetLink (SINGLE_LINK_OP_ID).phy;
Ptr<HtConfiguration> htConfiguration = GetHtConfiguration ();
Ptr<HeConfiguration> heConfiguration = GetHeConfiguration ();
capabilities.SetHeSupported (1);
uint8_t channelWidthSet = 0;
if ((phy->GetChannelWidth () >= 40) && (phy->GetPhyBand () == WIFI_PHY_BAND_2_4GHZ))
{
channelWidthSet |= 0x01;
}
if ((phy->GetChannelWidth () >= 80) && ((phy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand () == WIFI_PHY_BAND_6GHZ)))
{
channelWidthSet |= 0x02;
}
if ((phy->GetChannelWidth () >= 160) && ((phy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand () == WIFI_PHY_BAND_6GHZ)))
{
channelWidthSet |= 0x04;
}
capabilities.SetChannelWidthSet (channelWidthSet);
capabilities.SetLdpcCodingInPayload (htConfiguration->GetLdpcSupported ());
if (heConfiguration->GetGuardInterval () == NanoSeconds (800))
{
//todo: We assume for now that if we support 800ns GI then 1600ns GI is supported as well
//todo: Assuming reception support for both 1x HE LTF and 4x HE LTF 800 ns
capabilities.SetHeSuPpdu1xHeLtf800nsGi (true);
capabilities.SetHePpdu4xHeLtf800nsGi (true);
}
uint32_t maxAmpduLength = std::max ({m_voMaxAmpduSize, m_viMaxAmpduSize,
m_beMaxAmpduSize, m_bkMaxAmpduSize});
// round to the next power of two minus one
maxAmpduLength = (1ul << static_cast<uint32_t> (std::ceil (std::log2 (maxAmpduLength + 1)))) - 1;
// The maximum A-MPDU length in HE capabilities elements ranges from 2^20-1 to 2^23-1
capabilities.SetMaxAmpduLength (std::min (std::max (maxAmpduLength, 1048575u), 8388607u));
uint8_t maxMcs = 0;
for (const auto & mcs : phy->GetMcsList (WIFI_MOD_CLASS_HE))
{
if (mcs.GetMcsValue () > maxMcs)
{
maxMcs = mcs.GetMcsValue ();
}
}
capabilities.SetHighestMcsSupported (maxMcs);
capabilities.SetHighestNssSupported (phy->GetMaxSupportedTxSpatialStreams ());
channelWidthSet |= 0x01;
}
if ((phy->GetChannelWidth () >= 80) && ((phy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand () == WIFI_PHY_BAND_6GHZ)))
{
channelWidthSet |= 0x02;
}
if ((phy->GetChannelWidth () >= 160) && ((phy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand () == WIFI_PHY_BAND_6GHZ)))
{
channelWidthSet |= 0x04;
}
capabilities.SetChannelWidthSet (channelWidthSet);
capabilities.SetLdpcCodingInPayload (htConfiguration->GetLdpcSupported ());
if (heConfiguration->GetGuardInterval () == NanoSeconds (800))
{
//todo: We assume for now that if we support 800ns GI then 1600ns GI is supported as well
//todo: Assuming reception support for both 1x HE LTF and 4x HE LTF 800 ns
capabilities.SetHeSuPpdu1xHeLtf800nsGi (true);
capabilities.SetHePpdu4xHeLtf800nsGi (true);
}
uint32_t maxAmpduLength = std::max ({m_voMaxAmpduSize, m_viMaxAmpduSize,
m_beMaxAmpduSize, m_bkMaxAmpduSize});
// round to the next power of two minus one
maxAmpduLength = (1ul << static_cast<uint32_t> (std::ceil (std::log2 (maxAmpduLength + 1)))) - 1;
// The maximum A-MPDU length in HE capabilities elements ranges from 2^20-1 to 2^23-1
capabilities.SetMaxAmpduLength (std::min (std::max (maxAmpduLength, 1048575u), 8388607u));
uint8_t maxMcs = 0;
for (const auto & mcs : phy->GetMcsList (WIFI_MOD_CLASS_HE))
{
if (mcs.GetMcsValue () > maxMcs)
{
maxMcs = mcs.GetMcsValue ();
}
}
capabilities.SetHighestMcsSupported (maxMcs);
capabilities.SetHighestNssSupported (phy->GetMaxSupportedTxSpatialStreams ());
return capabilities;
}