wifi: Make MU EDCA Parameter Set IE optional in mgt frames

This commit is contained in:
Stefano Avallone
2022-07-12 23:14:17 +02:00
parent 1acc0bcf6a
commit d8a7a4ceff
7 changed files with 105 additions and 146 deletions

View File

@@ -527,58 +527,71 @@ ApWifiMac::GetEdcaParameterSet (uint8_t linkId) const
return edcaParameters;
}
MuEdcaParameterSet
std::optional<MuEdcaParameterSet>
ApWifiMac::GetMuEdcaParameterSet (void) const
{
NS_LOG_FUNCTION (this);
NS_ASSERT (GetHeSupported ());
Ptr<HeConfiguration> heConfiguration = GetHeConfiguration ();
NS_ASSERT (heConfiguration);
MuEdcaParameterSet muEdcaParameters;
if (GetHeSupported ())
muEdcaParameters.SetQosInfo (0);
UintegerValue uintegerValue;
TimeValue timeValue;
heConfiguration->GetAttribute ("MuBeAifsn", uintegerValue);
muEdcaParameters.SetMuAifsn (AC_BE, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuBeCwMin", uintegerValue);
muEdcaParameters.SetMuCwMin (AC_BE, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuBeCwMax", uintegerValue);
muEdcaParameters.SetMuCwMax (AC_BE, uintegerValue.Get ());
heConfiguration->GetAttribute ("BeMuEdcaTimer", timeValue);
muEdcaParameters.SetMuEdcaTimer (AC_BE, timeValue.Get ());
heConfiguration->GetAttribute ("MuBkAifsn", uintegerValue);
muEdcaParameters.SetMuAifsn (AC_BK, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuBkCwMin", uintegerValue);
muEdcaParameters.SetMuCwMin (AC_BK, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuBkCwMax", uintegerValue);
muEdcaParameters.SetMuCwMax (AC_BK, uintegerValue.Get ());
heConfiguration->GetAttribute ("BkMuEdcaTimer", timeValue);
muEdcaParameters.SetMuEdcaTimer (AC_BK, timeValue.Get ());
heConfiguration->GetAttribute ("MuViAifsn", uintegerValue);
muEdcaParameters.SetMuAifsn (AC_VI, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuViCwMin", uintegerValue);
muEdcaParameters.SetMuCwMin (AC_VI, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuViCwMax", uintegerValue);
muEdcaParameters.SetMuCwMax (AC_VI, uintegerValue.Get ());
heConfiguration->GetAttribute ("ViMuEdcaTimer", timeValue);
muEdcaParameters.SetMuEdcaTimer (AC_VI, timeValue.Get ());
heConfiguration->GetAttribute ("MuVoAifsn", uintegerValue);
muEdcaParameters.SetMuAifsn (AC_VO, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuVoCwMin", uintegerValue);
muEdcaParameters.SetMuCwMin (AC_VO, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuVoCwMax", uintegerValue);
muEdcaParameters.SetMuCwMax (AC_VO, uintegerValue.Get ());
heConfiguration->GetAttribute ("VoMuEdcaTimer", timeValue);
muEdcaParameters.SetMuEdcaTimer (AC_VO, timeValue.Get ());
// The timers of the MU EDCA Parameter Set must be either all zero or all
// non-zero. The information element is advertised if all timers are non-zero
auto timerNotNull = [&muEdcaParameters](uint8_t aci)
{ return !muEdcaParameters.GetMuEdcaTimer (aci).IsZero (); };
auto aci = {0, 1, 2, 3};
if (std::all_of (aci.begin (), aci.end (), timerNotNull))
{
Ptr<HeConfiguration> heConfiguration = GetHeConfiguration ();
NS_ASSERT (heConfiguration);
muEdcaParameters.SetQosInfo (0);
UintegerValue uintegerValue;
TimeValue timeValue;
heConfiguration->GetAttribute ("MuBeAifsn", uintegerValue);
muEdcaParameters.SetMuAifsn (AC_BE, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuBeCwMin", uintegerValue);
muEdcaParameters.SetMuCwMin (AC_BE, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuBeCwMax", uintegerValue);
muEdcaParameters.SetMuCwMax (AC_BE, uintegerValue.Get ());
heConfiguration->GetAttribute ("BeMuEdcaTimer", timeValue);
muEdcaParameters.SetMuEdcaTimer (AC_BE, timeValue.Get ());
heConfiguration->GetAttribute ("MuBkAifsn", uintegerValue);
muEdcaParameters.SetMuAifsn (AC_BK, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuBkCwMin", uintegerValue);
muEdcaParameters.SetMuCwMin (AC_BK, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuBkCwMax", uintegerValue);
muEdcaParameters.SetMuCwMax (AC_BK, uintegerValue.Get ());
heConfiguration->GetAttribute ("BkMuEdcaTimer", timeValue);
muEdcaParameters.SetMuEdcaTimer (AC_BK, timeValue.Get ());
heConfiguration->GetAttribute ("MuViAifsn", uintegerValue);
muEdcaParameters.SetMuAifsn (AC_VI, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuViCwMin", uintegerValue);
muEdcaParameters.SetMuCwMin (AC_VI, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuViCwMax", uintegerValue);
muEdcaParameters.SetMuCwMax (AC_VI, uintegerValue.Get ());
heConfiguration->GetAttribute ("ViMuEdcaTimer", timeValue);
muEdcaParameters.SetMuEdcaTimer (AC_VI, timeValue.Get ());
heConfiguration->GetAttribute ("MuVoAifsn", uintegerValue);
muEdcaParameters.SetMuAifsn (AC_VO, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuVoCwMin", uintegerValue);
muEdcaParameters.SetMuCwMin (AC_VO, uintegerValue.Get ());
heConfiguration->GetAttribute ("MuVoCwMax", uintegerValue);
muEdcaParameters.SetMuCwMax (AC_VO, uintegerValue.Get ());
heConfiguration->GetAttribute ("VoMuEdcaTimer", timeValue);
muEdcaParameters.SetMuEdcaTimer (AC_VO, timeValue.Get ());
return muEdcaParameters;
}
return muEdcaParameters;
NS_ABORT_MSG_UNLESS (std::none_of (aci.begin (), aci.end (), timerNotNull),
"MU EDCA Timers must be all zero if the IE is not advertised.");
return std::nullopt;
}
Ptr<ReducedNeighborReport>
@@ -868,7 +881,10 @@ ApWifiMac::SendProbeResp (Mac48Address to, uint8_t linkId)
{
probe.SetHeCapabilities (GetHeCapabilities ());
probe.SetHeOperation (GetHeOperation ());
probe.SetMuEdcaParameterSet (GetMuEdcaParameterSet ());
if (auto muEdcaParameterSet = GetMuEdcaParameterSet (); muEdcaParameterSet.has_value ())
{
probe.SetMuEdcaParameterSet (std::move (*muEdcaParameterSet));
}
}
if (GetEhtSupported ())
{
@@ -993,7 +1009,10 @@ ApWifiMac::GetAssocResp (Mac48Address to, bool isReassoc, uint8_t linkId)
{
assoc.SetHeCapabilities (GetHeCapabilities ());
assoc.SetHeOperation (GetHeOperation ());
assoc.SetMuEdcaParameterSet (GetMuEdcaParameterSet ());
if (auto muEdcaParameterSet = GetMuEdcaParameterSet (); muEdcaParameterSet.has_value ())
{
assoc.SetMuEdcaParameterSet (std::move (*muEdcaParameterSet));
}
}
if (GetEhtSupported ())
{
@@ -1098,7 +1117,10 @@ ApWifiMac::SendOneBeacon (uint8_t linkId)
{
beacon.SetHeCapabilities (GetHeCapabilities ());
beacon.SetHeOperation (GetHeOperation ());
beacon.SetMuEdcaParameterSet (GetMuEdcaParameterSet ());
if (auto muEdcaParameterSet = GetMuEdcaParameterSet (); muEdcaParameterSet.has_value ())
{
beacon.SetMuEdcaParameterSet (std::move (*muEdcaParameterSet));
}
}
if (GetEhtSupported ())
{

View File

@@ -308,11 +308,11 @@ private:
*/
EdcaParameterSet GetEdcaParameterSet (uint8_t linkId) const;
/**
* Return the MU EDCA Parameter Set of the current AP.
* Return the MU EDCA Parameter Set of the current AP, if one needs to be advertised
*
* \return the MU EDCA Parameter Set that we support
* \return the MU EDCA Parameter Set that needs to be advertised (if any)
*/
MuEdcaParameterSet GetMuEdcaParameterSet (void) const;
std::optional<MuEdcaParameterSet> GetMuEdcaParameterSet (void) const;
/**
* Return the Reduced Neighbor Report (RNR) element that the current AP sends
* on the given link

View File

@@ -42,21 +42,6 @@ MuEdcaParameterSet::ElementIdExt () const
return IE_EXT_MU_EDCA_PARAMETER_SET;
}
bool
MuEdcaParameterSet::IsPresent (void) const
{
auto timerNotNull = [](const ParameterRecord &r) { return r.muEdcaTimer != 0; };
bool isPresent = std::all_of (m_records.begin (), m_records.end (), timerNotNull);
if (isPresent)
{
return true;
}
NS_ABORT_MSG_IF (std::any_of (m_records.begin (), m_records.end (), timerNotNull),
"MU EDCA Timers must be either all zero or all non-zero.");
return false;
}
void
MuEdcaParameterSet::SetQosInfo (uint8_t qosInfo)
{
@@ -150,43 +135,19 @@ MuEdcaParameterSet::GetMuEdcaTimer (uint8_t aci) const
uint8_t
MuEdcaParameterSet::GetInformationFieldSize () const
{
NS_ASSERT (IsPresent ());
// ElementIdExt (1) + QoS Info (1) + MU Parameter Records (4 * 3)
return 14;
}
Buffer::Iterator
MuEdcaParameterSet::Serialize (Buffer::Iterator i) const
{
if (!IsPresent ())
{
return i;
}
return WifiInformationElement::Serialize (i);
}
uint16_t
MuEdcaParameterSet::GetSerializedSize () const
{
if (!IsPresent ())
{
return 0;
}
return WifiInformationElement::GetSerializedSize ();
}
void
MuEdcaParameterSet::SerializeInformationField (Buffer::Iterator start) const
{
if (IsPresent ())
start.WriteU8 (GetQosInfo ());
for (const auto& record : m_records)
{
start.WriteU8 (GetQosInfo ());
for (const auto& record : m_records)
{
start.WriteU8 (record.aifsnField);
start.WriteU8 (record.cwMinMax);
start.WriteU8 (record.muEdcaTimer);
}
start.WriteU8 (record.aifsnField);
start.WriteU8 (record.cwMinMax);
start.WriteU8 (record.muEdcaTimer);
}
}

View File

@@ -37,11 +37,6 @@ class MuEdcaParameterSet : public WifiInformationElement
{
public:
MuEdcaParameterSet ();
/**
* Return true if a valid MU EDCA Parameter Set is present in this object
* \return true if a valid MU EDCA Parameter Set is present in this object
*/
bool IsPresent (void) const;
/**
* Set the QoS Info field in the MuEdcaParameterSet information element.
@@ -156,25 +151,6 @@ public:
*/
uint8_t DeserializeInformationField (Buffer::Iterator start, uint8_t length);
/**
* 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.
*
* \param start iterator start
*
* \return an iterator
*/
Buffer::Iterator Serialize (Buffer::Iterator start) const;
/**
* Return the serialized size of this EDCA Parameter Set.
*
* \return the serialized size of this EDCA Parameter Set
*/
uint16_t GetSerializedSize () const;
private:
/**
* MU AC Parameter Record type

View File

@@ -544,7 +544,7 @@ MgtProbeResponseHeader::GetEdcaParameterSet (void) const
return m_edcaParameterSet;
}
const MuEdcaParameterSet&
const std::optional<MuEdcaParameterSet>&
MgtProbeResponseHeader::GetMuEdcaParameterSet (void) const
{
return m_muEdcaParameterSet;
@@ -599,7 +599,7 @@ MgtProbeResponseHeader::GetSerializedSize (void) const
if (m_vhtOperation.has_value ()) size += m_vhtOperation->GetSerializedSize ();
if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize ();
if (m_heOperation.has_value ()) size += m_heOperation->GetSerializedSize ();
size += m_muEdcaParameterSet.GetSerializedSize ();
if (m_muEdcaParameterSet.has_value ()) size += m_muEdcaParameterSet->GetSerializedSize ();
if (m_ehtCapability.has_value ()) size += m_ehtCapability->GetSerializedSize ();
if (m_reducedNeighborReport != nullptr) size += m_reducedNeighborReport->GetSerializedSize ();
if (m_multiLinkElement != nullptr) size += m_multiLinkElement->GetSerializedSize ();
@@ -642,7 +642,7 @@ MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const
if (m_vhtOperation.has_value ()) i = m_vhtOperation->Serialize (i);
if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i);
if (m_heOperation.has_value ()) i = m_heOperation->Serialize (i);
i = m_muEdcaParameterSet.Serialize (i);
if (m_muEdcaParameterSet.has_value ()) i = m_muEdcaParameterSet->Serialize (i);
if (m_ehtCapability.has_value ()) i = m_ehtCapability->Serialize (i);
if (m_reducedNeighborReport != nullptr) i = m_reducedNeighborReport->Serialize (i);
if (m_multiLinkElement != nullptr) i = m_multiLinkElement->Serialize (i);
@@ -669,7 +669,7 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start)
i = WifiInformationElement::DeserializeIfPresent (m_vhtOperation, i);
i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i);
i = WifiInformationElement::DeserializeIfPresent (m_heOperation, i);
i = m_muEdcaParameterSet.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_muEdcaParameterSet, i);
i = WifiInformationElement::DeserializeIfPresent (m_ehtCapability, i);
i = (m_reducedNeighborReport = Create<ReducedNeighborReport> ())->DeserializeIfPresent (tmp = i);
if (i.GetDistanceFrom (tmp) == 0) m_reducedNeighborReport = nullptr;
@@ -1524,7 +1524,7 @@ MgtAssocResponseHeader::GetEdcaParameterSet (void) const
return m_edcaParameterSet;
}
const MuEdcaParameterSet&
const std::optional<MuEdcaParameterSet>&
MgtAssocResponseHeader::GetMuEdcaParameterSet (void) const
{
return m_muEdcaParameterSet;
@@ -1565,7 +1565,7 @@ MgtAssocResponseHeader::GetSerializedSize (void) const
if (m_vhtOperation.has_value ()) size += m_vhtOperation->GetSerializedSize ();
if (m_heCapability.has_value ()) size += m_heCapability->GetSerializedSize ();
if (m_heOperation.has_value ()) size += m_heOperation->GetSerializedSize ();
size += m_muEdcaParameterSet.GetSerializedSize ();
if (m_muEdcaParameterSet.has_value ()) size += m_muEdcaParameterSet->GetSerializedSize ();
if (m_ehtCapability.has_value ()) size += m_ehtCapability->GetSerializedSize ();
if (m_multiLinkElement != nullptr) size += m_multiLinkElement->GetSerializedSize ();
return size;
@@ -1606,7 +1606,7 @@ MgtAssocResponseHeader::Serialize (Buffer::Iterator start) const
if (m_vhtOperation.has_value ()) i = m_vhtOperation->Serialize (i);
if (m_heCapability.has_value ()) i = m_heCapability->Serialize (i);
if (m_heOperation.has_value ()) i = m_heOperation->Serialize (i);
i = m_muEdcaParameterSet.Serialize (i);
if (m_muEdcaParameterSet.has_value ()) i = m_muEdcaParameterSet->Serialize (i);
if (m_ehtCapability.has_value ()) i = m_ehtCapability->Serialize (i);
if (m_multiLinkElement != nullptr) i = m_multiLinkElement->Serialize (i);
}
@@ -1629,7 +1629,7 @@ MgtAssocResponseHeader::Deserialize (Buffer::Iterator start)
i = WifiInformationElement::DeserializeIfPresent (m_vhtOperation, i);
i = WifiInformationElement::DeserializeIfPresent (m_heCapability, i);
i = WifiInformationElement::DeserializeIfPresent (m_heOperation, i);
i = m_muEdcaParameterSet.DeserializeIfPresent (i);
i = WifiInformationElement::DeserializeIfPresent (m_muEdcaParameterSet, i);
i = WifiInformationElement::DeserializeIfPresent (m_ehtCapability, i);
m_multiLinkElement = Create<MultiLinkElement> (WIFI_MAC_MGT_ASSOCIATION_RESPONSE);
i = m_multiLinkElement->DeserializeIfPresent (tmp = i);

View File

@@ -540,11 +540,11 @@ public:
*/
const std::optional<EdcaParameterSet>& GetEdcaParameterSet (void) const;
/**
* Return the MU EDCA Parameter Set.
* Return the MU EDCA Parameter Set, if present.
*
* \return the MU EDCA Parameter Set
* \return the MU EDCA Parameter Set, if present
*/
const MuEdcaParameterSet& GetMuEdcaParameterSet (void) const;
const std::optional<MuEdcaParameterSet>& GetMuEdcaParameterSet (void) const;
/**
* Set the Capability information.
*
@@ -722,7 +722,7 @@ private:
std::optional<EdcaParameterSet> m_edcaParameterSet; //!< EDCA Parameter Set
std::optional<HeCapabilities> m_heCapability; //!< HE capabilities
std::optional<HeOperation> m_heOperation; //!< HE operation
MuEdcaParameterSet m_muEdcaParameterSet; //!< MU EDCA Parameter Set
std::optional<MuEdcaParameterSet> m_muEdcaParameterSet; //!< MU EDCA Parameter Set
std::optional<EhtCapabilities> m_ehtCapability; //!< EHT capabilities
Ptr<MultiLinkElement> m_multiLinkElement; //!< Multi-Link Element
};
@@ -980,11 +980,11 @@ public:
*/
const std::optional<EdcaParameterSet>& GetEdcaParameterSet (void) const;
/**
* Return the MU EDCA Parameter Set.
* Return the MU EDCA Parameter Set, if present.
*
* \return the MU EDCA Parameter Set
* \return the MU EDCA Parameter Set, if present
*/
const MuEdcaParameterSet& GetMuEdcaParameterSet (void) const;
const std::optional<MuEdcaParameterSet>& GetMuEdcaParameterSet (void) const;
/**
* Return the Reduced Neighbor Report information element.
@@ -1204,7 +1204,7 @@ private:
std::optional<HeOperation> m_heOperation; //!< HE operation
std::optional<ErpInformation> m_erpInformation; //!< ERP information
std::optional<EdcaParameterSet> m_edcaParameterSet; //!< EDCA Parameter Set
MuEdcaParameterSet m_muEdcaParameterSet; //!< MU EDCA Parameter Set
std::optional<MuEdcaParameterSet> m_muEdcaParameterSet; //!< MU EDCA Parameter Set
std::optional<EhtCapabilities> m_ehtCapability; //!< EHT capabilities
Ptr<ReducedNeighborReport> m_reducedNeighborReport; //!< Reduced Neighbor Report information
Ptr<MultiLinkElement> m_multiLinkElement; //!< Multi-Link Element

View File

@@ -1166,17 +1166,17 @@ StaWifiMac::UpdateApInfo (const MgtFrameType& frame, const Mac48Address& apAddr,
}
}
const MuEdcaParameterSet& muEdcaParameters = frame.GetMuEdcaParameterSet ();
if (muEdcaParameters.IsPresent ())
const auto& muEdcaParameters = frame.GetMuEdcaParameterSet ();
if (muEdcaParameters.has_value ())
{
SetMuEdcaParameters (AC_BE, muEdcaParameters.GetMuCwMin (AC_BE), muEdcaParameters.GetMuCwMax (AC_BE),
muEdcaParameters.GetMuAifsn (AC_BE), muEdcaParameters.GetMuEdcaTimer (AC_BE));
SetMuEdcaParameters (AC_BK, muEdcaParameters.GetMuCwMin (AC_BK), muEdcaParameters.GetMuCwMax (AC_BK),
muEdcaParameters.GetMuAifsn (AC_BK), muEdcaParameters.GetMuEdcaTimer (AC_BK));
SetMuEdcaParameters (AC_VI, muEdcaParameters.GetMuCwMin (AC_VI), muEdcaParameters.GetMuCwMax (AC_VI),
muEdcaParameters.GetMuAifsn (AC_VI), muEdcaParameters.GetMuEdcaTimer (AC_VI));
SetMuEdcaParameters (AC_VO, muEdcaParameters.GetMuCwMin (AC_VO), muEdcaParameters.GetMuCwMax (AC_VO),
muEdcaParameters.GetMuAifsn (AC_VO), muEdcaParameters.GetMuEdcaTimer (AC_VO));
SetMuEdcaParameters (AC_BE, muEdcaParameters->GetMuCwMin (AC_BE), muEdcaParameters->GetMuCwMax (AC_BE),
muEdcaParameters->GetMuAifsn (AC_BE), muEdcaParameters->GetMuEdcaTimer (AC_BE));
SetMuEdcaParameters (AC_BK, muEdcaParameters->GetMuCwMin (AC_BK), muEdcaParameters->GetMuCwMax (AC_BK),
muEdcaParameters->GetMuAifsn (AC_BK), muEdcaParameters->GetMuEdcaTimer (AC_BK));
SetMuEdcaParameters (AC_VI, muEdcaParameters->GetMuCwMin (AC_VI), muEdcaParameters->GetMuCwMax (AC_VI),
muEdcaParameters->GetMuAifsn (AC_VI), muEdcaParameters->GetMuEdcaTimer (AC_VI));
SetMuEdcaParameters (AC_VO, muEdcaParameters->GetMuCwMin (AC_VO), muEdcaParameters->GetMuCwMax (AC_VO),
muEdcaParameters->GetMuAifsn (AC_VO), muEdcaParameters->GetMuEdcaTimer (AC_VO));
}
if (!GetEhtSupported ()) return;