wifi: Fix format of Per-STA Profile subelements

This commit is contained in:
Stefano Avallone
2023-04-17 14:59:00 +02:00
committed by Stefano Avallone
parent 0b28dfa6af
commit 18743af8d0
6 changed files with 362 additions and 65 deletions

View File

@@ -728,11 +728,18 @@ MultiLinkElement::PerStaProfileSubelement::GetInformationFieldSize() const
using T = std::decay_t<decltype(frame)>;
if constexpr (std::is_same_v<T, std::monostate>)
{
NS_ASSERT_MSG(std::holds_alternative<std::monostate>(m_containingFrame),
"Missing management frame for Per-STA Profile subelement");
return static_cast<uint32_t>(0);
}
else
{
return frame->GetSerializedSize();
using U = std::decay_t<decltype(*frame)>;
NS_ASSERT_MSG(
std::holds_alternative<std::reference_wrapper<const U>>(m_containingFrame),
"Containing frame type and frame type in Per-STA Profile do not match");
const auto& containing = std::get<std::reference_wrapper<const U>>(m_containingFrame);
return frame->GetSerializedSizeInPerStaProfile(containing);
}
};
ret += std::visit(staProfileSize, m_staProfile);
@@ -755,11 +762,18 @@ MultiLinkElement::PerStaProfileSubelement::SerializeInformationField(Buffer::Ite
using T = std::decay_t<decltype(frame)>;
if constexpr (std::is_same_v<T, std::monostate>)
{
NS_ASSERT_MSG(std::holds_alternative<std::monostate>(m_containingFrame),
"Missing management frame for Per-STA Profile subelement");
return;
}
else
{
frame->Serialize(start);
using U = std::decay_t<decltype(*frame)>;
NS_ASSERT_MSG(
std::holds_alternative<std::reference_wrapper<const U>>(m_containingFrame),
"Containing frame type and frame type in Per-STA Profile do not match");
const auto& containing = std::get<std::reference_wrapper<const U>>(m_containingFrame);
frame->SerializeInPerStaProfile(start, containing);
}
};
std::visit(staProfileSerialize, m_staProfile);
@@ -770,46 +784,37 @@ MultiLinkElement::PerStaProfileSubelement::DeserializeInformationField(Buffer::I
uint16_t length)
{
Buffer::Iterator i = start;
uint16_t count = 0;
m_staControl = i.ReadLsbtohU16();
count += 2;
i.ReadU8(); // STA Info Length
count++;
if (HasStaMacAddress())
{
ReadFrom(i, m_staMacAddress);
count += 6;
}
// TODO add other subfields of the STA Info field
uint16_t count = i.GetDistanceFrom(start);
if (count >= length)
NS_ASSERT_MSG(count <= length,
"Bytes read (" << count << ") exceed expected number (" << length << ")");
if (count == length)
{
return count;
}
if (m_frameType == WIFI_MAC_MGT_ASSOCIATION_REQUEST)
{
MgtAssocRequestHeader assoc;
count += assoc.Deserialize(i);
SetAssocRequest(std::move(assoc));
}
else if (m_frameType == WIFI_MAC_MGT_REASSOCIATION_REQUEST)
{
MgtReassocRequestHeader reassoc;
count += reassoc.Deserialize(i);
SetAssocRequest(std::move(reassoc));
}
else if (m_frameType == WIFI_MAC_MGT_ASSOCIATION_RESPONSE ||
m_frameType == WIFI_MAC_MGT_REASSOCIATION_RESPONSE)
{
MgtAssocResponseHeader assoc;
count += assoc.Deserialize(i);
SetAssocResponse(assoc);
}
auto staProfileDeserialize = [&](auto&& frame) {
using T = std::decay_t<decltype(frame)>;
if constexpr (!std::is_same_v<T, std::monostate>)
{
using U = std::decay_t<decltype(frame.get())>;
U assoc;
count += assoc.DeserializeFromPerStaProfile(i, length - count, frame.get());
m_staProfile = std::make_unique<U>(std::move(assoc));
}
};
std::visit(staProfileDeserialize, m_containingFrame);
return count;
}
@@ -864,6 +869,7 @@ MultiLinkElement::GetInformationFieldSize() const
for (const auto& subelement : m_perStaProfileSubelements)
{
subelement.m_containingFrame = m_containingFrame;
ret += subelement.GetSerializedSize();
}
@@ -930,11 +936,14 @@ MultiLinkElement::DeserializeInformationField(Buffer::Iterator start, uint16_t l
{
switch (static_cast<SubElementId>(i.PeekU8()))
{
case PER_STA_PROFILE_SUBELEMENT_ID:
case PER_STA_PROFILE_SUBELEMENT_ID: {
AddPerStaProfileSubelement();
i = GetPerStaProfile(GetNPerStaProfileSubelements() - 1).Deserialize(i);
auto& perStaProfile = GetPerStaProfile(GetNPerStaProfileSubelements() - 1);
perStaProfile.m_containingFrame = m_containingFrame;
i = perStaProfile.Deserialize(i);
count = i.GetDistanceFrom(start);
break;
}
break;
default:
NS_ABORT_MSG("Unsupported Subelement ID: " << +i.PeekU8());
}

View File

@@ -561,6 +561,9 @@ class MultiLinkElement : public WifiInformationElement
*/
uint8_t GetStaInfoLength() const;
mutable ContainingFrame
m_containingFrame; //!< the mgt frame containing this Per-STA Profile
private:
uint16_t GetInformationFieldSize() const override;
void SerializeInformationField(Buffer::Iterator start) const override;

View File

@@ -210,10 +210,7 @@ MgtAssocRequestHeader::Capabilities()
uint32_t
MgtAssocRequestHeader::GetSerializedSizeImpl() const
{
if (auto& mle = Get<MultiLinkElement>())
{
mle->m_containingFrame = *this;
}
SetMleContainingFrame();
uint32_t size = 0;
size += m_capability.GetSerializedSize();
@@ -222,13 +219,22 @@ MgtAssocRequestHeader::GetSerializedSizeImpl() const
return size;
}
uint32_t
MgtAssocRequestHeader::GetSerializedSizeInPerStaProfileImpl(
const MgtAssocRequestHeader& frame) const
{
uint32_t size = 0;
size += m_capability.GetSerializedSize();
size +=
MgtHeaderInPerStaProfile<MgtAssocRequestHeader,
AssocRequestElems>::GetSerializedSizeInPerStaProfileImpl(frame);
return size;
}
void
MgtAssocRequestHeader::SerializeImpl(Buffer::Iterator start) const
{
if (auto& mle = Get<MultiLinkElement>())
{
mle->m_containingFrame = *this;
}
SetMleContainingFrame();
Buffer::Iterator i = start;
i = m_capability.Serialize(i);
@@ -236,20 +242,62 @@ MgtAssocRequestHeader::SerializeImpl(Buffer::Iterator start) const
WifiMgtHeader<MgtAssocRequestHeader, AssocRequestElems>::SerializeImpl(i);
}
void
MgtAssocRequestHeader::SerializeInPerStaProfileImpl(Buffer::Iterator start,
const MgtAssocRequestHeader& frame) const
{
Buffer::Iterator i = start;
i = m_capability.Serialize(i);
MgtHeaderInPerStaProfile<MgtAssocRequestHeader,
AssocRequestElems>::SerializeInPerStaProfileImpl(i, frame);
}
uint32_t
MgtAssocRequestHeader::DeserializeImpl(Buffer::Iterator start)
{
Buffer::Iterator i = start;
i = m_capability.Deserialize(i);
m_listenInterval = i.ReadLsbtohU16();
auto distance = i.GetDistanceFrom(start) +
WifiMgtHeader<MgtAssocRequestHeader, AssocRequestElems>::DeserializeImpl(i);
if (auto& mle = Get<MultiLinkElement>())
{
for (std::size_t id = 0; id < mle->GetNPerStaProfileSubelements(); id++)
{
auto& perStaProfile = mle->GetPerStaProfile(id);
if (perStaProfile.HasAssocRequest())
{
auto& frameInPerStaProfile =
std::get<std::reference_wrapper<MgtAssocRequestHeader>>(
perStaProfile.GetAssocRequest())
.get();
frameInPerStaProfile.CopyIesFromContainingFrame(*this);
}
}
}
return distance;
}
uint32_t
MgtAssocRequestHeader::DeserializeFromPerStaProfileImpl(Buffer::Iterator start,
uint16_t length,
const MgtAssocRequestHeader& frame)
{
Buffer::Iterator i = start;
i = m_capability.Deserialize(i);
m_listenInterval = frame.m_listenInterval;
auto distance = i.GetDistanceFrom(start);
return distance + WifiMgtHeader<MgtAssocRequestHeader, AssocRequestElems>::DeserializeImpl(i);
NS_ASSERT_MSG(distance <= length,
"Bytes read (" << distance << ") exceed expected number (" << length << ")");
return distance + MgtHeaderInPerStaProfile<MgtAssocRequestHeader, AssocRequestElems>::
DeserializeFromPerStaProfileImpl(i, length - distance, frame);
}
void
MgtAssocRequestHeader::InitForDeserialization(std::optional<MultiLinkElement>& optElem)
{
optElem.emplace(WIFI_MAC_MGT_ASSOCIATION_REQUEST);
optElem->m_containingFrame = *this;
}
/***********************************************************
@@ -307,10 +355,7 @@ MgtReassocRequestHeader::SetCurrentApAddress(Mac48Address currentApAddr)
uint32_t
MgtReassocRequestHeader::GetSerializedSizeImpl() const
{
if (auto& mle = Get<MultiLinkElement>())
{
mle->m_containingFrame = *this;
}
SetMleContainingFrame();
uint32_t size = 0;
size += m_capability.GetSerializedSize();
@@ -320,6 +365,18 @@ MgtReassocRequestHeader::GetSerializedSizeImpl() const
return size;
}
uint32_t
MgtReassocRequestHeader::GetSerializedSizeInPerStaProfileImpl(
const MgtReassocRequestHeader& frame) const
{
uint32_t size = 0;
size += m_capability.GetSerializedSize();
size +=
MgtHeaderInPerStaProfile<MgtReassocRequestHeader,
AssocRequestElems>::GetSerializedSizeInPerStaProfileImpl(frame);
return size;
}
void
MgtReassocRequestHeader::PrintImpl(std::ostream& os) const
{
@@ -330,10 +387,7 @@ MgtReassocRequestHeader::PrintImpl(std::ostream& os) const
void
MgtReassocRequestHeader::SerializeImpl(Buffer::Iterator start) const
{
if (auto& mle = Get<MultiLinkElement>())
{
mle->m_containingFrame = *this;
}
SetMleContainingFrame();
Buffer::Iterator i = start;
i = m_capability.Serialize(i);
@@ -342,6 +396,16 @@ MgtReassocRequestHeader::SerializeImpl(Buffer::Iterator start) const
WifiMgtHeader<MgtReassocRequestHeader, AssocRequestElems>::SerializeImpl(i);
}
void
MgtReassocRequestHeader::SerializeInPerStaProfileImpl(Buffer::Iterator start,
const MgtReassocRequestHeader& frame) const
{
Buffer::Iterator i = start;
i = m_capability.Serialize(i);
MgtHeaderInPerStaProfile<MgtReassocRequestHeader,
AssocRequestElems>::SerializeInPerStaProfileImpl(i, frame);
}
uint32_t
MgtReassocRequestHeader::DeserializeImpl(Buffer::Iterator start)
{
@@ -349,14 +413,47 @@ MgtReassocRequestHeader::DeserializeImpl(Buffer::Iterator start)
i = m_capability.Deserialize(i);
m_listenInterval = i.ReadLsbtohU16();
ReadFrom(i, m_currentApAddr);
auto distance = i.GetDistanceFrom(start) +
WifiMgtHeader<MgtReassocRequestHeader, AssocRequestElems>::DeserializeImpl(i);
if (auto& mle = Get<MultiLinkElement>())
{
for (std::size_t id = 0; id < mle->GetNPerStaProfileSubelements(); id++)
{
auto& perStaProfile = mle->GetPerStaProfile(id);
if (perStaProfile.HasReassocRequest())
{
auto& frameInPerStaProfile =
std::get<std::reference_wrapper<MgtReassocRequestHeader>>(
perStaProfile.GetAssocRequest())
.get();
frameInPerStaProfile.CopyIesFromContainingFrame(*this);
}
}
}
return distance;
}
uint32_t
MgtReassocRequestHeader::DeserializeFromPerStaProfileImpl(Buffer::Iterator start,
uint16_t length,
const MgtReassocRequestHeader& frame)
{
Buffer::Iterator i = start;
i = m_capability.Deserialize(i);
m_listenInterval = frame.m_listenInterval;
m_currentApAddr = frame.m_currentApAddr;
auto distance = i.GetDistanceFrom(start);
return distance + WifiMgtHeader<MgtReassocRequestHeader, AssocRequestElems>::DeserializeImpl(i);
NS_ASSERT_MSG(distance <= length,
"Bytes read (" << distance << ") exceed expected number (" << length << ")");
return distance + MgtHeaderInPerStaProfile<MgtReassocRequestHeader, AssocRequestElems>::
DeserializeFromPerStaProfileImpl(i, length - distance, frame);
}
void
MgtReassocRequestHeader::InitForDeserialization(std::optional<MultiLinkElement>& optElem)
{
optElem.emplace(WIFI_MAC_MGT_REASSOCIATION_REQUEST);
optElem->m_containingFrame = *this;
}
/***********************************************************
@@ -420,10 +517,7 @@ MgtAssocResponseHeader::GetAssociationId() const
uint32_t
MgtAssocResponseHeader::GetSerializedSizeImpl() const
{
if (auto& mle = Get<MultiLinkElement>())
{
mle->m_containingFrame = *this;
}
SetMleContainingFrame();
uint32_t size = 0;
size += m_capability.GetSerializedSize();
@@ -433,6 +527,19 @@ MgtAssocResponseHeader::GetSerializedSizeImpl() const
return size;
}
uint32_t
MgtAssocResponseHeader::GetSerializedSizeInPerStaProfileImpl(
const MgtAssocResponseHeader& frame) const
{
uint32_t size = 0;
size += m_capability.GetSerializedSize();
size += m_code.GetSerializedSize();
size +=
MgtHeaderInPerStaProfile<MgtAssocResponseHeader,
AssocResponseElems>::GetSerializedSizeInPerStaProfileImpl(frame);
return size;
}
void
MgtAssocResponseHeader::PrintImpl(std::ostream& os) const
{
@@ -444,10 +551,7 @@ MgtAssocResponseHeader::PrintImpl(std::ostream& os) const
void
MgtAssocResponseHeader::SerializeImpl(Buffer::Iterator start) const
{
if (auto& mle = Get<MultiLinkElement>())
{
mle->m_containingFrame = *this;
}
SetMleContainingFrame();
Buffer::Iterator i = start;
i = m_capability.Serialize(i);
@@ -456,6 +560,17 @@ MgtAssocResponseHeader::SerializeImpl(Buffer::Iterator start) const
WifiMgtHeader<MgtAssocResponseHeader, AssocResponseElems>::SerializeImpl(i);
}
void
MgtAssocResponseHeader::SerializeInPerStaProfileImpl(Buffer::Iterator start,
const MgtAssocResponseHeader& frame) const
{
Buffer::Iterator i = start;
i = m_capability.Serialize(i);
i = m_code.Serialize(i);
MgtHeaderInPerStaProfile<MgtAssocResponseHeader,
AssocResponseElems>::SerializeInPerStaProfileImpl(i, frame);
}
uint32_t
MgtAssocResponseHeader::DeserializeImpl(Buffer::Iterator start)
{
@@ -463,14 +578,44 @@ MgtAssocResponseHeader::DeserializeImpl(Buffer::Iterator start)
i = m_capability.Deserialize(i);
i = m_code.Deserialize(i);
m_aid = i.ReadLsbtohU16();
auto distance = i.GetDistanceFrom(start) +
WifiMgtHeader<MgtAssocResponseHeader, AssocResponseElems>::DeserializeImpl(i);
if (auto& mle = Get<MultiLinkElement>())
{
for (std::size_t id = 0; id < mle->GetNPerStaProfileSubelements(); id++)
{
auto& perStaProfile = mle->GetPerStaProfile(id);
if (perStaProfile.HasAssocResponse())
{
auto& frameInPerStaProfile = perStaProfile.GetAssocResponse();
frameInPerStaProfile.CopyIesFromContainingFrame(*this);
}
}
}
return distance;
}
uint32_t
MgtAssocResponseHeader::DeserializeFromPerStaProfileImpl(Buffer::Iterator start,
uint16_t length,
const MgtAssocResponseHeader& frame)
{
Buffer::Iterator i = start;
i = m_capability.Deserialize(i);
i = m_code.Deserialize(i);
m_aid = frame.m_aid;
auto distance = i.GetDistanceFrom(start);
return distance + WifiMgtHeader<MgtAssocResponseHeader, AssocResponseElems>::DeserializeImpl(i);
NS_ASSERT_MSG(distance <= length,
"Bytes read (" << distance << ") exceed expected number (" << length << ")");
return distance + MgtHeaderInPerStaProfile<MgtAssocResponseHeader, AssocResponseElems>::
DeserializeFromPerStaProfileImpl(i, length - distance, frame);
}
void
MgtAssocResponseHeader::InitForDeserialization(std::optional<MultiLinkElement>& optElem)
{
optElem.emplace(WIFI_MAC_MGT_ASSOCIATION_RESPONSE);
optElem->m_containingFrame = *this;
}
/**********************************************************

View File

@@ -42,12 +42,52 @@
#include "ns3/mac48-address.h"
#include "ns3/mu-edca-parameter-set.h"
#include "ns3/multi-link-element.h"
#include "ns3/tid-to-link-mapping-element.h"
#include "ns3/vht-capabilities.h"
#include "ns3/vht-operation.h"
namespace ns3
{
/**
* Indicate which Information Elements cannot be included in a Per-STA Profile subelement of
* a Basic Multi-Link Element (see Sec. 35.3.3.4 of 802.11be D3.1):
*
* An AP affiliated with an AP MLD shall not include a Timestamp field, a Beacon Interval field,
* an AID field, a BSS Max Idle Period element, a Neighbor Report element, a Reduced Neighbor
* Report element, a Multiple BSSID element, TIM element, Multiple BSSID-Index element, Multiple
* BSSID Configuration element, TID-to-Link Mapping element, Multi-Link Traffic Indication element
* or another Multi- Link element in the STA Profile field of the Basic Multi-Link element.
*
* A non-AP STA affiliated with a non-AP MLD shall not include a Listen Interval field, a Current
* AP Address field, an SSID element, BSS Max Idle Period element or another Multi-Link element in
* the STA Profile field of the Basic Multi-Link element.
*/
/** \copydoc CanBeInPerStaProfile */
template <>
struct CanBeInPerStaProfile<ReducedNeighborReport> : std::false_type
{
};
/** \copydoc CanBeInPerStaProfile */
template <>
struct CanBeInPerStaProfile<TidToLinkMapping> : std::false_type
{
};
/** \copydoc CanBeInPerStaProfile */
template <>
struct CanBeInPerStaProfile<MultiLinkElement> : std::false_type
{
};
/** \copydoc CanBeInPerStaProfile */
template <>
struct CanBeInPerStaProfile<Ssid> : std::false_type
{
};
/// List of Information Elements included in Probe Request frames
using ProbeRequestElems = std::tuple<Ssid,
SupportedRates,
@@ -109,9 +149,11 @@ using AssocResponseElems = std::tuple<SupportedRates,
* \ingroup wifi
* Implement the header for management frames of type association request.
*/
class MgtAssocRequestHeader : public WifiMgtHeader<MgtAssocRequestHeader, AssocRequestElems>
class MgtAssocRequestHeader
: public MgtHeaderInPerStaProfile<MgtAssocRequestHeader, AssocRequestElems>
{
friend class WifiMgtHeader<MgtAssocRequestHeader, AssocRequestElems>;
friend class MgtHeaderInPerStaProfile<MgtAssocRequestHeader, AssocRequestElems>;
public:
~MgtAssocRequestHeader() override = default;
@@ -154,6 +196,34 @@ class MgtAssocRequestHeader : public WifiMgtHeader<MgtAssocRequestHeader, AssocR
/** \copydoc Header::Deserialize */
uint32_t DeserializeImpl(Buffer::Iterator start);
/**
* \param frame the frame containing the Multi-Link Element
* \return the number of bytes that are needed to serialize this header into a Per-STA Profile
* subelement of the Multi-Link Element
*/
uint32_t GetSerializedSizeInPerStaProfileImpl(const MgtAssocRequestHeader& frame) const;
/**
* Serialize this header into a Per-STA Profile subelement of a Multi-Link Element
*
* \param start an iterator which points to where the header should be written
* \param frame the frame containing the Multi-Link Element
*/
void SerializeInPerStaProfileImpl(Buffer::Iterator start,
const MgtAssocRequestHeader& frame) const;
/**
* Deserialize this header from a Per-STA Profile subelement of a Multi-Link Element.
*
* \param start an iterator which points to where the header should be read from
* \param length the expected number of bytes to read
* \param frame the frame containing the Multi-Link Element
* \return the number of bytes read
*/
uint32_t DeserializeFromPerStaProfileImpl(Buffer::Iterator start,
uint16_t length,
const MgtAssocRequestHeader& frame);
private:
using WifiMgtHeader<MgtAssocRequestHeader, AssocRequestElems>::InitForDeserialization;
@@ -171,9 +241,11 @@ class MgtAssocRequestHeader : public WifiMgtHeader<MgtAssocRequestHeader, AssocR
* \ingroup wifi
* Implement the header for management frames of type reassociation request.
*/
class MgtReassocRequestHeader : public WifiMgtHeader<MgtReassocRequestHeader, AssocRequestElems>
class MgtReassocRequestHeader
: public MgtHeaderInPerStaProfile<MgtReassocRequestHeader, AssocRequestElems>
{
friend class WifiMgtHeader<MgtReassocRequestHeader, AssocRequestElems>;
friend class MgtHeaderInPerStaProfile<MgtReassocRequestHeader, AssocRequestElems>;
public:
~MgtReassocRequestHeader() override = default;
@@ -224,6 +296,34 @@ class MgtReassocRequestHeader : public WifiMgtHeader<MgtReassocRequestHeader, As
/** \copydoc Header::Print */
void PrintImpl(std::ostream& os) const;
/**
* \param frame the frame containing the Multi-Link Element
* \return the number of bytes that are needed to serialize this header into a Per-STA Profile
* subelement of the Multi-Link Element
*/
uint32_t GetSerializedSizeInPerStaProfileImpl(const MgtReassocRequestHeader& frame) const;
/**
* Serialize this header into a Per-STA Profile subelement of a Multi-Link Element
*
* \param start an iterator which points to where the header should be written
* \param frame the frame containing the Multi-Link Element
*/
void SerializeInPerStaProfileImpl(Buffer::Iterator start,
const MgtReassocRequestHeader& frame) const;
/**
* Deserialize this header from a Per-STA Profile subelement of a Multi-Link Element.
*
* \param start an iterator which points to where the header should be read from
* \param length the expected number of bytes to read
* \param frame the frame containing the Multi-Link Element
* \return the number of bytes read
*/
uint32_t DeserializeFromPerStaProfileImpl(Buffer::Iterator start,
uint16_t length,
const MgtReassocRequestHeader& frame);
private:
using WifiMgtHeader<MgtReassocRequestHeader, AssocRequestElems>::InitForDeserialization;
@@ -242,9 +342,11 @@ class MgtReassocRequestHeader : public WifiMgtHeader<MgtReassocRequestHeader, As
* \ingroup wifi
* Implement the header for management frames of type association and reassociation response.
*/
class MgtAssocResponseHeader : public WifiMgtHeader<MgtAssocResponseHeader, AssocResponseElems>
class MgtAssocResponseHeader
: public MgtHeaderInPerStaProfile<MgtAssocResponseHeader, AssocResponseElems>
{
friend class WifiMgtHeader<MgtAssocResponseHeader, AssocResponseElems>;
friend class MgtHeaderInPerStaProfile<MgtAssocResponseHeader, AssocResponseElems>;
public:
~MgtAssocResponseHeader() override = default;
@@ -301,6 +403,34 @@ class MgtAssocResponseHeader : public WifiMgtHeader<MgtAssocResponseHeader, Asso
/** \copydoc Header::Print */
void PrintImpl(std::ostream& os) const;
/**
* \param frame the frame containing the Multi-Link Element
* \return the number of bytes that are needed to serialize this header into a Per-STA Profile
* subelement of the Multi-Link Element
*/
uint32_t GetSerializedSizeInPerStaProfileImpl(const MgtAssocResponseHeader& frame) const;
/**
* Serialize this header into a Per-STA Profile subelement of a Multi-Link Element
*
* \param start an iterator which points to where the header should be written
* \param frame the frame containing the Multi-Link Element
*/
void SerializeInPerStaProfileImpl(Buffer::Iterator start,
const MgtAssocResponseHeader& frame) const;
/**
* Deserialize this header from a Per-STA Profile subelement of a Multi-Link Element.
*
* \param start an iterator which points to where the header should be read from
* \param length the expected number of bytes to read
* \param frame the frame containing the Multi-Link Element
* \return the number of bytes read
*/
uint32_t DeserializeFromPerStaProfileImpl(Buffer::Iterator start,
uint16_t length,
const MgtAssocResponseHeader& frame);
private:
using WifiMgtHeader<MgtAssocResponseHeader, AssocResponseElems>::InitForDeserialization;

View File

@@ -62,7 +62,8 @@ class BasicMultiLinkElementTest : public HeaderSerializationTestCase
private:
void DoRun() override;
WifiMacType m_frameType; //!< the type of frame possibly included in the MLE
WifiMacType m_frameType; //!< the type of frame possibly included in the MLE
MgtAssocRequestHeader m_outerAssoc; //!< the frame containing the MLE
};
BasicMultiLinkElementTest::BasicMultiLinkElementTest()
@@ -114,6 +115,12 @@ BasicMultiLinkElementTest::GetMultiLinkElement(
mle.AddPerStaProfileSubelement();
mle.GetPerStaProfile(i) = std::move(subelements[i]);
}
if (!subelements.empty())
{
mle.m_containingFrame = m_outerAssoc;
}
return mle;
}
@@ -177,11 +184,14 @@ BasicMultiLinkElementTest::DoRun()
perStaProfile.SetAssocRequest(assoc);
// Adding Per-STA Profile Subelement
TestHeaderSerialization(GetMultiLinkElement(commonInfo, {perStaProfile}), m_frameType);
TestHeaderSerialization(GetMultiLinkElement(commonInfo, {perStaProfile}),
m_frameType,
m_outerAssoc);
// Adding two Per-STA Profile Subelements
TestHeaderSerialization(GetMultiLinkElement(commonInfo, {perStaProfile, perStaProfile}),
m_frameType);
m_frameType,
m_outerAssoc);
}
/**

View File

@@ -452,7 +452,7 @@ MultiLinkOperationsTestBase::DoSetup()
{
RngSeedManager::SetSeed(1);
RngSeedManager::SetRun(2);
int64_t streamNumber = 100;
int64_t streamNumber = 30;
NodeContainer wifiApNode;
wifiApNode.Create(1);
@@ -1493,7 +1493,7 @@ MultiLinkTxTest::StartTraffic()
client2->SetRemote(socket);
m_sourceMac->GetDevice()->GetNode()->AddApplication(client2);
// start during transmission of first A-MPDU, if multiple links are setup
client2->SetStartTime(MilliSeconds(3));
client2->SetStartTime(MilliSeconds(4));
client2->SetStopTime(duration);
}