9#ifndef WIFI_MGT_HEADER_H
10#define WIFI_MGT_HEADER_H
15#include "ns3/eht-capabilities.h"
16#include "ns3/header.h"
17#include "ns3/multi-link-element.h"
45 typedef std::optional<T>
type;
53 typedef std::optional<T>
type;
61 typedef std::vector<T>
type;
76template <
typename Derived,
typename Tuple>
94template <
typename Derived,
typename... Elems>
104 template <
typename T,
105 std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 0,
int> = 0>
106 std::optional<T>& Get();
114 template <
typename T,
115 std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 0,
int> = 0>
116 const std::optional<T>& Get()
const;
124 template <
typename T,
125 std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 1,
int> = 0>
126 std::vector<T>& Get();
134 template <
typename T,
135 std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 1,
int> = 0>
136 const std::vector<T>& Get()
const;
138 void Print(std::ostream& os)
const final;
139 uint32_t GetSerializedSize()
const final;
150 template <
typename IE>
151 void InitForDeserialization(std::optional<IE>& optElem);
157 void InitForDeserialization(std::optional<EhtCapabilities>& optElem);
160 void PrintImpl(std::ostream& os)
const;
162 uint32_t GetSerializedSizeImpl()
const;
174 template <
typename T>
183 template <
typename T>
187 using Elements = std::tuple<internal::GetStoredIeT<Elems>...>;
214template <
typename Derived,
typename Tuple>
226template <
typename Derived,
typename... Elems>
266 void CopyIesFromContainingFrame(
const Derived& frame);
276 uint32_t GetSerializedSizeInPerStaProfileImpl(
const Derived& frame)
const;
301 void SetMleContainingFrame()
const;
307 void InitForDeserialization(std::optional<MultiLinkElement>& optElem);
321template <
typename Derived,
typename... Elems>
322template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 0,
int>>
326 return std::get<std::optional<T>>(m_elements);
329template <
typename Derived,
typename... Elems>
330template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 0,
int>>
331const std::optional<T>&
334 return std::get<std::optional<T>>(m_elements);
337template <
typename Derived,
typename... Elems>
338template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 1,
int>>
342 return std::get<std::vector<T>>(m_elements);
345template <
typename Derived,
typename... Elems>
346template <
typename T, std::enable_if_t<(std::is_same_v<std::vector<T>, Elems> + ...) == 1,
int>>
350 return std::get<std::vector<T>>(m_elements);
353template <
typename Derived,
typename... Elems>
354template <
typename IE>
361template <
typename Derived,
typename... Elems>
364 std::optional<EhtCapabilities>& optElem)
371 auto& heCapabilities = Get<HeCapabilities>();
374 optElem.emplace(is2_4Ghz, heCapabilities.value());
382template <
typename Derived,
typename... Elems>
385 std::optional<MultiLinkElement>& optElem)
387 optElem.emplace(*
static_cast<const Derived*
>(
this));
402 return elem.has_value() ? elem->GetSerializedSize() : 0;
414 return std::accumulate(elems.cbegin(), elems.cend(), 0, [](uint16_t a,
const auto& b) {
415 return b.GetSerializedSize() + a;
421template <
typename Derived,
typename... Elems>
425 return static_cast<const Derived*
>(
this)->GetSerializedSizeImpl();
428template <
typename Derived,
typename... Elems>
449 return elem.has_value() ? elem->Serialize(start) : start;
462 return std::accumulate(elems.cbegin(),
470template <
typename Derived,
typename... Elems>
474 static_cast<const Derived*
>(
this)->SerializeImpl(start);
477template <
typename Derived,
typename... Elems>
485template <
typename Derived,
typename... Elems>
492 static_cast<Derived*
>(
this)->InitForDeserialization(elem);
493 i = elem->DeserializeIfPresent(i);
494 if (i.GetDistanceFrom(start) == 0)
501template <
typename Derived,
typename... Elems>
511 std::optional<T> item;
512 static_cast<Derived*
>(
this)->InitForDeserialization(item);
513 i = item->DeserializeIfPresent(i);
514 if (i.GetDistanceFrom(tmp) == 0)
518 elems.push_back(std::move(*item));
523template <
typename Derived,
typename... Elems>
527 return static_cast<Derived*
>(
this)->DeserializeImpl(start);
530template <
typename Derived,
typename... Elems>
542 if constexpr (std::is_same_v<std::remove_reference_t<
decltype(elems)>, Elems>)
545 i = DoDeserialize(elems, i);
550 static_cast<Derived*
>(
this)->InitForDeserialization(elems);
551 i = elems->Deserialize(i);
558 return i.GetDistanceFrom(start);
571DoPrint(
const std::optional<T>& elem, std::ostream& os)
573 if (elem.has_value())
575 os << *elem <<
" , ";
586DoPrint(
const std::vector<T>& elems, std::ostream& os)
588 std::copy(elems.cbegin(), elems.cend(), std::ostream_iterator<T>(os,
" , "));
593template <
typename Derived,
typename... Elems>
597 static_cast<const Derived*
>(
this)->PrintImpl(os);
600template <
typename Derived,
typename... Elems>
604 std::apply([&](
auto&... elems) { ((
internal::DoPrint(elems, os)), ...); }, m_elements);
618template <
typename T,
typename Derived>
627 if (
auto& outsideIe = frame.template Get<T>();
628 outsideIe.has_value() && elem.has_value() && !(outsideIe.value() == elem.value()))
635 if (!frame.template Get<T>().has_value() && elem.has_value())
653template <
typename T,
typename Derived>
662 if (
auto& outsideIe = frame.template Get<T>();
663 !outsideIe.empty() && !elems.empty() && !(outsideIe == elems))
670 if (frame.template Get<T>().empty() && !elems.empty())
689template <
typename T,
typename Derived>
690std::optional<std::pair<uint8_t, uint8_t>>
693 if (
auto& outsideIe = frame.template Get<T>();
696 return {{outsideIe->ElementId(), outsideIe->ElementIdExt()}};
710template <
typename T,
typename Derived>
711std::optional<std::pair<uint8_t, uint8_t>>
714 if (
auto& outsideIe = frame.template Get<T>();
717 return {{outsideIe.front().ElementId(), outsideIe.front().ElementIdExt()}};
724template <
typename Derived,
typename... Elems>
729 return static_cast<const Derived*
>(
this)->GetSerializedSizeInPerStaProfileImpl(frame);
732template <
typename Derived,
typename... Elems>
738 std::optional<NonInheritance> nonInheritance;
741 [&](
auto&... elems) {
752 nonInheritance.emplace();
754 nonInheritance->Add(idPair->first, idPair->second);
763 size += nonInheritance->GetSerializedSize();
768template <
typename Derived,
typename... Elems>
774 static_cast<const Derived*
>(
this)->SerializeInPerStaProfileImpl(start, frame);
777template <
typename Derived,
typename... Elems>
784 std::optional<NonInheritance> nonInheritance;
787 [&](
auto&... elems) {
798 nonInheritance.emplace();
800 nonInheritance->Add(idPair->first, idPair->second);
809 nonInheritance->Serialize(i);
826template <
typename T,
typename Derived>
830 if (
auto& outsideIe = frame.template Get<T>();
833 elem = outsideIe.value();
847template <
typename T,
typename Derived>
851 if (
auto& outsideIe = frame.template Get<T>();
860template <
typename Derived,
typename... Elems>
867 return static_cast<Derived*
>(
this)->DeserializeFromPerStaProfileImpl(start, length, frame);
870template <
typename Derived,
typename... Elems>
881 [&](
auto&... elems) {
884 if (i.GetDistanceFrom(start) < length)
886 i = static_cast<Derived*>(this)->DoDeserialize(elems, i);
887 internal::DoCopyIeFromContainingFrame(elems, frame);
895 m_nonInheritance.reset();
896 i = DoDeserialize(m_nonInheritance, i);
898 auto distance = i.GetDistanceFrom(start);
900 "Bytes read (" << distance <<
") not matching expected number (" << length
920 if (elem.has_value() && nonInheritance.
IsPresent(elem->ElementId(), elem->ElementIdExt()))
939 nonInheritance.
IsPresent(elem.front().ElementId(), elem.front().ElementIdExt()))
947template <
typename Derived,
typename... Elems>
959 if (m_nonInheritance)
962 [&](
auto&... elems) {
969template <
typename Derived,
typename... Elems>
975 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)
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)
typename GetStoredIe< T >::type GetStoredIeT
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