A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
power-save-manager.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Universita' degli Studi di Napoli Federico II
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stavallo@unina.it>
7 */
8
10
11#include "mgt-headers.h"
12#include "sta-wifi-mac.h"
13#include "txop.h"
14#include "wifi-mac-queue.h"
15#include "wifi-mpdu.h"
16#include "wifi-phy.h"
17
18#include "ns3/attribute-container.h"
19#include "ns3/boolean.h"
20#include "ns3/log.h"
21#include "ns3/pair.h"
22#include "ns3/uinteger.h"
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("PowerSaveManager");
28
30
33{
34 static TypeId tid =
35 TypeId("ns3::PowerSaveManager")
37 .SetGroupName("Wifi")
38 .AddAttribute(
39 "PowerSaveMode",
40 "Enable/disable power save mode on the given links. If a string is used to "
41 "set this attribute, the string must contain a comma-separated list of pairs, "
42 "where each pair is made of the link ID and a boolean value (indicating whether "
43 "to enable PS mode on that link), separated by a space. If this object is not "
44 "initialized yet when this attribute is set, the settings are stored and notified "
45 "to the STA wifi MAC upon initialization.",
46 StringValue(""),
52 .AddAttribute("ListenInterval",
53 "Interval (in beacon periods) between successive switches from sleep to "
54 "listen for a PS STAs",
58 .AddTraceSource(
59 "PmMode",
60 "Traces every change in the power management mode of the STAs affiliated with this "
61 "device. Provides the ID of the link on which the STA that changed power "
62 "management mode is operating and the new power management mode of the STA.",
64 "ns3::PowerSaveManager::PmModeChangeCallback");
65 return tid;
66}
67
72
73void
75{
76 NS_LOG_FUNCTION(this);
77
78 for (const auto& [linkId, enablePs] : m_linkIdEnableMap)
79 {
80 m_staMac->SetPowerSaveMode({enablePs, linkId});
81 }
82 m_linkIdEnableMap.clear();
83}
84
85void
87{
88 NS_LOG_FUNCTION(this);
89 m_staMac->TraceDisconnectWithoutContext("DroppedMpdu",
91 m_staMac = nullptr;
93}
94
95void
97{
98 NS_LOG_FUNCTION(this << mac);
99 m_staMac = mac;
100 m_staMac->TraceConnectWithoutContext("DroppedMpdu",
102}
103
106{
107 return m_staMac;
108}
109
115
118{
119 NS_ASSERT(m_staInfo.contains(linkId));
120 return m_staInfo.at(linkId);
121}
122
123bool
125{
126 const auto acList =
127 GetStaMac()->GetQosSupported() ? edcaAcIndices : std::list<AcIndex>{AC_BE_NQOS};
128
129 for (const auto aci : acList)
130 {
131 if (const auto status = GetStaMac()->GetTxopFor(aci)->GetAccessStatus(linkId);
132 status == Txop::REQUESTED || status == Txop::GRANTED)
133 {
134 return true;
135 }
136 }
137 return false;
138}
139
140void
141PowerSaveManager::SetPowerSaveMode(const std::map<linkId_t, bool>& linkIdEnableMap)
142{
143 for (const auto& [linkId, enablePs] : linkIdEnableMap)
144 {
145 if (m_staMac && m_staMac->IsInitialized())
146 {
147 m_staMac->SetPowerSaveMode({enablePs, linkId});
148 }
149 else
150 {
151 m_linkIdEnableMap[linkId] = enablePs;
152 }
153 }
154}
155
156void
158 const Time& timestamp,
159 linkId_t linkId)
160{
161 NS_LOG_FUNCTION(this << beaconInterval << timestamp << linkId);
162 m_staInfo[linkId] = {.beaconInterval = beaconInterval, .lastBeaconTimestamp = timestamp};
163}
164
165std::optional<Time>
167{
168 const auto staInfoIt = m_staInfo.find(linkId);
169
170 if ((staInfoIt == m_staInfo.cend()) || staInfoIt->second.beaconInterval.IsZero())
171 {
172 return std::nullopt;
173 }
174
175 const auto sinceLastTbtt = (Simulator::Now() - staInfoIt->second.lastBeaconTimestamp) %
176 staInfoIt->second.beaconInterval;
177
178 return sinceLastTbtt.IsZero() ? Time{0} : staInfoIt->second.beaconInterval - sinceLastTbtt;
179}
180
181void
183{
184 NS_LOG_FUNCTION(this);
185
186 const auto linkIds = m_staMac->GetSetupLinkIds();
187 for (const auto linkId : linkIds)
188 {
189 m_staInfo.try_emplace(linkId, StaInfo{});
190 }
191
193}
194
195void
197{
198 NS_LOG_FUNCTION(this);
199
200 m_staInfo.clear();
201 for (const auto linkId : m_staMac->GetLinkIds())
202 {
203 auto phy = m_staMac->GetWifiPhy(linkId);
204 if (phy && phy->IsStateSleep())
205 {
206 phy->ResumeFromSleep();
207 }
208 }
209
211}
212
213void
215{
216 NS_LOG_FUNCTION(this << pmMode << linkId);
217
219 {
220 auto phy = m_staMac->GetWifiPhy(linkId);
221 if (phy && phy->IsStateSleep())
222 {
223 phy->ResumeFromSleep();
224 }
225 }
226 m_pmModeLogger(linkId, pmMode);
227
228 DoNotifyPmModeChanged(pmMode, linkId);
229}
230
231void
233{
234 NS_LOG_FUNCTION(this << *mpdu << linkId);
235
236 NS_ASSERT(mpdu->GetHeader().IsBeacon());
237 NS_ASSERT(mpdu->GetHeader().GetAddr2() == m_staMac->GetBssid(linkId));
238
239 MgtBeaconHeader beacon;
240 mpdu->GetPacket()->PeekHeader(beacon);
241
242 auto& staInfo = GetStaInfo(linkId);
243 staInfo.beaconInterval = MicroSeconds(beacon.m_beaconInterval);
244 staInfo.lastBeaconTimestamp = MicroSeconds(beacon.GetTimestamp());
245
246 auto& tim = beacon.Get<Tim>();
247 staInfo.pendingUnicast = tim->HasAid(m_staMac->GetAssociationId());
248 staInfo.pendingGroupcast = tim->m_hasMulticastPending;
249
250 DoNotifyReceivedBeacon(beacon, linkId);
251}
252
253void
255{
256 NS_LOG_FUNCTION(this << *mpdu << linkId);
257
258 auto& staInfo = GetStaInfo(linkId);
259
260 if (!staInfo.pendingUnicast)
261 {
262 NS_LOG_DEBUG("Not expecting a buffered unit on link " << +linkId);
263 return;
264 }
265
266 // use More Data flag
267 staInfo.pendingUnicast = mpdu->GetHeader().IsMoreData();
268
269 if (GetStaMac()->GetPmMode(linkId) == WIFI_PM_POWERSAVE)
270 {
271 // The PS-Poll is dequeued when the Ack transmission starts. In order to avoid that the STA
272 // is not put to sleep because a frame (the PS-Poll) is queued, notify subclasses after
273 // that the Ack transmission has started.
274 Simulator::Schedule(m_staMac->GetWifiPhy(linkId)->GetSifs() + TimeStep(1),
276 this,
277 mpdu,
278 linkId);
279 }
280}
281
282void
284{
285 NS_LOG_FUNCTION(this << *mpdu << linkId);
286
287 auto& staInfo = GetStaInfo(linkId);
288
289 if (!staInfo.pendingGroupcast)
290 {
291 NS_LOG_DEBUG("Not expecting a group addressed frame on link " << +linkId);
292 return;
293 }
294
295 // use More Data flag
296 staInfo.pendingGroupcast = mpdu->GetHeader().IsMoreData();
297
298 if (GetStaMac()->GetPmMode(linkId) == WIFI_PM_POWERSAVE)
299 {
300 DoNotifyReceivedGroupcast(mpdu, linkId);
301 }
302}
303
304void
306{
307 NS_LOG_FUNCTION(this << txop << linkId);
308
309 DoNotifyRequestAccess(txop, linkId);
310}
311
312void
314{
315 NS_LOG_FUNCTION(this << txop << linkId);
316
317 DoNotifyChannelReleased(txop, linkId);
318}
319
320void
322{
323 NS_LOG_FUNCTION(this << reason << *mpdu);
324
325 // make sure the PS Poll is not in the queue, which could prevent the STA from going to sleep
326 if (mpdu->GetHeader().IsPsPoll() && mpdu->IsQueued())
327 {
328 GetStaMac()->GetTxopQueue(mpdu->GetQueueAc())->DequeueIfQueued({mpdu});
329 }
330
331 DoTxDropped(reason, mpdu);
332}
333
334} // namespace ns3
Implement the header for management frames of type beacon.
uint64_t m_beaconInterval
Beacon interval (microseconds).
uint64_t GetTimestamp() const
Object()
Caller graph was not generated because of its size.
Definition object.cc:93
virtual void DoDispose()
Destructor implementation.
Definition object.cc:430
AttributeValue implementation for Pair.
Definition pair.h:54
PowerSaveManager is an abstract base class.
void NotifyPmModeChanged(WifiPowerManagementMode pmMode, linkId_t linkId)
Notify that the Power Management mode of the non-AP STA operating on the given link has changed.
Ptr< StaWifiMac > m_staMac
MAC which is using this Power Save Manager.
Ptr< StaWifiMac > GetStaMac() const
void DoDispose() override
Destructor implementation.
TracedCallback< linkId_t, WifiPowerManagementMode > m_pmModeLogger
link ID-indexed power management mode logger
virtual void DoNotifyRequestAccess(Ptr< Txop > txop, linkId_t linkId)=0
Notify subclasses that the given TXOP is requesting channel access on the given link.
uint32_t GetListenInterval() const
virtual void DoNotifyDisassociation()=0
Notify subclasses that the non-AP STA/MLD has disassociated.
StaInfo & GetStaInfo(linkId_t linkId)
Get the information about the STA operating on the given link.
std::map< linkId_t, bool > m_linkIdEnableMap
a link ID-indexed map indicating whether to enable or not power save mode on the link with the given ...
virtual void DoNotifyReceivedFrameAfterPsPoll(Ptr< const WifiMpdu > mpdu, linkId_t linkId)=0
Notify subclasses of the reception of a frame in response to a PS-Poll frame on the given link.
void NotifyAssocCompleted()
Notify that the non-AP STA/MLD has completed association with an AP.
void NotifyReceivedFrameAfterPsPoll(Ptr< const WifiMpdu > mpdu, linkId_t linkId)
Notify the reception of a frame in response to a PS-Poll frame on the given link.
void DoInitialize() override
Initialize() implementation.
virtual void DoNotifyPmModeChanged(WifiPowerManagementMode pmMode, linkId_t linkId)=0
Notify subclasses that the Power Management mode of the non-AP STA operating on the given link has ch...
bool HasRequestedOrGainedChannel(linkId_t linkId) const
Get whether any Access Category has requested (or gained) the channel on the given link.
void TxDropped(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Notify that the given MPDU has been discarded for the given reason.
void NotifyReceivedGroupcast(Ptr< const WifiMpdu > mpdu, linkId_t linkId)
Notify the reception of a groupcast frame (possibly after a DTIM) on the given link.
void SetPowerSaveMode(const std::map< linkId_t, bool > &linkIdEnableMap)
Enable or disable Power Save mode on a given set of links.
void NotifyChannelReleased(Ptr< Txop > txop, linkId_t linkId)
Notify that the given TXOP has released the channel on the given link.
void NotifyRequestAccess(Ptr< Txop > txop, linkId_t linkId)
Notify that the given TXOP is requesting channel access on the given link.
uint32_t m_listenInterval
beacon listen interval
std::optional< Time > GetTimeUntilNextTbtt(linkId_t linkId) const
static TypeId GetTypeId()
Get the type ID.
virtual void DoNotifyAssocCompleted()=0
Notify subclasses that the non-AP STA/MLD has completed association with an AP.
virtual void DoNotifyReceivedBeacon(const MgtBeaconHeader &beacon, linkId_t linkId)=0
Notify subclasses that a Beacon frame has been received from the associated AP on the given link.
std::map< linkId_t, StaInfo > m_staInfo
link ID-indexed map of STA infos
virtual void DoTxDropped(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)=0
Notify subclasses that the given MPDU has been discarded for the given reason.
virtual void DoNotifyChannelReleased(Ptr< Txop > txop, linkId_t linkId)=0
Notify subclasses that the given TXOP is releasing the channel on the given link.
virtual void DoNotifyReceivedGroupcast(Ptr< const WifiMpdu > mpdu, linkId_t linkId)=0
Notify subclasses of the reception of a groupcast frame (possibly after a DTIM) on the given link.
void NotifyBeaconIntervalAndTimestamp(const Time &beaconInterval, const Time &timestamp, linkId_t linkId)
This function is normally used to notify the Beacon interval and timestamp included in the last Beaco...
void SetWifiMac(Ptr< StaWifiMac > mac)
Set the MAC which is using this Power Save Manager.
void NotifyReceivedBeacon(Ptr< const WifiMpdu > mpdu, linkId_t linkId)
Notify that a Beacon frame has been received from the associated AP on the given link.
void NotifyDisassociation()
Notify that the non-AP STA/MLD has disassociated.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
Hold variables of type string.
Definition string.h:45
The Traffic Indication Map Information Element.
Definition tim.h:29
bool HasAid(uint16_t aid) const
Check whether the bit corresponding to the provided AID is set in the Virtual Bitmap included in this...
Definition tim.cc:48
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
Time TimeStep(uint64_t ts)
Scheduler interface.
Definition nstime.h:1370
@ GRANTED
Definition txop.h:79
@ REQUESTED
Definition txop.h:78
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
Ptr< AttributeChecker > MakeAttributeContainerChecker(const AttributeContainerValue< A, Sep, C > &value)
Make AttributeContainerChecker from AttributeContainerValue.
Ptr< const AttributeAccessor > MakeAttributeContainerAccessor(T1 a1)
Make AttributeContainerAccessor using explicit types.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< AttributeChecker > MakePairChecker(const PairValue< A, B > &value)
Make a PairChecker from a PairValue.
Definition pair.h:272
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
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...
Definition callback.h:690
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#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.
Definition object-base.h:35
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1307
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
WifiMacDropReason
The reason why an MPDU was dropped.
Definition wifi-mac.h:71
WifiPowerManagementMode
Enumeration for power management modes.
@ WIFI_PM_POWERSAVE
@ WIFI_PM_ACTIVE
@ AC_BE_NQOS
Non-QoS.
Definition qos-utils.h:74
Every class exported by the ns3 library is enclosed in the ns3 namespace.
const std::list< AcIndex > edcaAcIndices
List of the Access Categories corresponding to the four EDCA functions.
Definition qos-utils.h:203
uint8_t linkId_t
IEEE 802.11be D7.0 Figure 9-207e—Link ID Info field format.
Definition wifi-utils.h:74
Information about each STA operating on a given link.