20#ifndef WIFI_MGT_HEADER_H
21#define WIFI_MGT_HEADER_H
25#include "ns3/eht-capabilities.h"
26#include "ns3/header.h"
27#include "ns3/multi-link-element.h"
28#include "ns3/supported-rates.h"
56 typedef std::optional<T>
type;
64 typedef std::optional<T>
type;
72 typedef std::vector<T>
type;
87template <
typename Derived,
typename Tuple>
105template <
typename Derived,
typename... Elems>
115 template <
typename T,
116 std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 0,
int> = 0>
117 std::optional<T>& Get();
125 template <
typename T,
126 std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 0,
int> = 0>
127 const std::optional<T>& Get()
const;
135 template <
typename T,
136 std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 1,
int> = 0>
137 std::vector<T>& Get();
145 template <
typename T,
146 std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 1,
int> = 0>
147 const std::vector<T>& Get()
const;
149 void Print(std::ostream& os)
const final;
150 uint32_t GetSerializedSize()
const final;
161 template <
typename IE>
162 void InitForDeserialization(std::optional<IE>& optElem);
168 void InitForDeserialization(std::optional<EhtCapabilities>& optElem);
171 void PrintImpl(std::ostream& os)
const;
173 uint32_t GetSerializedSizeImpl()
const;
185 template <
typename T>
194 template <
typename T>
198 using Elements = std::tuple<internal::GetStoredIeT<Elems>...>;
225template <
typename Derived,
typename Tuple>
237template <
typename Derived,
typename... Elems>
277 void CopyIesFromContainingFrame(
const Derived& frame);
287 uint32_t GetSerializedSizeInPerStaProfileImpl(
const Derived& frame)
const;
312 void SetMleContainingFrame()
const;
318 void InitForDeserialization(std::optional<MultiLinkElement>& optElem);
332template <
typename Derived,
typename... Elems>
333template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 0,
int>>
337 return std::get<std::optional<T>>(m_elements);
340template <
typename Derived,
typename... Elems>
341template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 0,
int>>
342const std::optional<T>&
345 return std::get<std::optional<T>>(m_elements);
348template <
typename Derived,
typename... Elems>
349template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 1,
int>>
353 return std::get<std::vector<T>>(m_elements);
356template <
typename Derived,
typename... Elems>
357template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 1,
int>>
361 return std::get<std::vector<T>>(m_elements);
364template <
typename Derived,
typename... Elems>
365template <
typename IE>
372template <
typename Derived,
typename... Elems>
375 std::optional<EhtCapabilities>& optElem)
382 auto& heCapabilities = Get<HeCapabilities>();
385 optElem.emplace(is2_4Ghz, heCapabilities.value());
393template <
typename Derived,
typename... Elems>
396 std::optional<MultiLinkElement>& optElem)
398 optElem.emplace(*
static_cast<const Derived*
>(
this));
413 return elem.has_value() ? elem->GetSerializedSize() : 0;
425 return std::accumulate(elems.cbegin(), elems.cend(), 0, [](uint16_t a,
const auto& b) {
426 return b.GetSerializedSize() + a;
432template <
typename Derived,
typename... Elems>
436 return static_cast<const Derived*
>(
this)->GetSerializedSizeImpl();
439template <
typename Derived,
typename... Elems>
460 return elem.has_value() ? elem->Serialize(start) : start;
473 return std::accumulate(elems.cbegin(),
481template <
typename Derived,
typename... Elems>
485 static_cast<const Derived*
>(
this)->SerializeImpl(start);
488template <
typename Derived,
typename... Elems>
496template <
typename Derived,
typename... Elems>
503 static_cast<Derived*
>(
this)->InitForDeserialization(elem);
504 i = elem->DeserializeIfPresent(i);
505 if (i.GetDistanceFrom(start) == 0)
512template <
typename Derived,
typename... Elems>
522 std::optional<T> item;
523 static_cast<Derived*
>(
this)->InitForDeserialization(item);
524 i = item->DeserializeIfPresent(i);
525 if (i.GetDistanceFrom(tmp) == 0)
529 elems.push_back(std::move(*item));
534template <
typename Derived,
typename... Elems>
538 return static_cast<Derived*
>(
this)->DeserializeImpl(start);
541template <
typename Derived,
typename... Elems>
553 if constexpr (std::is_same_v<std::remove_reference_t<
decltype(elems)>, Elems>)
556 i = DoDeserialize(elems, i);
561 static_cast<Derived*
>(
this)->InitForDeserialization(elems);
562 i = elems->Deserialize(i);
569 return i.GetDistanceFrom(start);
582DoPrint(
const std::optional<T>& elem, std::ostream& os)
584 if (elem.has_value())
586 os << *elem <<
" , ";
597DoPrint(
const std::vector<T>& elems, std::ostream& os)
599 std::copy(elems.cbegin(), elems.cend(), std::ostream_iterator<T>(os,
" , "));
604template <
typename Derived,
typename... Elems>
608 static_cast<const Derived*
>(
this)->PrintImpl(os);
611template <
typename Derived,
typename... Elems>
615 std::apply([&](
auto&... elems) { ((
internal::DoPrint(elems, os)), ...); }, m_elements);
629template <
typename T,
typename Derived>
633 if (!CanBeInPerStaProfileV<T>)
638 if (
auto& outsideIe = frame.template Get<T>();
639 outsideIe.has_value() && elem.has_value() && !(outsideIe.value() == elem.value()))
646 if (!frame.template Get<T>().has_value() && elem.has_value())
664template <
typename T,
typename Derived>
668 if (!CanBeInPerStaProfileV<T>)
673 if (
auto& outsideIe = frame.template Get<T>();
674 !outsideIe.empty() && !elems.empty() && !(outsideIe == elems))
681 if (frame.template Get<T>().empty() && !elems.empty())
700template <
typename T,
typename Derived>
701std::optional<std::pair<uint8_t, uint8_t>>
704 if (
auto& outsideIe = frame.template Get<T>();
705 CanBeInPerStaProfileV<T> && outsideIe.has_value() && !elem.has_value())
707 return {{outsideIe->ElementId(), outsideIe->ElementIdExt()}};
721template <
typename T,
typename Derived>
722std::optional<std::pair<uint8_t, uint8_t>>
725 if (
auto& outsideIe = frame.template Get<T>();
726 CanBeInPerStaProfileV<T> && !outsideIe.empty() && elems.empty())
728 return {{outsideIe.front().ElementId(), outsideIe.front().ElementIdExt()}};
735template <
typename Derived,
typename... Elems>
740 return static_cast<const Derived*
>(
this)->GetSerializedSizeInPerStaProfileImpl(frame);
743template <
typename Derived,
typename... Elems>
749 std::optional<NonInheritance> nonInheritance;
752 [&](
auto&... elems) {
763 nonInheritance.emplace();
765 nonInheritance->Add(idPair->first, idPair->second);
774 size += nonInheritance->GetSerializedSize();
779template <
typename Derived,
typename... Elems>
785 static_cast<const Derived*
>(
this)->SerializeInPerStaProfileImpl(start, frame);
788template <
typename Derived,
typename... Elems>
795 std::optional<NonInheritance> nonInheritance;
798 [&](
auto&... elems) {
809 nonInheritance.emplace();
811 nonInheritance->Add(idPair->first, idPair->second);
820 nonInheritance->Serialize(i);
837template <
typename T,
typename Derived>
841 if (
auto& outsideIe = frame.template Get<T>();
842 CanBeInPerStaProfileV<T> && outsideIe.has_value() && !elem.has_value())
844 elem = outsideIe.value();
858template <
typename T,
typename Derived>
862 if (
auto& outsideIe = frame.template Get<T>();
863 CanBeInPerStaProfileV<T> && !outsideIe.empty() && elems.empty())
871template <
typename Derived,
typename... Elems>
878 return static_cast<Derived*
>(
this)->DeserializeFromPerStaProfileImpl(start, length, frame);
881template <
typename Derived,
typename... Elems>
892 [&](
auto&... elems) {
895 if (i.GetDistanceFrom(start) < length)
897 i = static_cast<Derived*>(this)->DoDeserialize(elems, i);
898 internal::DoCopyIeFromContainingFrame(elems, frame);
906 m_nonInheritance.reset();
907 i = DoDeserialize(m_nonInheritance, i);
909 auto distance = i.GetDistanceFrom(start);
911 "Bytes read (" << distance <<
") not matching expected number (" << length
931 if (elem.has_value() && nonInheritance.
IsPresent(elem->ElementId(), elem->ElementIdExt()))
950 nonInheritance.
IsPresent(elem.front().ElementId(), elem.front().ElementIdExt()))
958template <
typename Derived,
typename... Elems>
970 if (m_nonInheritance)
973 [&](
auto&... elems) {
980template <
typename Derived,
typename... Elems>
986 mle->m_containingFrame = *
static_cast<const Derived*
>(
this);
Simple class derived from ns3::Object, used to check attribute constructors.
iterator in a Buffer instance
The IEEE 802.11 Non-Inheritance Information Element.
bool IsPresent(uint8_t elemId, uint8_t elemIdExt=0) const
#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...
void Print(ComponentCarrier cc)
void DoPrint(const std::optional< T > &elem, std::ostream &os)
bool MustBeSerializedInPerStaProfile(const std::optional< T > &elem, const Derived &frame)
void DoCopyIeFromContainingFrame(std::optional< T > &elem, const Derived &frame)
typename GetStoredIe< T >::type GetStoredIeT
uint16_t DoGetSerializedSize(const std::optional< T > &elem)
std::optional< std::pair< uint8_t, uint8_t > > MustBeListedInNonInheritance(const std::optional< T > &elem, const Derived &frame)
void RemoveIfNotInherited(std::optional< T > &elem, const NonInheritance &nonInheritance)
Buffer::Iterator DoSerialize(const std::optional< T > &elem, Buffer::Iterator start)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
constexpr bool CanBeInPerStaProfileV
Inspect a type to deduce whether it is an Information Element that can be included in a Per-STA Profi...
Struct containing all supported rates.
bool IsSupportedRate(uint64_t bs) const
Check if the given rate is supported.
Inspect a type to deduce whether it is an Information Element that can be included in a Per-STA Profi...
std::optional< T > type
typedef for the resulting optional type
std::vector< T > type
typedef for the resulting optional type
std::optional< T > type
typedef for the resulting optional type