20 #ifndef WIFI_MGT_HEADER_H
21 #define WIFI_MGT_HEADER_H
26 #include "ns3/eht-capabilities.h"
27 #include "ns3/header.h"
28 #include "ns3/multi-link-element.h"
56 typedef std::optional<T>
type;
64 typedef std::optional<T>
type;
72 typedef std::vector<T>
type;
87 template <
typename Derived,
typename Tuple>
105 template <
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>...>;
225 template <
typename Derived,
typename Tuple>
237 template <
typename Derived,
typename... Elems>
247 uint32_t GetSerializedSizeInPerStaProfile(
const Derived& frame)
const;
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);
332 template <
typename Derived,
typename... Elems>
333 template <
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);
340 template <
typename Derived,
typename... Elems>
341 template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 0,
int>>
342 const std::optional<T>&
345 return std::get<std::optional<T>>(m_elements);
348 template <
typename Derived,
typename... Elems>
349 template <
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);
356 template <
typename Derived,
typename... Elems>
357 template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 1,
int>>
358 const std::vector<T>&
361 return std::get<std::vector<T>>(m_elements);
364 template <
typename Derived,
typename... Elems>
365 template <
typename IE>
372 template <
typename Derived,
typename... Elems>
375 std::optional<EhtCapabilities>& optElem)
382 auto& heCapabilities = Get<HeCapabilities>();
385 optElem.emplace(is2_4Ghz, heCapabilities.value());
393 template <
typename Derived,
typename... Elems>
396 std::optional<MultiLinkElement>& optElem)
398 optElem.emplace(*
static_cast<const Derived*
>(
this));
409 template <
typename T>
413 return elem.has_value() ? elem->GetSerializedSize() : 0;
421 template <
typename T>
425 return std::accumulate(elems.cbegin(), elems.cend(), 0, [](uint16_t a,
const auto& b) {
426 return b.GetSerializedSize() + a;
432 template <
typename Derived,
typename... Elems>
436 return static_cast<const Derived*
>(
this)->GetSerializedSizeImpl();
439 template <
typename Derived,
typename... Elems>
456 template <
typename T>
460 return elem.has_value() ? elem->Serialize(
start) :
start;
469 template <
typename T>
473 return std::accumulate(elems.cbegin(),
481 template <
typename Derived,
typename... Elems>
485 static_cast<const Derived*
>(
this)->SerializeImpl(
start);
488 template <
typename Derived,
typename... Elems>
496 template <
typename Derived,
typename... Elems>
497 template <
typename T>
503 static_cast<Derived*
>(
this)->InitForDeserialization(elem);
504 i = elem->DeserializeIfPresent(i);
505 if (i.GetDistanceFrom(
start) == 0)
512 template <
typename Derived,
typename... Elems>
513 template <
typename T>
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));
534 template <
typename Derived,
typename... Elems>
538 return static_cast<Derived*
>(
this)->DeserializeImpl(
start);
541 template <
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);
580 template <
typename T>
582 DoPrint(
const std::optional<T>& elem, std::ostream& os)
584 if (elem.has_value())
586 os << *elem <<
" , ";
595 template <
typename T>
597 DoPrint(
const std::vector<T>& elems, std::ostream& os)
599 std::copy(elems.cbegin(), elems.cend(), std::ostream_iterator<T>(os,
" , "));
604 template <
typename Derived,
typename... Elems>
608 static_cast<const Derived*
>(
this)->PrintImpl(os);
611 template <
typename Derived,
typename... Elems>
615 std::apply([&](
auto&... elems) { ((
internal::DoPrint(elems, os)), ...); }, m_elements);
629 template <
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())
664 template <
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())
700 template <
typename T,
typename Derived>
701 std::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()}};
721 template <
typename T,
typename Derived>
722 std::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()}};
735 template <
typename Derived,
typename... Elems>
740 return static_cast<const Derived*
>(
this)->GetSerializedSizeInPerStaProfileImpl(frame);
743 template <
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();
779 template <
typename Derived,
typename... Elems>
785 static_cast<const Derived*
>(
this)->SerializeInPerStaProfileImpl(
start, frame);
788 template <
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);
837 template <
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();
858 template <
typename T,
typename Derived>
862 if (
auto& outsideIe = frame.template Get<T>();
863 CanBeInPerStaProfileV<T> && !outsideIe.empty() && elems.empty())
871 template <
typename Derived,
typename... Elems>
878 return static_cast<Derived*
>(
this)->DeserializeFromPerStaProfileImpl(
start, length, frame);
881 template <
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
927 template <
typename T>
931 if (elem.has_value() && nonInheritance.
IsPresent(elem->ElementId(), elem->ElementIdExt()))
945 template <
typename T>
950 nonInheritance.
IsPresent(elem.front().ElementId(), elem.front().ElementIdExt()))
958 template <
typename Derived,
typename... Elems>
970 if (m_nonInheritance)
973 [&](
auto&... elems) {
980 template <
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)
typename std::enable_if< B, T >::type enable_if_t
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