22#include "ns3/address-utils.h"
23#include "ns3/mgt-headers.h"
84 start.WriteHtolsbU16(val);
92 start.WriteHtolsbU16(val);
101 uint8_t length = i.
ReadU8();
105 if ((presence & 0x0001) != 0)
110 if ((presence & 0x0002) != 0)
115 if ((presence & 0x0004) != 0)
124 if ((presence & 0x0008) != 0)
136 if ((presence & 0x0010) != 0)
149 "Common Info Length (" << +length
151 "from actual number of bytes read ("
166 for (uint8_t i = 1; i <= 4; i++)
168 if (1 << (i + 4) == delayUs)
199 for (uint8_t i = 1; i <= 5; i++)
201 if (1 << (i + 3) == delayUs)
226 : m_containingFrame(frame),
227 m_commonInfo(
std::in_place_type<
std::monostate>)
287 std::get<BASIC_VARIANT>(
m_commonInfo).m_mldMacAddress = address;
293 return std::get<BASIC_VARIANT>(
m_commonInfo).m_mldMacAddress;
299 std::get<BASIC_VARIANT>(
m_commonInfo).m_linkIdInfo = (linkIdInfo & 0x0f);
305 return std::get<BASIC_VARIANT>(
m_commonInfo).m_linkIdInfo.has_value();
311 return std::get<BASIC_VARIANT>(
m_commonInfo).m_linkIdInfo.value();
317 std::get<BASIC_VARIANT>(
m_commonInfo).m_bssParamsChangeCount = count;
323 return std::get<BASIC_VARIANT>(
m_commonInfo).m_bssParamsChangeCount.has_value();
329 return std::get<BASIC_VARIANT>(
m_commonInfo).m_bssParamsChangeCount.value();
336 NS_ABORT_MSG_IF(delayUs % 32 != 0,
"Delay must be a multiple of 32 microseconds");
339 auto& mediumSyncDelayInfo = std::get<BASIC_VARIANT>(
m_commonInfo).m_mediumSyncDelayInfo;
340 if (!mediumSyncDelayInfo.has_value())
351 (std::get<BASIC_VARIANT>(
m_commonInfo).m_mediumSyncDelayInfo.value().mediumSyncDuration) *
358 NS_ABORT_MSG_IF(threshold < -72 || threshold > -62,
"Threshold may range from -72 to -62 dBm");
359 uint8_t value = 72 + threshold;
361 auto& mediumSyncDelayInfo = std::get<BASIC_VARIANT>(
m_commonInfo).m_mediumSyncDelayInfo;
362 if (!mediumSyncDelayInfo.has_value())
373 .m_mediumSyncDelayInfo.value()
374 .mediumSyncOfdmEdThreshold) -
384 auto& mediumSyncDelayInfo = std::get<BASIC_VARIANT>(
m_commonInfo).m_mediumSyncDelayInfo;
385 if (!mediumSyncDelayInfo.has_value())
396 .m_mediumSyncDelayInfo.value()
397 .mediumSyncMaxNTxops) +
404 return std::get<BASIC_VARIANT>(
m_commonInfo).m_mediumSyncDelayInfo.has_value();
410 auto& emlCapabilities = std::get<BASIC_VARIANT>(
m_commonInfo).m_emlCapabilities;
411 if (!emlCapabilities.has_value())
421 auto& emlCapabilities = std::get<BASIC_VARIANT>(
m_commonInfo).m_emlCapabilities;
422 if (!emlCapabilities.has_value())
432 auto& emlCapabilities = std::get<BASIC_VARIANT>(
m_commonInfo).m_emlCapabilities;
433 if (!emlCapabilities.has_value())
443 auto& emlCapabilities = std::get<BASIC_VARIANT>(
m_commonInfo).m_emlCapabilities;
444 if (!emlCapabilities.has_value())
452 emlCapabilities->transitionTimeout = 0;
457 for (i = 1; i <= 10; i++)
459 if (1 << (i + 6) == timeoutUs)
461 emlCapabilities->transitionTimeout = i;
472 return std::get<BASIC_VARIANT>(
m_commonInfo).m_emlCapabilities.has_value();
478 return std::get<BASIC_VARIANT>(
m_commonInfo).m_emlCapabilities->emlsrSupport;
484 auto& emlCapabilities = std::get<BASIC_VARIANT>(
m_commonInfo).m_emlCapabilities;
492 auto& emlCapabilities = std::get<BASIC_VARIANT>(
m_commonInfo).m_emlCapabilities;
500 auto& emlCapabilities = std::get<BASIC_VARIANT>(
m_commonInfo).m_emlCapabilities;
502 if (emlCapabilities->transitionTimeout == 0)
506 return MicroSeconds(1 << (6 + emlCapabilities->transitionTimeout));
510 : m_variant(variant),
517 : m_variant(perStaProfile.m_variant),
518 m_staControl(perStaProfile.m_staControl),
519 m_staMacAddress(perStaProfile.m_staMacAddress)
522 auto staProfileCopy = [&](
auto&& frame) {
523 using Ptr = std::decay_t<
decltype(frame)>;
524 if constexpr (std::is_same_v<Ptr, std::monostate>)
530 using T = std::decay_t<
decltype(*frame.get())>;
541 if (&perStaProfile ==
this)
551 auto staProfileCopy = [&](
auto&& frame) {
552 using Ptr = std::decay_t<
decltype(frame)>;
553 if constexpr (std::is_same_v<Ptr, std::monostate>)
559 using T = std::decay_t<
decltype(*frame.get())>;
560 m_staProfile = std::make_unique<T>(*frame.get());
571 m_staControl &= 0xfff0;
572 m_staControl |= (linkId & 0x0f);
578 return static_cast<uint8_t
>(m_staControl & 0x000f);
584 m_staControl |= 0x0010;
590 return (m_staControl & 0x0010) != 0;
597 m_staMacAddress = address;
598 m_staControl |= 0x0020;
604 return (m_staControl & 0x0020) != 0;
611 return m_staMacAddress;
616 const std::variant<MgtAssocRequestHeader, MgtReassocRequestHeader>& assoc)
620 m_staProfile = std::make_unique<std::decay_t<
decltype(frame)>>(frame);
627 std::variant<MgtAssocRequestHeader, MgtReassocRequestHeader>&& assoc)
631 using T = std::decay_t<
decltype(frame)>;
632 m_staProfile = std::make_unique<T>(std::forward<T>(frame));
640 return std::holds_alternative<std::unique_ptr<MgtAssocRequestHeader>>(m_staProfile);
646 return std::holds_alternative<std::unique_ptr<MgtReassocRequestHeader>>(m_staProfile);
652 if (HasAssocRequest())
654 return *std::get<std::unique_ptr<MgtAssocRequestHeader>>(m_staProfile);
657 return *std::get<std::unique_ptr<MgtReassocRequestHeader>>(m_staProfile);
663 m_staProfile = std::make_unique<MgtAssocResponseHeader>(assoc);
669 m_staProfile = std::make_unique<MgtAssocResponseHeader>(std::move(assoc));
675 return std::holds_alternative<std::unique_ptr<MgtAssocResponseHeader>>(m_staProfile);
682 return *std::get<std::unique_ptr<MgtAssocResponseHeader>>(m_staProfile);
690 if (HasStaMacAddress())
709 ret += GetStaInfoLength();
711 auto staProfileSize = [&](
auto&& frame) {
712 using T = std::decay_t<
decltype(frame)>;
713 if constexpr (std::is_same_v<T, std::monostate>)
716 "Missing management frame for Per-STA Profile subelement");
721 using U = std::decay_t<
decltype(*frame)>;
724 "Containing frame type and frame type in Per-STA Profile do not match");
725 const auto& containing = std::get<std::reference_wrapper<const U>>(
m_containingFrame);
726 return frame->GetSerializedSizeInPerStaProfile(containing);
729 ret += std::visit(staProfileSize, m_staProfile);
737 start.WriteHtolsbU16(m_staControl);
738 start.WriteU8(GetStaInfoLength());
740 if (HasStaMacAddress())
742 WriteTo(start, m_staMacAddress);
745 auto staProfileSerialize = [&](
auto&& frame) {
746 using T = std::decay_t<
decltype(frame)>;
747 if constexpr (std::is_same_v<T, std::monostate>)
750 "Missing management frame for Per-STA Profile subelement");
755 using U = std::decay_t<
decltype(*frame)>;
758 "Containing frame type and frame type in Per-STA Profile do not match");
759 const auto& containing = std::get<std::reference_wrapper<const U>>(
m_containingFrame);
760 frame->SerializeInPerStaProfile(start, containing);
763 std::visit(staProfileSerialize, m_staProfile);
775 if (HasStaMacAddress())
784 "Bytes read (" << count <<
") exceed expected number (" << length <<
")");
791 auto staProfileDeserialize = [&](
auto&& frame) {
792 using T = std::decay_t<
decltype(frame)>;
793 if constexpr (!std::is_same_v<T, std::monostate>)
795 using U = std::decay_t<
decltype(frame.get())>;
797 count += assoc.DeserializeFromPerStaProfile(i, length - count, frame.get());
798 m_staProfile = std::make_unique<U>(std::move(assoc));
839 [](
auto&& arg) -> uint8_t {
840 using T = std::decay_t<
decltype(arg)>;
841 if constexpr (std::is_same_v<T, std::monostate>)
848 return arg.GetSize();
856 ret += subelement.GetSerializedSize();
867 [
this, &start](
auto&& arg) {
868 using T = std::decay_t<
decltype(arg)>;
869 if constexpr (std::is_same_v<T, std::monostate>)
876 static_cast<uint8_t
>(
GetVariant()) + (arg.GetPresenceBitmap() << 4);
877 start.WriteHtolsbU16(mlControl);
878 arg.Serialize(start);
885 start = subelement.Serialize(start);
899 uint16_t presence = mlControl >> 4;
901 uint8_t nBytes = std::visit(
902 [&i, &presence](
auto&& arg) -> uint8_t {
903 using T = std::decay_t<
decltype(arg)>;
904 if constexpr (std::is_same_v<T, std::monostate>)
911 return arg.Deserialize(i, presence);
918 while (count < length)
926 i = perStaProfile.Deserialize(i);
iterator in a Buffer instance
uint32_t GetDistanceFrom(const Iterator &o) const
void Next()
go forward by one byte
Per-STA Profile Subelement of Multi-Link element.
PerStaProfileSubelement(Variant variant)
Constructor.
Variant m_variant
Multi-Link element variant.
MgtAssocResponseHeader & GetAssocResponse() const
Get the (Re)Association Response frame body included in the STA Profile field of this Per-STA Profile...
AssocReqRefVariant GetAssocRequest() const
Get the (Re)Association Request frame body included in the STA Profile field of this Per-STA Profile ...
bool HasReassocRequest() const
Return true if a Reassociation Request frame body is included in the STA Profile field of this Per-ST...
Mac48Address GetStaMacAddress() const
Get the STA MAC Address subfield in the STA Info field, if present.
bool HasStaMacAddress() const
Return true if the STA MAC Address subfield in the STA Info field is present.
void SetAssocResponse(const MgtAssocResponseHeader &assoc)
Include the given (Re)Association Response frame body in the STA Profile field of this Per-STA Profil...
PerStaProfileSubelement & operator=(const PerStaProfileSubelement &perStaProfile)
Copy assignment operator performing a deep copy of the object.
uint16_t DeserializeInformationField(Buffer::Iterator start, uint16_t length) override
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets)
uint8_t GetStaInfoLength() const
Get the size in bytes of the serialized STA Info Length subfield of the STA Info field.
WifiInformationElementId ElementId() const override
Get the wifi information element ID.
void SerializeInformationField(Buffer::Iterator start) const override
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
void SetStaMacAddress(Mac48Address address)
Set the STA MAC Address subfield in the STA Info field.
Mac48Address m_staMacAddress
STA MAC address.
void SetCompleteProfile()
Set the Complete Profile flag in the STA Control field.
void SetAssocRequest(const std::variant< MgtAssocRequestHeader, MgtReassocRequestHeader > &assoc)
Include the given (Re)Association Request frame body in the STA Profile field of this Per-STA Profile...
std::variant< std::monostate, std::unique_ptr< MgtAssocRequestHeader >, std::unique_ptr< MgtReassocRequestHeader >, std::unique_ptr< MgtAssocResponseHeader > > m_staProfile
STA Profile field, containing the frame body of a frame of the same type as the frame containing the ...
uint16_t GetInformationFieldSize() const override
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
bool IsCompleteProfileSet() const
void SetLinkId(uint8_t linkId)
Set the Link ID subfield in the STA Control field.
bool HasAssocRequest() const
Return true if an Association Request frame body is included in the STA Profile field of this Per-STA...
uint16_t m_staControl
STA Control field.
uint8_t GetLinkId() const
Get the Link ID subfield in the STA Control field.
bool HasAssocResponse() const
Return true if a (Re)Association Response frame body is included in the STA Profile field of this Per...
ContainingFrame m_containingFrame
reference to the mgt frame containing this MLE
uint16_t DeserializeInformationField(Buffer::Iterator start, uint16_t length) override
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets)
uint16_t GetInformationFieldSize() const override
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
bool HasBssParamsChangeCount() const
Return true if the BSS Parameters Change Count subfield in the Common Info field is present and false...
void AddPerStaProfileSubelement()
Add a Per-STA Profile Subelement in the Link Info field.
void SetEmlsrSupported(bool supported)
Set the EMLSR Support subfield of the EML Capabilities subfield in the Common Info field to 1 if EMLS...
void SetMediumSyncMaxNTxops(uint8_t nTxops)
Set the Medium Synchronization Maximum Number of TXOPs subfield of the Medium Synchronization Delay i...
bool HasMediumSyncDelayInfo() const
Return true if the Medium Synchronization Delay Information subfield in the Common Info field is pres...
Time GetTransitionTimeout() const
Get the Transition Timeout subfield of the EML Capabilities subfield in the Common Info field.
void SetBssParamsChangeCount(uint8_t count)
Set the BSS Parameters Change Count subfield in the Common Info field.
uint8_t GetBssParamsChangeCount() const
Return the BSS Parameters Change Count subfield in the Common Info field.
void SerializeInformationField(Buffer::Iterator start) const override
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
void SetLinkIdInfo(uint8_t linkIdInfo)
Set the Link ID Info subfield in the Common Info field.
void SetVariant(Variant variant)
Set the variant of this Multi-Link Element.
Time GetEmlsrTransitionDelay() const
Get the EMLSR Transition Delay subfield of the EML Capabilities subfield in the Common Info field.
std::vector< PerStaProfileSubelement > m_perStaProfileSubelements
Per-STA Profile Subelements.
CommonInfoBasicMle & GetCommonInfoBasic()
void SetEmlsrTransitionDelay(Time delay)
Set the EMLSR Transition Delay subfield of the EML Capabilities subfield in the Common Info field.
Time GetMediumSyncDelayTimer() const
Get the Medium Synchronization Duration subfield of the Medium Synchronization Delay information in t...
void SetMediumSyncDelayTimer(Time delay)
Set the Medium Synchronization Duration subfield of the Medium Synchronization Delay information in t...
PerStaProfileSubelement & GetPerStaProfile(std::size_t i)
Get a reference to the i-th Per-STA Profile Subelement in the Link Info field.
Variant GetVariant() const
Get the Multi-Link element variant.
Time GetEmlsrPaddingDelay() const
Get the EMLSR Padding Delay subfield of the EML Capabilities subfield in the Common Info field.
void SetEmlsrPaddingDelay(Time delay)
Set the EMLSR Padding Delay subfield of the EML Capabilities subfield in the Common Info field.
CommonInfo m_commonInfo
Common Info field.
bool HasLinkIdInfo() const
Return true if the Link ID Info subfield in the Common Info field is present and false otherwise.
Mac48Address GetMldMacAddress() const
Return the MLD MAC Address subfield in the Common Info field.
bool HasEmlCapabilities() const
Return true if the EML Capabilities subfield in the Common Info field is present and false otherwise.
bool IsEmlsrSupported() const
Return true if the EMLSR Support subfield of the EML Capabilities subfield in the Common Info field i...
void SetMediumSyncOfdmEdThreshold(int8_t threshold)
Set the Medium Synchronization OFDM ED Threshold subfield of the Medium Synchronization Delay informa...
void SetMldMacAddress(Mac48Address address)
Set the MLD MAC Address subfield in the Common Info field.
MultiLinkElement(ContainingFrame frame={})
Construct a Multi-Link Element with no variant set.
WifiInformationElementId ElementIdExt() const override
Get the wifi information element ID extension.
WifiInformationElementId ElementId() const override
Get the wifi information element ID.
uint8_t GetMediumSyncMaxNTxops() const
Get the maximum number of TXOPs a non-AP STA is allowed to attempt to initiate while the MediumSyncDe...
void SetTransitionTimeout(Time timeout)
Set the Transition Timeout subfield of the EML Capabilities subfield in the Common Info field.
std::variant< std::monostate, std::reference_wrapper< const MgtAssocRequestHeader >, std::reference_wrapper< const MgtReassocRequestHeader >, std::reference_wrapper< const MgtAssocResponseHeader > > ContainingFrame
Typedef for structure holding a reference to the containing frame.
std::size_t GetNPerStaProfileSubelements() const
Return the number of Per-STA Profile Subelement in the Link Info field.
uint8_t GetLinkIdInfo() const
Return the Link ID Info subfield in the Common Info field.
int8_t GetMediumSyncOfdmEdThreshold() const
Get the Medium Synchronization OFDM ED Threshold in dBm.
Smart pointer class similar to boost::intrusive_ptr.
Simulation virtual time values and global simulation resolution.
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_ABORT_UNLESS(cond)
Abnormal program termination if a condition is false.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Variant
Multi-Link element variants.
SubElementId
SubElement IDs.
@ PER_STA_PROFILE_SUBELEMENT_ID
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::variant< std::reference_wrapper< MgtAssocRequestHeader >, std::reference_wrapper< MgtReassocRequestHeader > > AssocReqRefVariant
variant holding a reference to a (Re)Association Request
void WriteTo(Buffer::Iterator &i, Ipv4Address ad)
Write an Ipv4Address to a Buffer.
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
void ReadFrom(Buffer::Iterator &i, Ipv4Address &ad)
Read an Ipv4Address from a Buffer.
EML Capabilities subfield.
uint8_t emlsrSupport
EMLSR Support.
uint8_t emlsrPaddingDelay
EMLSR Padding Delay.
uint8_t emlsrTransitionDelay
EMLSR Transition Delay.
Medium Synchronization Delay Information subfield.
uint8_t mediumSyncOfdmEdThreshold
Medium Synchronization OFDM ED Threshold.
uint8_t mediumSyncDuration
Medium Synchronization Duration.
uint8_t mediumSyncMaxNTxops
Medium Synchronization MAximum Number of TXOPs.
MLD Capabilities subfield.
Common Info field of the Basic Multi-Link element.
uint16_t GetPresenceBitmap() const
Get the Presence Bitmap subfield of the Common Info field.
uint8_t GetSize() const
Get the size of the serialized Common Info field.
static uint8_t EncodeEmlsrTransitionDelay(Time delay)
static Time DecodeEmlsrTransitionDelay(uint8_t value)
std::optional< EmlCapabilities > m_emlCapabilities
EML Capabilities.
uint8_t Deserialize(Buffer::Iterator start, uint16_t presence)
Deserialize the Common Info field.
std::optional< MldCapabilities > m_mldCapabilities
MLD Capabilities.
static Time DecodeEmlsrPaddingDelay(uint8_t value)
void Serialize(Buffer::Iterator &start) const
Serialize the Common Info field.
std::optional< MediumSyncDelayInfo > m_mediumSyncDelayInfo
Medium Synchronization Delay Information.
Mac48Address m_mldMacAddress
Subfields.
std::optional< uint8_t > m_bssParamsChangeCount
BSS Parameters Change Count.
std::optional< uint8_t > m_linkIdInfo
Link ID Info.
static uint8_t EncodeEmlsrPaddingDelay(Time delay)