13#include "ns3/boolean.h"
15#include "ns3/wifi-net-device.h"
16#include "ns3/wifi-phy-listener.h"
17#include "ns3/wifi-phy.h"
77 const std::vector<Time>& )
override
112 TypeId(
"ns3::AdvancedEmlsrManager")
114 .SetGroupName(
"Wifi")
116 .AddAttribute(
"AllowUlTxopInRx",
117 "Whether a (main or aux) PHY is allowed to start an UL TXOP if "
118 "another PHY is receiving a PPDU (possibly starting a DL TXOP). "
119 "If this attribute is true, the PPDU may be dropped.",
123 .AddAttribute(
"InterruptSwitch",
124 "Whether the main PHY can be interrupted while switching to start "
125 "switching to another link.",
129 .AddAttribute(
"UseAuxPhyCca",
130 "Whether the CCA performed in the last PIFS interval by a non-TX "
131 "capable aux PHY should be used when the main PHY ends switching to "
132 "the aux PHY's link to determine whether TX can start or not (and what "
133 "bandwidth can be used for transmission) independently of whether the "
134 "aux PHY bandwidth is smaller than the main PHY bandwidth or not.",
138 .AddAttribute(
"SwitchMainPhyBackDelay",
139 "Duration of the timer started in case of non-TX capable aux PHY (that "
140 "does not switch link) when medium is sensed busy during the PIFS "
141 "interval preceding/following the main PHY switch end. When the timer "
142 "expires, the main PHY is switched back to the preferred link.",
146 .AddAttribute(
"KeepMainPhyAfterDlTxop",
147 "In case aux PHYs are not TX capable and do not switch link, after the "
148 "end of a DL TXOP carried out on an aux PHY link, the main PHY stays on "
149 "that link for a switch main PHY back delay, if this attribute is true, "
150 "or it returns to the preferred link, otherwise.",
154 .AddAttribute(
"CheckAccessOnMainPhyLink",
155 "In case aux PHYs are not TX capable and an Access Category, say it AC "
156 "X, is about to gain channel access on an aux PHY link, determine "
157 "whether the time the ACs with priority higher than or equal to AC X and "
158 "with frames to send on the main PHY link are expected to gain access on "
159 "the main PHY link should be taken into account when taking the decision "
160 "to switch the main PHY to the aux PHY link.",
165 "MinAcToSkipCheckAccess",
166 "If the CheckAccessOnMainPhyLink attribute is set to false, indicate the "
167 "minimum priority AC for which it is allowed to skip the check related "
168 "to the expected channel access time on the main PHY link.",
197 for (
auto phy :
GetStaMac()->GetDevice()->GetPhys())
199 phy->TraceDisconnectWithoutContext(
214 for (
const auto& linkId :
GetStaMac()->GetLinkIds())
216 GetStaMac()->GetChannelAccessManager(linkId)->TraceDisconnectWithoutContext(
225 ->GetChannelAccessManager(emlsrLinkId)
226 ->TraceConnectWithoutContext(
239 for (
auto phy :
GetStaMac()->GetDevice()->GetPhys())
241 phy->TraceConnectWithoutContext(
277 for (
const auto id :
GetStaMac()->GetLinkIds())
295 return {
false, delay};
299 auto phy =
GetStaMac()->GetWifiPhy(linkId);
308 return {
false,
Time{0}};
315 return {
true,
Time{0}};
324 auto linkId =
GetStaMac()->GetLinkForPhy(phy);
331 auto& ongoingTxopEnd =
GetEhtFem(*linkId)->GetOngoingTxopEndEvent();
333 if (ongoingTxopEnd.IsPending() && macHdr.
GetAddr1() !=
GetEhtFem(*linkId)->GetAddress() &&
338 ongoingTxopEnd.Cancel();
353 const auto mainPhyInvolved =
362 (reason =
GetStaMac()->GetChannelAccessManager(*linkId)->GetExpectedAccessWithin(
365 SwitchMainPhyBackDelayExpired(*linkId, reason);
398 "Switch main PHY back timer should not be running at the end of a DL TXOP");
400 "Main PHY should not be switching at the end of a DL TXOP");
402 if (
GetStaMac()->GetChannelAccessManager(linkId)->GetExpectedAccessWithin(
405 NS_LOG_DEBUG(
"Keep main PHY on link " << +linkId <<
" to try to gain an UL TXOP");
418 std::shared_ptr<EmlsrMainPhySwitchTrace> traceInfo;
424 traceInfo = std::make_shared<EmlsrCtsAfterRtsTimeoutTrace>(
Time{0});
429 traceInfo = std::make_shared<EmlsrTxopEndedTrace>();
443 "Aux PHY next link ID should have a value when interrupting a main PHY switch");
450 const auto delay = mainPhy->GetDelayUntilIdle();
452 if (
auto info = std::dynamic_pointer_cast<EmlsrCtsAfterRtsTimeoutTrace>(traceInfo))
454 info->sinceCtsTimeout = delay;
460 if (!
GetEhtFem(linkId)->UsingOtherEmlsrLink())
468std::optional<WifiIcfDrop>
492 auto state = mainPhy->GetState()->GetState();
496 "Main PHY cannot be in state " << state);
499 auto switchingTime = mainPhy->GetChannelSwitchDelay();
501 if (switchingTime > timeToCtsEnd)
504 NS_LOG_DEBUG(
"Not enough time for main PHY to switch link (main PHY state: "
505 << mainPhy->GetState()->GetState() <<
")");
507 return {
false, timeToCtsEnd};
514 return {
true,
Time{0}};
520 NS_LOG_FUNCTION(
this << phy->GetPhyId() << linkId << edca->GetAccessCategory());
522 const auto caManager =
GetStaMac()->GetChannelAccessManager(linkId);
523 const auto pifs = phy->GetSifs() + phy->GetSlot();
525 const auto isBusy = caManager->IsBusy();
527 auto width = caManager->GetLargestIdlePrimaryChannel(pifs,
Simulator::Now());
530 auto txopNotStarted = [=,
this]() {
539 (reason =
GetStaMac()->GetChannelAccessManager(linkId)->GetExpectedAccessWithin(
542 NS_LOG_DEBUG(
"No AC is expected to get backoff soon, switch main PHY back");
547 edca->NotifyChannelReleased(linkId);
548 edca->StartAccessAfterEvent(linkId,
555 NS_LOG_DEBUG(
"Main PHY switched back (or scheduled to switch back) before PIFS check");
558 else if (!isBusy && width >
MHz_u{0})
567 if (
GetEhtFem(linkId)->StartTransmission(edca, width))
587 std::optional<WifiExpectedAccessReason> stopReason)
591 std::stringstream ss;
592 if (stopReason.has_value())
594 ss << stopReason.value();
605 for (
const auto id :
GetStaMac()->GetLinkIds())
609 if (!phy || !
GetStaMac()->IsEmlsrLink(
id))
614 if (!
GetEhtFem(
id)->VirtualCsMediumIdle() &&
617 NS_LOG_DEBUG(
"NAV is set and TXOP holder is not the associated AP MLD on link " << +
id);
625 extension =
Max(extension, delay);
627 else if (
id == linkId && phy->IsStateIdle())
632 if (
GetStaMac()->GetChannelAccessManager(linkId)->GetExpectedAccessWithin(
635 extension =
Max(extension, phy->GetChannelSwitchDelay());
640 if (extension.IsStrictlyPositive())
675 std::forward<EmlsrMainPhySwitchTrace>(traceInfo));
691 std::forward<EmlsrMainPhySwitchTrace>(traceInfo));
708 if (!linkId.has_value())
712 NS_LOG_DEBUG(
"Main PHY is switching to link " << +linkId.value());
717 if (
auto reason =
GetStaMac()->GetChannelAccessManager(*linkId)->GetExpectedAccessWithin(delay);
756 NS_LOG_DEBUG(
"Main PHY is not operating on any link and cannot switch to another link");
763 NS_LOG_DEBUG(
"Main PHY is trying to get access on another link");
768 auto minDelay = mainPhy->GetChannelSwitchDelay();
773 const auto pifs =
GetStaMac()->GetWifiPhy(linkId)->GetPifs();
777 "Main PHY has to perform CCA but switch main PHY back delay is less than PIFS");
782 minDelay = std::max(delay, minDelay);
788 NS_LOG_DEBUG(
"No more TXOP attempts allowed on aux PHY link and MSD timer still running");
794 if (
const auto state = mainPhy->GetState()->GetState();
798 NS_LOG_DEBUG(
"Cannot request main PHY to switch when in state " << state);
804 if (!
GetStaMac()->GetQosTxop(aci)->HasFramesToTransmit(linkId))
806 NS_LOG_DEBUG(
"No frames of " << aci <<
" to send on link " << +linkId);
815 NS_LOG_DEBUG(
"Skipping check related to the expected channel access time on main PHY link");
819 const auto mainPhyLinkId =
GetStaMac()->GetLinkForPhy(mainPhy);
820 if (!mainPhyLinkId.has_value())
823 NS_LOG_DEBUG(
"The main PHY is not connected to any link");
845 const auto edca =
GetStaMac()->GetQosTxop(acIndex);
846 const auto backoffEnd =
847 GetStaMac()->GetChannelAccessManager(*mainPhyLinkId)->GetBackoffEndFor(edca);
849 <<
" on main PHY link: " << backoffEnd.As(
Time::US));
851 if ((backoffEnd <= now + minDelay) && edca->HasFramesToTransmit(*mainPhyLinkId))
853 NS_LOG_DEBUG(acIndex <<
" is expected to gain access on link " << +mainPhyLinkId.value()
854 <<
" sooner than " << aci <<
" on link " << +linkId);
868 "This function should only be called if aux PHY is not TX capable");
878 NS_LOG_DEBUG(
"Main PHY is already switching to link " << +linkId);
884 const auto auxPhy =
GetStaMac()->GetWifiPhy(linkId);
885 const auto pifs = auxPhy->GetSifs() + auxPhy->GetSlot();
892 NS_LOG_DEBUG(
"Schedule CCA check at the end of main PHY switch");
903 NS_LOG_DEBUG(
"Schedule CCA check a PIFS after the end of main PHY switch");
914 if (
const auto mainPhyLinkId =
GetStaMac()->GetLinkForPhy(mainPhy))
916 auto mainPhyNavEnd =
GetStaMac()->GetChannelAccessManager(*mainPhyLinkId)->GetNavEnd();
960 std::optional<Time> delay;
967 else if (mainPhy->GetState()->GetLastTime(
968 {WifiPhyState::SWITCHING, WifiPhyState::CCA_BUSY, WifiPhyState::RX}) ==
971 delay = mainPhy->GetDelayUntilIdle();
974 NS_LOG_DEBUG(
"Main PHY state is " << mainPhy->GetState()->GetState());
975 auto edca =
GetStaMac()->GetQosTxop(aci);
976 edca->NotifyChannelReleased(linkId);
978 if (!delay.has_value())
987 edca->StartAccessAfterEvent(linkId,
1002 NS_LOG_DEBUG(
"Nothing to do if aux PHY is TX capable");
1008 NS_LOG_DEBUG(
"Do nothing if delay is not strictly positive");
1012 if (
GetEhtFem(linkId)->UsingOtherEmlsrLink())
1014 NS_LOG_DEBUG(
"Do nothing because another EMLSR link is being used");
1020 NS_LOG_DEBUG(
"Do nothing because a frame is being received on another EMLSR link");
1025 auto phy =
GetStaMac()->GetWifiPhy(linkId);
1027 if (!phy || phy == mainPhy)
1029 NS_LOG_DEBUG(
"No aux PHY is operating on link " << +linkId);
1035 NS_LOG_DEBUG(
"Chosen not to request the main PHY to switch");
1036 if (
const auto untilIdle = mainPhy->GetDelayUntilIdle();
1037 untilIdle.IsStrictlyPositive() && untilIdle < delay)
1054 const auto edca =
GetStaMac()->GetQosTxop(aci);
1055 const auto auxPhy =
GetStaMac()->GetWifiPhy(linkId);
1056 const auto switchDelay = mainPhy->GetChannelSwitchDelay();
1057 const auto auxPhyCcaCanBeUsed =
1073 const auto backoffEnd =
1074 GetStaMac()->GetChannelAccessManager(linkId)->GetBackoffEndFor(edca);
1075 const auto pifs =
GetStaMac()->GetWifiPhy(linkId)->GetPifs();
1084 if (auxPhyCcaCanBeUsed && backoffEnd < now)
1096 else if (!auxPhyCcaCanBeUsed && (backoffEnd - now <= pifs))
1108 NS_LOG_DEBUG(
"Schedule CCA check a PIFS after the end of main PHY switch");
1118 (reason =
GetStaMac()->GetChannelAccessManager(linkId)->GetExpectedAccessWithin(
1120 mainPhy->GetChannelSwitchDelay())) !=
1123 NS_LOG_DEBUG(
"No AC is expected to get backoff soon, switch main PHY back");
1129 if (
const auto mainPhyLinkId =
GetStaMac()->GetLinkForPhy(mainPhy))
1131 auto mainPhyNavEnd =
GetStaMac()->GetChannelAccessManager(*mainPhyLinkId)->GetNavEnd();
AdvancedEmlsrManager is an advanced EMLSR manager.
void SwitchMainPhyBackDelayExpired(uint8_t linkId, std::optional< WifiExpectedAccessReason > stopReason)
This method is called when the switch main PHY back timer (which is started when the main PHY switche...
std::pair< bool, Time > DoGetDelayUntilAccessRequest(uint8_t linkId) override
Subclasses have to provide an implementation for this method, that is called by the base class when t...
void InterruptSwitchMainPhyBackTimerIfNeeded()
This method is called by the PHY listener attached to the main PHY when a switch main PHY back timer ...
void DoNotifyDlTxopStart(uint8_t linkId) override
Notify the subclass of the reception of an initial Control frame on the given link.
std::pair< bool, Time > GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) override
Subclasses have to provide an implementation for this method, that is called by the base class when t...
bool m_useAuxPhyCca
whether the CCA performed in the last PIFS interval by a non-TX capable aux PHY should be used when t...
~AdvancedEmlsrManager() override
bool RequestMainPhyToSwitch(uint8_t linkId, AcIndex aci, const Time &delay)
Determine whether the main PHY shall be requested to switch to the link of an aux PHY that is expecte...
void UnregisterListener()
Disconnect the PHY listener from the PHY it is connected to (if any)
void RegisterListener(Ptr< WifiPhy > phy)
Register a PHY listener so that this EMLSR Manager is notified of PHY events generated by the given P...
void SwitchMainPhyIfTxopToBeGainedByAuxPhy(uint8_t linkId, AcIndex aci, const Time &delay)
This method is called when the given AC of the EMLSR client is expected to get channel access in the ...
bool m_allowUlTxopInRx
whether a (main or aux) PHY is allowed to start an UL TXOP if another PHY is receiving a PPDU
void CheckNavAndCcaLastPifs(Ptr< WifiPhy > phy, uint8_t linkId, Ptr< QosTxop > edca)
Use information from NAV and CCA performed by the given PHY on the given link in the last PIFS interv...
Ptr< WifiPhy > m_auxPhyWithListener
aux PHY which a PHY listener is connected to
std::optional< WifiIcfDrop > CheckMainPhyTakesOverDlTxop(uint8_t linkId) const override
This method is called when an aux PHY has completed reception of an ICF to determine whether there is...
void NotifyEmlsrModeChanged() override
Notify subclass that EMLSR mode changed.
static TypeId GetTypeId()
Get the type ID.
void SwitchMainPhyBackToPreferredLink(uint8_t linkId, EmlsrMainPhySwitchTrace &&traceInfo) override
This method can only be called when aux PHYs do not switch link.
void DoNotifyUlTxopStart(uint8_t linkId) override
Notify the subclass of the start of an UL TXOP on the given link.
std::shared_ptr< WifiPhyListener > m_phyListener
PHY listener connected to an aux PHY (that is not TX capable and does not switch link) while the main...
Time m_switchMainPhyBackDelay
duration of the timer started in case of non-TX capable aux PHY when medium is sensed busy during the...
void DoDispose() override
Destructor implementation.
EventId m_switchMainPhyBackEvent
event scheduled in case of non-TX capable aux PHY when medium is sensed busy during the PIFS interval...
void DoNotifyTxopEnd(uint8_t linkId, Ptr< QosTxop > edca) override
Notify the subclass of the end of a TXOP on the given link.
AcIndex m_minAcToSkipCheckAccess
if m_checkAccessOnMainPhyLink is set to false, indicate the minimum priority AC for which it is allow...
void SwitchMainPhyIfTxopGainedByAuxPhy(uint8_t linkId, AcIndex aci) override
Subclasses have to provide an implementation for this method, that is called by the base class when t...
void DoSetWifiMac(Ptr< StaWifiMac > mac) override
Allow subclasses to take actions when the MAC is set.
bool m_keepMainPhyAfterDlTxop
whether the main PHY must stay, for a switch main PHY back delay, on an aux PHY link after a DL TXOP,...
void ReceivedMacHdr(Ptr< WifiPhy > phy, const WifiMacHeader &macHdr, const WifiTxVector &txVector, Time psduDuration)
Possibly take actions when notified of the MAC header of the MPDU being received by the given PHY.
EventId m_ccaLastPifs
event scheduled in case of non-TX capable aux PHY to determine whether TX can be started based on whe...
bool m_interruptSwitching
whether a main PHY switching can be interrupted to start switching to another link
bool m_checkAccessOnMainPhyLink
in case aux PHYs are not TX capable and an Access Category, say it AC X, is about to gain channel acc...
AttributeValue implementation for Boolean.
DefaultEmlsrManager is the default EMLSR manager.
void NotifyEmlsrModeChanged() override
Notify subclass that EMLSR mode changed.
Ptr< WifiPhy > m_auxPhyToReconnect
Aux PHY the ChannelAccessManager of the link on which the main PHY is operating has to connect a list...
bool m_switchAuxPhy
whether Aux PHY should switch channel to operate on the link on which the Main PHY was operating befo...
Time GetTimeToCtsEnd(uint8_t linkId) const
This function is intended to be called when an aux PHY is about to transmit an RTS on the given link ...
std::map< uint8_t, std::pair< Time, bool > > m_rtsStartingUlTxop
link ID-indexed map indicating the time when an UL TXOP is going to start and whether it is starting ...
virtual void SwitchMainPhyBackToPreferredLink(uint8_t linkId, EmlsrMainPhySwitchTrace &&traceInfo)
This method can only be called when aux PHYs do not switch link.
std::pair< bool, Time > GetDelayUnlessMainPhyTakesOverUlTxop(uint8_t linkId) override
Subclasses have to provide an implementation for this method, that is called by the base class when t...
Time GetMediumSyncDuration() const
void SwitchMainPhy(uint8_t linkId, bool noSwitchDelay, bool requestAccess, EmlsrMainPhySwitchTrace &&traceInfo)
Switch channel on the Main PHY so that it operates on the given link.
bool m_useNotifiedMacHdr
whether to use the information about the MAC header of the MPDU being received (if notified by the PH...
bool m_auxPhyTxCapable
whether Aux PHYs are capable of transmitting PPDUs
bool MediumSyncDelayNTxopsExceeded(uint8_t linkId)
Return whether no more TXOP attempt is allowed on the given link.
Ptr< EhtFrameExchangeManager > GetEhtFem(uint8_t linkId) const
void NotifyUlTxopStart(uint8_t linkId)
Notify the start of an UL TXOP on the given link.
uint8_t m_mainPhyId
ID of main PHY (position in the vector of PHYs held by WifiNetDevice)
const std::set< uint8_t > & GetEmlsrLinks() const
void NotifyTxopEnd(uint8_t linkId, Ptr< QosTxop > edca=nullptr)
Notify the end of a TXOP on the given link.
std::optional< Time > GetElapsedMediumSyncDelayTimer(uint8_t linkId) const
Check whether the MediumSyncDelay timer is running for the STA operating on the given link.
virtual std::optional< WifiIcfDrop > CheckMainPhyTakesOverDlTxop(uint8_t linkId) const
This method is called when an aux PHY has completed reception of an ICF to determine whether there is...
const WifiPhyOperatingChannel & GetChannelForMainPhy(uint8_t linkId) const
MainPhySwitchInfo m_mainPhySwitchInfo
main PHY switch info
static constexpr bool REQUEST_ACCESS
request channel access when PHY switch ends
static constexpr bool DONT_REQUEST_ACCESS
do not request channel access when PHY switch ends
Ptr< StaWifiMac > GetStaMac() const
uint8_t GetMainPhyId() const
const WifiPhyOperatingChannel & GetChannelForAuxPhy(uint8_t linkId) const
std::pair< bool, Time > CheckPossiblyReceivingIcf(uint8_t linkId) const
Check whether a PPDU that may be an ICF is being received on the given link.
PHY listener connected to the main PHY while operating on the link of an aux PHY that is not TX capab...
EmlsrPhyListener(Ptr< AdvancedEmlsrManager > emlsrManager)
Constructor.
void NotifyCcaBusyStart(Time, WifiChannelListType, const std::vector< Time > &) override
void NotifyWakeup() override
Notify listeners that we woke up.
void NotifyOff() override
Notify listeners that we went to switch off.
void NotifyTxStart(Time, dBm_u) override
void NotifyRxEndError(const WifiTxVector &) override
void NotifySwitchingStart(Time) override
void NotifyRxStart(Time) override
void NotifyRxEndOk() override
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
void NotifyOn() override
Notify listeners that we went to switch on.
void NotifySleep() override
Notify listeners that we went to sleep.
Ptr< AdvancedEmlsrManager > m_emlsrManager
the EMLSR manager
Hold variables of type enum.
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
bool IsPending() const
This method is syntactic sugar for !IsExpired().
EventImpl * PeekEventImpl() const
void Invoke()
Called by the simulation engine to notify the event that it is time to execute.
virtual void DoDispose()
Destructor implementation.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now()
Return the current simulation virtual time.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
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.
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
AttributeValue implementation for Time.
static constexpr bool DIDNT_HAVE_FRAMES_TO_TRANSMIT
no packet available for transmission was in the queue
static constexpr bool CHECK_MEDIUM_BUSY
generation of backoff (also) depends on the busy/idle state of the medium
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
uint8_t GetPhyId() const
Get the index allocated to this PHY.
void UnregisterListener(const std::shared_ptr< WifiPhyListener > &listener)
receive notifications about PHY events.
MHz_u GetTotalWidth() const
Return the width of the whole operating channel.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#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...
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
WifiExpectedAccessReason
Enumeration values for the outcome of the check whether channel access is expected to be gained withi...
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ SWITCHING
The PHY layer is switching to other channel.
@ IDLE
The PHY layer is IDLE.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ RX
The PHY layer is receiving a packet.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
const std::map< AcIndex, WifiAc > wifiAcList
Map containing the four ACs in increasing order of priority (according to Table 10-1 "UP-to-AC Mappin...
@ LOG_FUNCTION
Function tracing for non-trivial function calls.
Base struct for EMLSR Main PHY switch traces.
std::string reason
the reason for switching the main PHY
uint8_t from
ID of the link which the main PHY is/has been leaving.
Time start
start of channel switching
uint8_t to
ID of the link which the main PHY is moving to.
bool disconnected
true if the main PHY is not connected to any link, i.e., it is switching or waiting to be connected t...
Struct to trace that main PHY switched to leave a link on which an aux PHY was expected to gain a TXO...
Struct to trace that main PHY switched to operate on a link on which an aux PHY that is not TX capabl...