16#include "ns3/simulator.h"
29 TypeId(
"ns3::DefaultPowerSaveManager")
33 .AddAttribute(
"PsmTimeout",
34 "The length of the extra time during which the PHY is kept in active "
35 "state before being put to sleep state. If channel access is requested "
36 "(to transmit a frame) during such extra time, the PHY is kept in active "
37 "state to attempt to gain channel access and transmit. See the TGax "
38 "Simulation Scenarios document IEEE 802.11-14/0980r16.",
42 .AddAttribute(
"ListenAdvance",
43 "The amount of time the STA wakes up in advance prior to the Target "
44 "Beacon Transmission Time.",
74 NS_LOG_DEBUG(
"STA on link " << +linkId <<
" is in active mode");
78 if (
GetStaMac()->GetWifiPhy(linkId)->IsStateSleep())
80 NS_LOG_DEBUG(
"PHY operating on link " << +linkId <<
" is already in sleep state");
86 if (staInfo.beaconInterval.IsZero() || staInfo.lastBeaconTimestamp.IsZero())
88 NS_LOG_DEBUG(
"No Beacon received yet, cannot put PHY to sleep");
92 if (staInfo.pendingUnicast)
94 NS_LOG_DEBUG(
"AP has pending unicast frames, do not put PHY to sleep");
98 if (staInfo.pendingGroupcast)
100 NS_LOG_DEBUG(
"AP has pending groupcast frames, do not put PHY to sleep");
106 NS_LOG_DEBUG(
"Channel access requested or gained, do not put PHY to sleep");
112 NS_LOG_DEBUG(
"Already scheduled a sleep event, do nothing");
116 auto putToSleep = [=,
this] {
117 NS_LOG_DEBUG(
"PHY operating on link " << +linkId <<
" is put to sleep");
118 GetStaMac()->GetWifiPhy(linkId)->SetSleepMode(
true);
128 auto delay = (
Simulator::Now() - staInfo.lastBeaconTimestamp) % staInfo.beaconInterval;
129 delay = staInfo.beaconInterval - delay;
134 NS_LOG_DEBUG(
"Scheduling PHY on link " << +linkId <<
" to wake up in "
140 NS_LOG_DEBUG(
"Scheduling sleep state for PHY on link " << +linkId <<
"at time "
150 const auto linkIds =
GetStaMac()->GetSetupLinkIds();
151 for (
const auto linkId : linkIds)
223 NS_LOG_LOGIC(
"Waiting for more unicast frames; enqueue a PS-Poll frame");
249 if (
auto phy =
GetStaMac()->GetWifiPhy(linkId); phy->IsStateSleep())
251 NS_LOG_DEBUG(
"Resume from sleep STA operating on link " << +linkId);
252 phy->ResumeFromSleep();
273 if (mpdu->GetHeader().IsPsPoll())
275 auto addr2 = mpdu->GetHeader().GetAddr2();
276 const auto linkId =
GetStaMac()->GetLinkIdByAddress(addr2);
277 NS_ASSERT_MSG(linkId.has_value(), addr2 <<
" is not a link address");
279 NS_LOG_DEBUG(
"PS-Poll dropped. Give up polling the AP on link " << +linkId.value());
283 staInfo.pendingUnicast =
false;
287 for (
const auto&
id :
GetStaMac()->GetLinkIds())
DefaultPowerSaveManager is the default power save manager.
void DoNotifyReceivedFrameAfterPsPoll(Ptr< const WifiMpdu > mpdu, linkId_t linkId) override
Notify subclasses of the reception of a frame in response to a PS-Poll frame on the given link.
void DoNotifyRequestAccess(Ptr< Txop > txop, linkId_t linkId) override
Notify subclasses that the given TXOP is requesting channel access on the given link.
std::map< linkId_t, EventId > m_sleepEvents
events scheduled to set PHYs to sleep
std::map< linkId_t, EventId > m_wakeUpEvents
events scheduled to wake up PHYs
Time m_listenAdvance
the amount of time the STA wakes up in advance prior to the TBTT
void DoNotifyDisassociation() override
Notify subclasses that the non-AP STA/MLD has disassociated.
void DoNotifyReceivedGroupcast(Ptr< const WifiMpdu > mpdu, linkId_t linkId) override
Notify subclasses of the reception of a groupcast frame (possibly after a DTIM) on the given link.
void DoNotifyPmModeChanged(WifiPowerManagementMode pmMode, linkId_t linkId) override
Notify subclasses that the Power Management mode of the non-AP STA operating on the given link has ch...
DefaultPowerSaveManager()
void DoNotifyAssocCompleted() override
Notify subclasses that the non-AP STA/MLD has completed association with an AP.
void DoNotifyReceivedBeacon(const MgtBeaconHeader &beacon, linkId_t linkId) override
Notify subclasses that a Beacon frame has been received from the associated AP on the given link.
void GoToSleepIfPossible(linkId_t linkId)
Put the PHY operating on the given link to sleep, if no reason to stay awake.
void DoTxDropped(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu) override
Notify subclasses that the given MPDU has been discarded for the given reason.
static TypeId GetTypeId()
Get the type ID.
void DoNotifyChannelReleased(Ptr< Txop > txop, linkId_t linkId) override
Notify subclasses that the given TXOP is releasing the channel on the given link.
~DefaultPowerSaveManager() override
Time m_psmTimeout
the extra time during which the PHY is kept in active state before being put to sleep state
PowerSaveManager is an abstract base class.
Ptr< StaWifiMac > GetStaMac() const
uint32_t GetListenInterval() const
StaInfo & GetStaInfo(linkId_t linkId)
Get the information about the STA operating on the given link.
bool HasRequestedOrGainedChannel(linkId_t linkId) const
Get whether any Access Category has requested (or gained) the channel on the given link.
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.
Simulation virtual time values and global simulation resolution.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
void ResumeFromSleep()
Resume from sleep mode.
#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 > 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_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_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#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.
WifiMacDropReason
The reason why an MPDU was dropped.
WifiPowerManagementMode
Enumeration for power management modes.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t linkId_t
IEEE 802.11be D7.0 Figure 9-207e—Link ID Info field format.
bool pendingUnicast
AP has buffered unicast frame(s) (set from last TIM and updated as frames are received from the AP).