26#include "ns3/assert.h"
27#include "ns3/attribute-container.h"
29#include "ns3/mgt-action-headers.h"
30#include "ns3/wifi-mpdu.h"
31#include "ns3/wifi-net-device.h"
32#include "ns3/wifi-phy-state-helper.h"
48 TypeId(
"ns3::EmlsrManager")
51 .AddAttribute(
"EmlsrPaddingDelay",
52 "The EMLSR Paddind Delay (not used by AP MLDs). "
53 "Possible values are 0 us, 32 us, 64 us, 128 us or 256 us.",
57 .AddAttribute(
"EmlsrTransitionDelay",
58 "The EMLSR Transition Delay (not used by AP MLDs). "
59 "Possible values are 0 us, 16 us, 32 us, 64 us, 128 us or 256 us.",
65 "The ID of the main PHY (position in the vector of PHYs held by "
66 "WifiNetDevice). This attribute cannot be set after construction.",
70 MakeUintegerChecker<uint8_t>())
71 .AddAttribute(
"AuxPhyChannelWidth",
72 "The maximum channel width (MHz) supported by Aux PHYs. Note that the "
73 "maximum channel width is capped to the maximum channel width supported "
74 "by the configured maximum modulation class supported.",
79 MakeUintegerChecker<uint16_t>(20, 160))
80 .AddAttribute(
"AuxPhyMaxModClass",
81 "The maximum modulation class supported by Aux PHYs. Use "
82 "WIFI_MOD_CLASS_OFDM for non-HT.",
101 .AddAttribute(
"AuxPhyTxCapable",
102 "Whether Aux PHYs are capable of transmitting PPDUs.",
109 "IDs of the links on which EMLSR mode will be enabled. An empty set "
110 "indicates to disable EMLSR.",
113 MakeAttributeContainerChecker<UintegerValue>(MakeUintegerChecker<uint8_t>()))
114 .AddAttribute(
"ResetCamState",
115 "Whether to reset the state of the ChannelAccessManager associated with "
116 "the link on which the main PHY has just switched to.",
152 status.timer.Cancel();
167 "EmlsrManager can only be installed on non-AP MLDs");
212const std::set<uint8_t>&
287std::optional<uint8_t>
296 std::stringstream ss;
299 std::copy(linkIds.cbegin(), linkIds.cend(), std::ostream_iterator<uint16_t>(ss,
" "));
302 NS_ABORT_MSG_IF(linkIds.size() == 1,
"Cannot enable EMLSR mode on a single link");
321 const auto& hdr = mpdu->GetHeader();
343 action.protectedEhtAction ==
389 auto uid = auxPhy->GetPreviouslyRxPpduUid();
390 mainPhy->SetPreviouslyRxPpduUid(uid);
403 NS_LOG_DEBUG(
"EMLSR is not enabled on link " << +linkId);
425 "Expecting the aux PHY to be transmitting (an RTS frame)");
427 "Aux PHY is sending RTS, expected to get the time to CTS end");
456 NS_LOG_DEBUG(
"EMLSR is not enabled on link " << +linkId);
465 if (it->second.IsPending())
467 NS_LOG_DEBUG(
"Cancelling main PHY channel switch event on link " << +linkId);
485 if (ulTxopNotStarted)
495 std::set<uint8_t> linkIds;
498 if ((id != linkId) && m_staMac->IsEmlsrLink(id))
500 m_staMac->GetChannelAccessManager(id)->NotifyStopUsingOtherEmlsrLink();
511EmlsrManager::SetCcaEdThresholdOnLinkSwitch(
Ptr<WifiPhy> phy, uint8_t linkId)
517 if (
auto statusIt = m_mediumSyncDelayStatus.find(linkId);
518 statusIt != m_mediumSyncDelayStatus.cend() && statusIt->second.timer.IsPending())
520 NS_LOG_DEBUG(
"Setting CCA ED threshold of PHY " << phy <<
" to " << +m_msdOfdmEdThreshold
521 <<
" on link " << +linkId);
524 m_prevCcaEdThreshold.try_emplace(phy, phy->GetCcaEdThreshold());
526 phy->SetCcaEdThreshold(m_msdOfdmEdThreshold);
529 else if (
auto threshIt = m_prevCcaEdThreshold.find(phy);
530 threshIt != m_prevCcaEdThreshold.cend())
532 NS_LOG_DEBUG(
"Resetting CCA ED threshold of PHY " << phy <<
" to " << threshIt->second
533 <<
" on link " << +linkId);
534 phy->SetCcaEdThreshold(threshIt->second);
535 m_prevCcaEdThreshold.erase(threshIt);
540EmlsrManager::SwitchMainPhy(uint8_t linkId,
545 NS_LOG_FUNCTION(
this << linkId << noSwitchDelay << resetBackoff << requestAccess);
547 auto mainPhy = m_staMac->GetDevice()->GetPhy(m_mainPhyId);
550 "Main PHY is already operating on link " << +linkId);
552 if (mainPhy->IsStateSwitching())
554 NS_LOG_DEBUG(
"Main PHY is already switching, ignore new switching request");
559 auto currMainPhyLinkId = m_staMac->GetLinkForPhy(mainPhy);
560 NS_ASSERT_MSG(currMainPhyLinkId,
"Current link ID for main PHY not found");
562 auto newMainPhyChannel = GetChannelForMainPhy(linkId);
564 NS_LOG_DEBUG(
"Main PHY (" << mainPhy <<
") is about to switch to " << newMainPhyChannel
565 <<
" to operate on link " << +linkId);
568 m_staMac->GetChannelAccessManager(*currMainPhyLinkId)
569 ->NotifySwitchingEmlsrLink(mainPhy, newMainPhyChannel, linkId);
573 "We should not ask the main PHY to switch channel while transmitting");
576 const auto delay = mainPhy->GetChannelSwitchDelay();
577 const auto pifs = mainPhy->GetSifs() + mainPhy->GetSlot();
578 NS_ASSERT_MSG(noSwitchDelay || delay <= std::max(m_lastAdvTransitionDelay, pifs),
579 "Channel switch delay ("
580 << delay.As(Time::US)
581 <<
") should be shorter than the maximum between the Transition delay ("
582 << m_lastAdvTransitionDelay.As(Time::US) <<
") and a PIFS ("
583 << pifs.As(Time::US) <<
")");
588 mainPhy->SetOperatingChannel(newMainPhyChannel);
592 mainPhy->SetAttribute(
"ChannelSwitchDelay",
TimeValue(delay));
595 if (m_staMac->GetWifiRemoteStationManager(linkId)->GetShortSlotTimeEnabled())
603 m_staMac->GetChannelAccessManager(*currMainPhyLinkId)->ResetAllBackoffs();
606 const auto timeToSwitchEnd = noSwitchDelay ?
Seconds(0) : mainPhy->GetChannelSwitchDelay();
611 Simulator::Schedule(timeToSwitchEnd, [=,
this]() {
614 m_staMac->GetQosTxop(acIndex)->StartAccessAfterEvent(
616 Txop::DIDNT_HAVE_FRAMES_TO_TRANSMIT,
617 Txop::CHECK_MEDIUM_BUSY);
622 SetCcaEdThresholdOnLinkSwitch(mainPhy, linkId);
623 NotifyMainPhySwitch(*currMainPhyLinkId, linkId);
627EmlsrManager::SwitchAuxPhy(uint8_t currLinkId, uint8_t nextLinkId)
631 auto auxPhy = GetStaMac()->GetWifiPhy(currLinkId);
633 auto newAuxPhyChannel = GetChannelForAuxPhy(nextLinkId);
635 NS_LOG_DEBUG(
"Aux PHY (" << auxPhy <<
") is about to switch to " << newAuxPhyChannel
636 <<
" to operate on link " << +nextLinkId);
639 ->GetChannelAccessManager(currLinkId)
640 ->NotifySwitchingEmlsrLink(auxPhy, newAuxPhyChannel, nextLinkId);
642 auxPhy->SetOperatingChannel(newAuxPhyChannel);
644 if (m_staMac->GetWifiRemoteStationManager(nextLinkId)->GetShortSlotTimeEnabled())
650 Simulator::Schedule(auxPhy->GetChannelSwitchDelay(), [=,
this]() {
651 for (const auto& [acIndex, ac] : wifiAcList)
653 m_staMac->GetQosTxop(acIndex)->StartAccessAfterEvent(
655 Txop::DIDNT_HAVE_FRAMES_TO_TRANSMIT,
656 Txop::CHECK_MEDIUM_BUSY);
660 SetCcaEdThresholdOnLinkSwitch(auxPhy, nextLinkId);
664EmlsrManager::StartMediumSyncDelayTimer(uint8_t linkId)
669 for (
auto id : m_staMac->GetLinkIds())
671 if (
id != linkId && m_staMac->IsEmlsrLink(
id))
673 const auto [it, inserted] = m_mediumSyncDelayStatus.try_emplace(
id);
676 it->second.msdNTxopsLeft = m_msdMaxNTxops;
682 if (
auto phy = m_staMac->GetWifiPhy(
id); phy && !it->second.timer.IsPending())
685 << +
id <<
" to " << +m_msdOfdmEdThreshold <<
" PHY " << phy);
686 m_prevCcaEdThreshold[phy] = phy->GetCcaEdThreshold();
687 phy->SetCcaEdThreshold(m_msdOfdmEdThreshold);
691 it->second.timer.Cancel();
692 it->second.timer = Simulator::Schedule(m_mediumSyncDuration,
693 &EmlsrManager::MediumSyncDelayTimerExpired,
701EmlsrManager::CancelMediumSyncDelayTimer(uint8_t linkId)
705 auto timerIt = m_mediumSyncDelayStatus.find(linkId);
707 NS_ASSERT(timerIt != m_mediumSyncDelayStatus.cend() && timerIt->second.timer.IsPending());
709 timerIt->second.timer.Cancel();
710 MediumSyncDelayTimerExpired(linkId);
714EmlsrManager::MediumSyncDelayTimerExpired(uint8_t linkId)
718 auto timerIt = m_mediumSyncDelayStatus.find(linkId);
720 NS_ASSERT(timerIt != m_mediumSyncDelayStatus.cend() && !timerIt->second.timer.IsPending());
723 auto phy = m_staMac->GetWifiPhy(linkId);
734 auto threshIt = m_prevCcaEdThreshold.find(phy);
736 "No value to restore for CCA ED threshold on PHY " << phy);
737 NS_LOG_DEBUG(
"Resetting CCA ED threshold of PHY " << phy <<
" to " << threshIt->second
738 <<
" on link " << +linkId);
739 phy->SetCcaEdThreshold(threshIt->second);
740 m_prevCcaEdThreshold.erase(threshIt);
744EmlsrManager::DecrementMediumSyncDelayNTxops(uint8_t linkId)
748 const auto timerIt = m_mediumSyncDelayStatus.find(linkId);
750 NS_ASSERT(timerIt != m_mediumSyncDelayStatus.cend() && timerIt->second.timer.IsPending());
751 NS_ASSERT(timerIt->second.msdNTxopsLeft != 0);
753 if (timerIt->second.msdNTxopsLeft)
755 --timerIt->second.msdNTxopsLeft.value();
760EmlsrManager::ResetMediumSyncDelayNTxops(uint8_t linkId)
764 auto timerIt = m_mediumSyncDelayStatus.find(linkId);
766 NS_ASSERT(timerIt != m_mediumSyncDelayStatus.cend() && timerIt->second.timer.IsPending());
767 timerIt->second.msdNTxopsLeft.reset();
771EmlsrManager::MediumSyncDelayNTxopsExceeded(uint8_t linkId)
775 auto timerIt = m_mediumSyncDelayStatus.find(linkId);
777 NS_ASSERT(timerIt != m_mediumSyncDelayStatus.cend() && timerIt->second.timer.IsPending());
778 return timerIt->second.msdNTxopsLeft == 0;
782EmlsrManager::GetEmlOmn()
787 if (m_lastAdvPaddingDelay != m_emlsrPaddingDelay ||
788 m_lastAdvTransitionDelay != m_emlsrTransitionDelay)
790 m_lastAdvPaddingDelay = m_emlsrPaddingDelay;
791 m_lastAdvTransitionDelay = m_emlsrTransitionDelay;
795 CommonInfoBasicMle::EncodeEmlsrPaddingDelay(m_lastAdvPaddingDelay);
797 CommonInfoBasicMle::EncodeEmlsrTransitionDelay(m_lastAdvTransitionDelay);
801 auto setupLinkIds = m_staMac->GetSetupLinkIds();
803 for (
auto emlsrLinkIt = m_nextEmlsrLinks->begin(); emlsrLinkIt != m_nextEmlsrLinks->end();)
805 if (
auto setupLinkIt = setupLinkIds.find(*emlsrLinkIt); setupLinkIt != setupLinkIds.cend())
807 setupLinkIds.erase(setupLinkIt);
813 NS_LOG_DEBUG(
"Link ID " << +(*emlsrLinkIt) <<
" has not been setup");
814 emlsrLinkIt = m_nextEmlsrLinks->erase(emlsrLinkIt);
825EmlsrManager::SendEmlOmn()
830 "AP did not advertise a Transition Timeout, cannot send EML notification");
831 NS_ASSERT_MSG(m_nextEmlsrLinks,
"Need to set EMLSR links before calling this method");
842 auto frame = GetEmlOmn();
843 auto linkId = GetLinkToSendEmlOmn();
844 GetEhtFem(linkId)->SendEmlOmn(m_staMac->GetBssid(linkId), frame);
852 const auto& hdr = mpdu->GetHeader();
854 if (hdr.IsAssocReq())
858 mpdu->GetPacket()->PeekHeader(assocReq);
860 NS_ASSERT_MSG(mle,
"AssocReq should contain a Multi-Link Element");
861 m_lastAdvPaddingDelay = mle->GetEmlsrPaddingDelay();
862 m_lastAdvTransitionDelay = mle->GetEmlsrTransitionDelay();
865 if (hdr.IsMgt() && hdr.IsAction())
867 if (
auto [category, action] = WifiActionHeader::Peek(mpdu->GetPacket());
868 category == WifiActionHeader::PROTECTED_EHT &&
869 action.protectedEhtAction ==
870 WifiActionHeader::PROTECTED_EHT_EML_OPERATING_MODE_NOTIFICATION)
874 NS_ASSERT_MSG(m_emlsrTransitionTimeout,
"No transition timeout received from AP");
875 m_transitionTimeoutEvent = Simulator::Schedule(*m_emlsrTransitionTimeout,
876 &EmlsrManager::ChangeEmlsrMode,
887 const auto& hdr = mpdu->GetHeader();
889 if (hdr.IsMgt() && hdr.IsAction())
891 auto pkt = mpdu->GetPacket()->Copy();
892 if (
auto [category, action] = WifiActionHeader::Remove(pkt);
893 category == WifiActionHeader::PROTECTED_EHT &&
894 action.protectedEhtAction ==
895 WifiActionHeader::PROTECTED_EHT_EML_OPERATING_MODE_NOTIFICATION)
899 auto linkId = ResendNotification(mpdu);
903 pkt->RemoveHeader(frame);
904 GetEhtFem(*linkId)->SendEmlOmn(m_staMac->GetBssid(*linkId), frame);
908 m_nextEmlsrLinks.reset();
915EmlsrManager::ChangeEmlsrMode()
926 NS_ASSERT_MSG(m_nextEmlsrLinks,
"No set of EMLSR links stored");
927 m_emlsrLinks.swap(*m_nextEmlsrLinks);
928 m_nextEmlsrLinks.reset();
932 m_staMac->NotifyEmlsrModeChanged(m_emlsrLinks);
934 ApplyMaxChannelWidthAndModClassOnAuxPhys();
936 NotifyEmlsrModeChanged();
940EmlsrManager::ApplyMaxChannelWidthAndModClassOnAuxPhys()
943 auto currMainPhyLinkId = m_staMac->GetLinkForPhy(m_mainPhyId);
946 for (
const auto linkId : m_staMac->GetLinkIds())
948 auto auxPhy = m_staMac->GetWifiPhy(linkId);
949 auto channel = GetChannelForAuxPhy(linkId);
951 if (linkId == currMainPhyLinkId || !m_staMac->IsEmlsrLink(linkId) ||
952 auxPhy->GetOperatingChannel() == channel)
957 auxPhy->SetMaxModulationClassSupported(m_auxPhyMaxModClass);
959 NS_LOG_DEBUG(
"Aux PHY (" << auxPhy <<
") is about to switch to " << channel
960 <<
" to operate on link " << +linkId);
966 auto cam = m_staMac->GetChannelAccessManager(linkId);
967 cam->NotifySwitchingEmlsrLink(auxPhy, channel, linkId);
969 auxPhy->SetOperatingChannel(channel);
976 cam->ResetAllBackoffs();
977 Simulator::Schedule(auxPhy->GetChannelSwitchDelay(), [=,
this]() {
978 for (const auto& [acIndex, ac] : wifiAcList)
980 m_staMac->GetQosTxop(acIndex)->StartAccessAfterEvent(
982 Txop::DIDNT_HAVE_FRAMES_TO_TRANSMIT,
983 Txop::CHECK_MEDIUM_BUSY);
990EmlsrManager::ComputeOperatingChannels()
994 m_mainPhyChannels.clear();
995 m_auxPhyChannels.clear();
997 auto linkIds = m_staMac->GetSetupLinkIds();
999 for (
auto linkId : linkIds)
1001 const auto& channel = m_staMac->GetWifiPhy(linkId)->GetOperatingChannel();
1002 m_mainPhyChannels.emplace(linkId, channel);
1004 auto mainPhyChWidth = channel.GetWidth();
1005 auto auxPhyMaxWidth =
1007 if (auxPhyMaxWidth >= mainPhyChWidth)
1010 m_auxPhyChannels.emplace(linkId, channel);
1014 auto freq = channel.GetPrimaryChannelCenterFrequency(auxPhyMaxWidth);
1015 auto chIt = WifiPhyOperatingChannel::FindFirst(0,
1019 channel.GetPhyBand());
1020 NS_ASSERT_MSG(chIt != WifiPhyOperatingChannel::m_frequencyChannels.end(),
1021 "Primary" << auxPhyMaxWidth <<
" channel not found");
1022 m_auxPhyChannels.emplace(linkId, chIt);
1024 auto p20Index = channel.GetPrimaryChannelIndex(20);
1025 while (mainPhyChWidth > auxPhyMaxWidth)
1027 mainPhyChWidth /= 2;
1030 m_auxPhyChannels[linkId].SetPrimary20Index(p20Index);
1035EmlsrManager::GetChannelForMainPhy(uint8_t linkId)
const
1037 auto it = m_mainPhyChannels.find(linkId);
1039 "Channel for main PHY on link ID " << +linkId <<
" not found");
1044EmlsrManager::GetChannelForAuxPhy(uint8_t linkId)
const
1046 auto it = m_auxPhyChannels.find(linkId);
1048 "Channel for aux PHY on link ID " << +linkId <<
" not found");
A container for one type of attribute.
AttributeValue implementation for Boolean.
void NotifyStartUsingOtherEmlsrLink()
Notify that another EMLSR link is being used, hence medium access should be disabled.
void SendEmlOmn()
Send an EML Operating Mode Notification frame.
Time GetMediumSyncDuration() const
void ComputeOperatingChannels()
Compute the operating channels that the main PHY and the aux PHY(s) must switch to in order to operat...
void SetTransitionTimeout(Time timeout)
Set the Transition Timeout advertised by the associated AP with EMLSR activated.
bool m_auxPhyTxCapable
whether Aux PHYs are capable of transmitting PPDUs
std::optional< Time > GetTransitionTimeout() const
Ptr< EhtFrameExchangeManager > GetEhtFem(uint8_t linkId) const
void TxDropped(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Notify that the given MPDU has been discarded for the given reason.
void TxOk(Ptr< const WifiMpdu > mpdu)
Notify the acknowledgment of the given MPDU.
void NotifyTxopEnd(uint8_t linkId, bool ulTxopNotStarted=false, bool ongoingDlTxop=false)
Notify the end of a TXOP on the given link.
std::map< uint8_t, EventId > m_ulMainPhySwitch
link ID-indexed map of timers started when an aux PHY gains an UL TXOP and schedules a channel switch...
void SwitchMainPhy(uint8_t linkId, bool noSwitchDelay, bool resetBackoff, bool requestAccess)
Switch channel on the Main PHY so that it operates on the given link.
bool GetCamStateReset() const
void NotifyUlTxopStart(uint8_t linkId, std::optional< Time > timeToCtsEnd)
Notify the start of an UL TXOP on the given link.
void SetEmlsrLinks(const std::set< uint8_t > &linkIds)
Take actions to enable EMLSR mode on the given set of links, if non-empty, or disable EMLSR mode,...
void SetMediumSyncOfdmEdThreshold(int8_t threshold)
Set the Medium Synchronization OFDM ED threshold (dBm) to use while the MediumSyncDelay timer is runn...
uint8_t m_mainPhyId
ID of main PHY (position in the vector of PHYs held by WifiNetDevice)
int8_t GetMediumSyncOfdmEdThreshold() const
void NotifyIcfReceived(uint8_t linkId)
Notify the reception of an initial Control frame on the given link.
std::map< uint8_t, MediumSyncDelayStatus > m_mediumSyncDelayStatus
the status of MediumSyncDelay timers (link ID-indexed)
void NotifyMgtFrameReceived(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
Notify the reception of a management frame addressed to us.
virtual void DoNotifyUlTxopStart(uint8_t linkId)=0
Notify the subclass of the start of an UL TXOP on the given link.
Ptr< StaWifiMac > m_staMac
the MAC of the managed non-AP MLD
virtual void DoNotifyMgtFrameReceived(Ptr< const WifiMpdu > mpdu, uint8_t linkId)=0
Notify the subclass of the reception of a management frame addressed to us.
Time m_emlsrPaddingDelay
EMLSR Padding delay.
void SetMediumSyncMaxNTxops(std::optional< uint8_t > nTxops)
Set the maximum number of TXOPs a non-AP STA is allowed to attempt to initiate while the MediumSyncDe...
Time m_emlsrTransitionDelay
EMLSR Transition delay.
void SetWifiMac(Ptr< StaWifiMac > mac)
Set the wifi MAC.
bool GetAuxPhyTxCapable() const
const std::set< uint8_t > & GetEmlsrLinks() const
Time m_mediumSyncDuration
duration of the MediumSyncDelay timer
std::optional< Time > m_emlsrTransitionTimeout
Transition timeout advertised by APs with EMLSR activated.
std::optional< Time > GetElapsedMediumSyncDelayTimer(uint8_t linkId) const
Check whether the MediumSyncDelay timer is running for the STA operating on the given link.
virtual void DoNotifyTxopEnd(uint8_t linkId)=0
Notify the subclass of the end of a TXOP on the given link.
void SetAuxPhyTxCapable(bool capable)
Set the member variable indicating whether Aux PHYs are capable of transmitting PPDUs.
std::optional< std::set< uint8_t > > m_nextEmlsrLinks
ID of the links that will become the EMLSR links when the pending notification frame is acknowledged.
void SetMainPhyId(uint8_t mainPhyId)
Set the ID of main PHY (position in the vector of PHYs held by WifiNetDevice).
void SetMediumSyncDuration(Time duration)
Set the duration of the MediumSyncDelay timer.
static constexpr bool RESET_BACKOFF
reset backoff on main PHY switch
static constexpr bool DONT_REQUEST_ACCESS
do not request channel access when PHY switch ends
void DoDispose() override
Destructor implementation.
void StartMediumSyncDelayTimer(uint8_t linkId)
Start the MediumSyncDelay timer and take the appropriate actions, if the timer is not already running...
int8_t m_msdOfdmEdThreshold
MediumSyncDelay OFDM ED threshold.
std::optional< uint8_t > m_msdMaxNTxops
MediumSyncDelay max number of TXOPs.
Ptr< StaWifiMac > GetStaMac() const
WifiModulationClass m_auxPhyMaxModClass
max modulation class supported by aux PHYs
uint8_t GetMainPhyId() const
std::optional< uint8_t > GetMediumSyncMaxNTxops() const
void SetCamStateReset(bool enable)
Set the member variable indicating whether the state of the CAM should be reset when the main PHY swi...
EventId m_transitionTimeoutEvent
Timer started after the successful transmission of an EML Operating Mode Notification frame.
uint16_t m_auxPhyMaxWidth
max channel width (MHz) supported by aux PHYs
virtual void DoNotifyIcfReceived(uint8_t linkId)=0
Notify the subclass of the reception of an initial Control frame on the given link.
bool m_resetCamState
whether to reset the state of CAM when main PHY switches channel
static TypeId GetTypeId()
Get the type ID.
std::set< uint8_t > m_emlsrLinks
ID of the EMLSR links (empty if EMLSR mode is disabled)
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.
Implement the header for Action frames of type EML Operating Mode Notification.
void SetLinkIdInBitmap(uint8_t linkId)
Set the bit position in the link bitmap corresponding to the given link.
EmlControl m_emlControl
EML Control field.
std::optional< EmlsrParamUpdate > m_emlsrParamUpdate
EMLSR Parameter Update field.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
A base class which provides memory management and object aggregation.
virtual void DoDispose()
Destructor implementation.
bool IsInitialized() const
Check if the object has been initialized.
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 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.
void BlockTxOnLink(uint8_t linkId, WifiQueueBlockedReason reason)
Block transmissions on the given link for the given reason.
bool IsEmlsrLink(uint8_t linkId) const
void UnblockTxOnLink(std::set< uint8_t > linkIds, WifiQueueBlockedReason reason)
Unblock transmissions on the given links for the given reason.
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.
AttributeValue implementation for Time.
a unique identifier for an interface.
@ ATTR_GET
The attribute can be read.
@ ATTR_CONSTRUCT
The attribute can be written at construction-time.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Mac48Address GetBssid(uint8_t linkId) const
TypeOfStation GetTypeOfStation() const
Return the type of station.
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Ptr< WifiPhy > GetWifiPhy(uint8_t linkId=SINGLE_LINK_OP_ID) const
Ptr< EhtConfiguration > GetEhtConfiguration() const
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
std::optional< uint8_t > GetLinkForPhy(Ptr< const WifiPhy > phy) const
Get the ID of the link (if any) on which the given PHY is operating.
const std::set< uint8_t > & GetLinkIds() const
Ptr< ChannelAccessManager > GetChannelAccessManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Channel Access Manager associated with the given link.
Ptr< WifiPhy > GetPhy() const
Time GetChannelSwitchDelay() const
Ptr< WifiPhyStateHelper > GetState() const
Return the WifiPhyStateHelper of this PHY.
Class that keeps track of all information about the current PHY operating channel.
#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 AttributeAccessor > MakeBooleanAccessor(T1 a1)
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
#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 MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
WifiMacDropReason
The reason why an MPDU was dropped.
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ WIFI_MOD_CLASS_HR_DSSS
HR/DSSS (Clause 16)
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_MOD_CLASS_ERP_OFDM
ERP-OFDM (18.4)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static constexpr uint8_t DEFAULT_MSD_MAX_N_TXOPS
default MediumSyncDelay max number of TXOP attempts
@ TX
The PHY layer is sending a packet.
uint16_t GetMaximumChannelWidth(WifiModulationClass modulation)
Get the maximum channel width in MHz allowed for the given modulation class.
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...
static constexpr int8_t DEFAULT_MSD_OFDM_ED_THRESH
default MediumSyncDelay timer OFDM ED threshold
@ LOG_FUNCTION
Function tracing for non-trivial function calls.
static constexpr uint16_t DEFAULT_MSD_DURATION_USEC
default MediumSyncDelay timer duration (max PPDU TX time rounded to a multiple of 32 us)
uint8_t emlsrMode
EMLSR Mode.
uint8_t emlsrParamUpdateCtrl
EMLSR Parameter Update Control.
EMLSR Parameter Update field.