26#include "ns3/assert.h"
27#include "ns3/attribute-container.h"
29#include "ns3/wifi-mpdu.h"
30#include "ns3/wifi-net-device.h"
31#include "ns3/wifi-phy-state-helper.h"
44 TypeId(
"ns3::EmlsrManager")
47 .AddAttribute(
"EmlsrPaddingDelay",
48 "The EMLSR Paddind Delay (not used by AP MLDs). "
49 "Possible values are 0 us, 32 us, 64 us, 128 us or 256 us.",
53 .AddAttribute(
"EmlsrTransitionDelay",
54 "The EMLSR Transition Delay (not used by AP MLDs). "
55 "Possible values are 0 us, 16 us, 32 us, 64 us, 128 us or 256 us.",
61 "The ID of the main PHY (position in the vector of PHYs held by "
62 "WifiNetDevice). This attribute cannot be set after initialization.",
65 MakeUintegerChecker<uint8_t>())
66 .AddAttribute(
"AuxPhyChannelWidth",
67 "The maximum channel width (MHz) supported by Aux PHYs",
70 MakeUintegerChecker<uint16_t>(20, 160))
73 "IDs of the links on which EMLSR mode will be enabled. An empty set "
74 "indicates to disable EMLSR.",
77 MakeAttributeContainerChecker<UintegerValue>(MakeUintegerChecker<uint8_t>()))
78 .AddAttribute(
"ResetCamState",
79 "Whether to reset the state of the ChannelAccessManager associated with "
80 "the link on which the main PHY has just switched to.",
120 "EmlsrManager can only be installed on non-AP MLDs");
153const std::set<uint8_t>&
188 NS_ABORT_MSG_IF(linkIds.size() == 1,
"Cannot enable EMLSR mode on a single link");
207 const auto& hdr = mpdu->GetHeader();
229 action.protectedEhtAction ==
271 auto uid = auxPhy->GetPreviouslyRxPpduUid();
272 mainPhy->SetPreviouslyRxPpduUid(uid);
282 NS_LOG_DEBUG(
"EMLSR is not enabled on link " << +linkId);
305 "Expecting the aux PHY to be transmitting (an RTS frame)");
321 NS_LOG_DEBUG(
"EMLSR is not enabled on link " << +linkId);
344 "Main PHY is already operating on link " << +linkId);
348 NS_ASSERT_MSG(currMainPhyLinkId,
"Current link ID for main PHY not found");
352 NS_LOG_DEBUG(
"Main PHY (" << mainPhy <<
") is about to switch to " << newMainPhyChannel
353 <<
" to operate on link " << +linkId);
361 "We should not ask the main PHY to switch channel while transmitting");
365 auto delay = mainPhy->GetChannelSwitchDelay();
368 <<
") should exceed the channel switch delay ("
374 mainPhy->SetOperatingChannel(newMainPhyChannel);
378 mainPhy->SetAttribute(
"ChannelSwitchDelay",
TimeValue(delay));
409 if (
auto setupLinkIt = setupLinkIds.find(*emlsrLinkIt); setupLinkIt != setupLinkIds.cend())
411 setupLinkIds.erase(setupLinkIt);
417 NS_LOG_DEBUG(
"Link ID " << +(*emlsrLinkIt) <<
" has not been setup");
434 "AP did not advertise a Transition Timeout, cannot send EML notification");
456 const auto& hdr = mpdu->GetHeader();
458 if (hdr.IsAssocReq())
462 mpdu->GetPacket()->PeekHeader(assocReq);
464 NS_ASSERT_MSG(mle,
"AssocReq should contain a Multi-Link Element");
469 if (hdr.IsMgt() && hdr.IsAction())
473 action.protectedEhtAction ==
491 const auto& hdr = mpdu->GetHeader();
493 if (hdr.IsMgt() && hdr.IsAction())
495 auto pkt = mpdu->GetPacket()->Copy();
498 action.protectedEhtAction ==
507 pkt->RemoveHeader(frame);
556 auxPhy->GetOperatingChannel() == channel)
561 NS_LOG_DEBUG(
"Aux PHY (" << auxPhy <<
") is about to switch to " << channel
562 <<
" to operate on link " << +linkId);
587 for (
auto linkId : linkIds)
592 auto mainPhyChWidth = channel.GetWidth();
605 channel.GetPhyBand());
610 auto p20Index = channel.GetPrimaryChannelIndex(20);
625 "Channel for main PHY on link ID " << +linkId <<
" not found");
634 "Channel for aux PHY on link ID " << +linkId <<
" not found");
A container for one type of attribute.
AttributeValue implementation for Boolean.
void NotifySwitchingEmlsrLink(Ptr< WifiPhy > phy, const WifiPhyOperatingChannel &channel, uint8_t linkId)
Notify that the given PHY is about to switch to the given operating channel, which is used by the giv...
void NotifyStopUsingOtherEmlsrLink()
Notify that another EMLSR link is no longer being used, hence medium access can be resumed.
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.
void ComputeOperatingChannels()
Compute the operating channels that the main PHY and the aux PHY(s) must switch to in order to operat...
void ApplyMaxChannelWidthOnAuxPhys()
Adjust the operating channel of all the aux PHYs to meet the constraint on the maximum channel width ...
void SetTransitionTimeout(Time timeout)
Set the Transition Timeout advertised by the associated AP with EMLSR activated.
std::optional< Time > GetTransitionTimeout() const
void ChangeEmlsrMode()
This method is called to make an EMLSR mode change effective after the transition delay has elapsed o...
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 NotifyUlTxopStart(uint8_t linkId)
Notify the start of an UL TXOP on the given link.
void TxOk(Ptr< const WifiMpdu > mpdu)
Notify the acknowledgment of the given MPDU.
virtual void NotifyMainPhySwitch(uint8_t currLinkId, uint8_t nextLinkId)=0
Notify subclass that the main PHY is switching channel to operate on another link.
bool GetCamStateReset() const
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,...
uint8_t m_mainPhyId
ID of main PHY (position in the vector of PHYs held by WifiNetDevice)
void NotifyIcfReceived(uint8_t linkId)
Notify the reception of an initial Control frame on the given link.
void NotifyMgtFrameReceived(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
Notify the reception of a management frame addressed to us.
virtual uint8_t GetLinkToSendEmlOmn()=0
std::map< uint8_t, WifiPhyOperatingChannel > m_auxPhyChannels
link ID-indexed map of operating channels for the aux PHYs
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 NotifyTxopEnd(uint8_t linkId)
Notify the end of a TXOP on the given link.
Time m_emlsrTransitionDelay
EMLSR Transition delay.
void SetWifiMac(Ptr< StaWifiMac > mac)
Set the wifi MAC.
const std::set< uint8_t > & GetEmlsrLinks() const
std::optional< Time > m_emlsrTransitionTimeout
Transition timeout advertised by APs with EMLSR activated.
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.
virtual void NotifyEmlsrModeChanged()=0
Notify subclass that EMLSR mode changed.
void SetMainPhyId(uint8_t mainPhyId)
Set the ID of main PHY (position in the vector of PHYs held by WifiNetDevice).
const WifiPhyOperatingChannel & GetChannelForMainPhy(uint8_t linkId) const
void SwitchMainPhy(uint8_t linkId, bool noSwitchDelay)
Switch channel on the Main PHY so that it operates on the given link.
Time m_lastAdvTransitionDelay
last advertised transition delay
void DoDispose() override
Destructor implementation.
std::map< uint8_t, WifiPhyOperatingChannel > m_mainPhyChannels
link ID-indexed map of operating channels for the main PHY
virtual std::optional< uint8_t > ResendNotification(Ptr< const WifiMpdu > mpdu)=0
A previous EML Operating Mode Notification frame was dropped.
Ptr< StaWifiMac > GetStaMac() const
Time m_lastAdvPaddingDelay
last advertised padding delay
uint8_t GetMainPhyId() 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
const WifiPhyOperatingChannel & GetChannelForAuxPhy(uint8_t linkId) const
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)
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
EventImpl * PeekEventImpl() const
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
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.
std::set< uint8_t > GetSetupLinkIds() const
Get the IDs of the setup links (if any).
void UnblockTxOnLink(uint8_t linkId, WifiQueueBlockedReason reason)
Unblock transmissions on the given link for the given reason.
void BlockTxOnLink(uint8_t linkId, WifiQueueBlockedReason reason)
Block transmissions on the given link for the given reason.
void NotifyEmlsrModeChanged(const std::set< uint8_t > &linkIds)
Notify the MAC that EMLSR mode has changed on the given set of links.
bool IsEmlsrLink(uint8_t linkId) const
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.
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
Ptr< WifiPhyStateHelper > GetState() const
Return the WifiPhyStateHelper of this PHY.
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Class that keeps track of all information about the current PHY operating channel.
static const std::set< FrequencyChannelInfo > m_frequencyChannels
Available frequency channels.
static ConstIterator FindFirst(uint8_t number, uint16_t frequency, uint16_t width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first channel matching the specified parameters.
#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
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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...
static uint8_t EncodeEmlsrTransitionDelay(Time delay)
static uint8_t EncodeEmlsrPaddingDelay(Time delay)
uint8_t emlsrMode
EMLSR Mode.
uint8_t emlsrParamUpdateCtrl
EMLSR Parameter Update Control.
EMLSR Parameter Update field.
@ TX
The PHY layer is sending a packet.