wifi: Fix format of Per-STA Profile subelements
This commit is contained in:
committed by
Stefano Avallone
parent
0b28dfa6af
commit
18743af8d0
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user