A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
parf-wifi-manager.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 Universidad de la República - Uruguay
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Matias Richart <mrichart@fing.edu.uy>
7 */
8
9#include "parf-wifi-manager.h"
10
11#include "ns3/data-rate.h"
12#include "ns3/log.h"
13#include "ns3/uinteger.h"
14#include "ns3/wifi-phy.h"
15
16namespace ns3
17{
18
19NS_LOG_COMPONENT_DEFINE("ParfWifiManager");
20
21/**
22 * Hold per-remote-station state for PARF Wifi manager.
23 *
24 * This struct extends from WifiRemoteStation struct to hold additional
25 * information required by the PARF Wifi manager
26 */
28{
29 uint32_t m_nAttempt; //!< Number of transmission attempts.
30 uint32_t m_nSuccess; //!< Number of successful transmission attempts.
31 uint32_t m_nFail; //!< Number of failed transmission attempts.
32 bool m_usingRecoveryRate; //!< If using recovery rate.
33 bool m_usingRecoveryPower; //!< If using recovery power.
34 uint32_t m_nRetry; //!< Number of transmission retries.
35 uint8_t m_prevRateIndex; //!< Rate index of the previous transmission.
36 uint8_t m_rateIndex; //!< Current rate index used by the remote station.
37 uint8_t m_prevPowerLevel; //!< Power level of the previous transmission.
38 uint8_t m_powerLevel; //!< Current power level used by the remote station.
39 uint8_t m_nSupported; //!< Number of supported rates by the remote station.
40 bool m_initialized; //!< For initializing variables.
41};
42
44
47{
48 static TypeId tid =
49 TypeId("ns3::ParfWifiManager")
51 .SetGroupName("Wifi")
52 .AddConstructor<ParfWifiManager>()
53 .AddAttribute("AttemptThreshold",
54 "The minimum number of transmission attempts to try a new power or rate.",
55 UintegerValue(15),
58 .AddAttribute(
59 "SuccessThreshold",
60 "The minimum number of successful transmissions to try a new power or rate.",
61 UintegerValue(10),
64 .AddTraceSource("PowerChange",
65 "The transmission power has change",
67 "ns3::WifiRemoteStationManager::PowerChangeTracedCallback")
68 .AddTraceSource("RateChange",
69 "The transmission rate has change",
71 "ns3::WifiRemoteStationManager::RateChangeTracedCallback");
72 return tid;
73}
74
79
84
85void
87{
88 NS_LOG_FUNCTION(this << phy);
89 m_minPower = 0;
90 m_maxPower = phy->GetNTxPower() - 1;
92}
93
94void
96{
97 NS_LOG_FUNCTION(this);
98 if (GetHtSupported())
99 {
100 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HT rates");
101 }
102 if (GetVhtSupported())
103 {
104 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support VHT rates");
105 }
106 if (GetHeSupported())
107 {
108 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HE rates");
109 }
110}
111
114{
115 NS_LOG_FUNCTION(this);
116 auto station = new ParfWifiRemoteStation();
117
118 station->m_nSuccess = 0;
119 station->m_nFail = 0;
120 station->m_usingRecoveryRate = false;
121 station->m_usingRecoveryPower = false;
122 station->m_initialized = false;
123 station->m_nRetry = 0;
124 station->m_nAttempt = 0;
125
126 NS_LOG_DEBUG("create station=" << station << ", timer=" << station->m_nAttempt
127 << ", rate=" << +station->m_rateIndex
128 << ", power=" << +station->m_powerLevel);
129
130 return station;
131}
132
133void
135{
136 if (!station->m_initialized)
137 {
138 station->m_nSupported = GetNSupported(station);
139 station->m_rateIndex = station->m_nSupported - 1;
140 station->m_prevRateIndex = station->m_nSupported - 1;
141 station->m_powerLevel = m_maxPower;
142 station->m_prevPowerLevel = m_maxPower;
143 WifiMode mode = GetSupported(station, station->m_rateIndex);
144 auto channelWidth = GetChannelWidth(station);
145 DataRate rate(mode.GetDataRate(channelWidth));
146 const auto power = GetPhy()->GetPower(m_maxPower);
147 m_powerChange(power, power, station->m_state->m_address);
148 m_rateChange(rate, rate, station->m_state->m_address);
149 station->m_initialized = true;
150 }
151}
152
153void
158
159/*
160 * It is important to realize that "recovery" mode starts after failure of
161 * the first transmission after a rate increase and ends at the first successful
162 * transmission. Specifically, recovery mode spans retransmissions boundaries.
163 * Fundamentally, ARF handles each data transmission independently, whether it
164 * is the initial transmission of a packet or the retransmission of a packet.
165 * The fundamental reason for this is that there is a backoff between each data
166 * transmission, be it an initial transmission or a retransmission.
167 */
168void
170{
171 NS_LOG_FUNCTION(this << st);
172 auto station = static_cast<ParfWifiRemoteStation*>(st);
173 CheckInit(station);
174 station->m_nAttempt++;
175 station->m_nFail++;
176 station->m_nRetry++;
177 station->m_nSuccess = 0;
178
179 NS_LOG_DEBUG("station=" << station << " data fail retry=" << station->m_nRetry << ", timer="
180 << station->m_nAttempt << ", rate=" << +station->m_rateIndex
181 << ", power=" << +station->m_powerLevel);
182 if (station->m_usingRecoveryRate)
183 {
184 NS_ASSERT(station->m_nRetry >= 1);
185 if (station->m_nRetry == 1)
186 {
187 // need recovery fallback
188 if (station->m_rateIndex != 0)
189 {
190 NS_LOG_DEBUG("station=" << station << " dec rate");
191 station->m_rateIndex--;
192 station->m_usingRecoveryRate = false;
193 }
194 }
195 station->m_nAttempt = 0;
196 }
197 else if (station->m_usingRecoveryPower)
198 {
199 NS_ASSERT(station->m_nRetry >= 1);
200 if (station->m_nRetry == 1)
201 {
202 // need recovery fallback
203 if (station->m_powerLevel < m_maxPower)
204 {
205 NS_LOG_DEBUG("station=" << station << " inc power");
206 station->m_powerLevel++;
207 station->m_usingRecoveryPower = false;
208 }
209 }
210 station->m_nAttempt = 0;
211 }
212 else
213 {
214 NS_ASSERT(station->m_nRetry >= 1);
215 if (((station->m_nRetry - 1) % 2) == 1)
216 {
217 // need normal fallback
218 if (station->m_powerLevel == m_maxPower)
219 {
220 if (station->m_rateIndex != 0)
221 {
222 NS_LOG_DEBUG("station=" << station << " dec rate");
223 station->m_rateIndex--;
224 }
225 }
226 else
227 {
228 NS_LOG_DEBUG("station=" << station << " inc power");
229 station->m_powerLevel++;
230 }
231 }
232 if (station->m_nRetry >= 2)
233 {
234 station->m_nAttempt = 0;
235 }
236 }
237}
238
239void
241{
242 NS_LOG_FUNCTION(this << station << rxSnr << txMode);
243}
244
245void
247 double ctsSnr,
248 WifiMode ctsMode,
249 double rtsSnr)
250{
251 NS_LOG_FUNCTION(this << station << ctsSnr << ctsMode << rtsSnr);
252}
253
254void
256 double ackSnr,
257 WifiMode ackMode,
258 double dataSnr,
259 MHz_u dataChannelWidth,
260 uint8_t dataNss)
261{
262 NS_LOG_FUNCTION(this << st << ackSnr << ackMode << dataSnr << dataChannelWidth << +dataNss);
263 auto station = static_cast<ParfWifiRemoteStation*>(st);
264 CheckInit(station);
265 station->m_nAttempt++;
266 station->m_nSuccess++;
267 station->m_nFail = 0;
268 station->m_usingRecoveryRate = false;
269 station->m_usingRecoveryPower = false;
270 station->m_nRetry = 0;
271 NS_LOG_DEBUG("station=" << station << " data ok success=" << station->m_nSuccess << ", timer="
272 << station->m_nAttempt << ", rate=" << +station->m_rateIndex
273 << ", power=" << +station->m_powerLevel);
274 if ((station->m_nSuccess == m_successThreshold || station->m_nAttempt == m_attemptThreshold) &&
275 (station->m_rateIndex < (station->m_state->m_operationalRateSet.size() - 1)))
276 {
277 NS_LOG_DEBUG("station=" << station << " inc rate");
278 station->m_rateIndex++;
279 station->m_nAttempt = 0;
280 station->m_nSuccess = 0;
281 station->m_usingRecoveryRate = true;
282 }
283 else if (station->m_nSuccess == m_successThreshold || station->m_nAttempt == m_attemptThreshold)
284 {
285 // we are at the maximum rate, we decrease power
286 if (station->m_powerLevel != m_minPower)
287 {
288 NS_LOG_DEBUG("station=" << station << " dec power");
289 station->m_powerLevel--;
290 }
291 station->m_nAttempt = 0;
292 station->m_nSuccess = 0;
293 station->m_usingRecoveryPower = true;
294 }
295}
296
297void
302
303void
308
311{
312 NS_LOG_FUNCTION(this << st << allowedWidth);
313 auto station = static_cast<ParfWifiRemoteStation*>(st);
314 auto channelWidth = GetChannelWidth(station);
315 if (channelWidth > MHz_u{20} && channelWidth != MHz_u{22})
316 {
317 channelWidth = MHz_u{20};
318 }
319 CheckInit(station);
320 WifiMode mode = GetSupported(station, station->m_rateIndex);
321 DataRate rate(mode.GetDataRate(channelWidth));
322 DataRate prevRate(GetSupported(station, station->m_prevRateIndex).GetDataRate(channelWidth));
323 const auto power = GetPhy()->GetPower(station->m_powerLevel);
324 const auto prevPower = GetPhy()->GetPower(station->m_prevPowerLevel);
325 if (station->m_prevPowerLevel != station->m_powerLevel)
326 {
327 m_powerChange(prevPower, power, station->m_state->m_address);
328 station->m_prevPowerLevel = station->m_powerLevel;
329 }
330 if (station->m_prevRateIndex != station->m_rateIndex)
331 {
332 m_rateChange(prevRate, rate, station->m_state->m_address);
333 station->m_prevRateIndex = station->m_rateIndex;
334 }
335 return WifiTxVector(
336 mode,
337 station->m_powerLevel,
339 NanoSeconds(800),
340 1,
341 1,
342 0,
343 channelWidth,
344 GetAggregation(station));
345}
346
349{
350 NS_LOG_FUNCTION(this << st);
351 /// @todo we could/should implement the ARF algorithm for
352 /// RTS only by picking a single rate within the BasicRateSet.
353 auto station = static_cast<ParfWifiRemoteStation*>(st);
354 auto channelWidth = GetChannelWidth(station);
355 if (channelWidth > MHz_u{20} && channelWidth != MHz_u{22})
356 {
357 channelWidth = MHz_u{20};
358 }
359 WifiMode mode;
361 {
362 mode = GetSupported(station, 0);
363 }
364 else
365 {
366 mode = GetNonErpSupported(station, 0);
367 }
368 return WifiTxVector(
369 mode,
372 NanoSeconds(800),
373 1,
374 1,
375 0,
376 channelWidth,
377 GetAggregation(station));
378}
379
380} // namespace ns3
Class for representing data rates.
Definition data-rate.h:78
PARF Rate control algorithm.
WifiTxVector DoGetDataTxVector(WifiRemoteStation *station, MHz_u allowedWidth) override
void DoReportFinalRtsFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
uint32_t m_successThreshold
The minimum number of successful transmissions to try a new power or rate.
void CheckInit(ParfWifiRemoteStation *station)
Check for initializations.
TracedCallback< double, double, Mac48Address > m_powerChange
The trace source fired when the transmission power changes.
void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode) override
This method is a pure virtual method that must be implemented by the sub-class.
void DoReportDataOk(WifiRemoteStation *station, double ackSnr, WifiMode ackMode, double dataSnr, MHz_u dataChannelWidth, uint8_t dataNss) override
This method is a pure virtual method that must be implemented by the sub-class.
TracedCallback< DataRate, DataRate, Mac48Address > m_rateChange
The trace source fired when the transmission rate changes.
void DoReportRtsOk(WifiRemoteStation *station, double ctsSnr, WifiMode ctsMode, double rtsSnr) override
This method is a pure virtual method that must be implemented by the sub-class.
void DoReportRtsFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
void DoReportDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
uint32_t m_attemptThreshold
The minimum number of transmission attempts to try a new power or rate.
void SetupPhy(const Ptr< WifiPhy > phy) override
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
uint8_t m_maxPower
Maximal power level.
WifiRemoteStation * DoCreateStation() const override
static TypeId GetTypeId()
Register this type.
uint8_t m_minPower
Minimal power level.
WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station) override
void DoInitialize() override
Initialize() implementation.
void DoReportFinalDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
represent a single transmission mode
Definition wifi-mode.h:38
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:172
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:110
uint8_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
Ptr< WifiPhy > GetPhy() const
Return the WifiPhy.
MHz_u GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
bool GetAggregation(const WifiRemoteStation *station) const
Return whether the given station supports A-MPDU.
bool GetHtSupported() const
Return whether the device has HT capability support enabled on the link this manager is associated wi...
WifiMode GetNonErpSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether non-ERP mode associated with the specified station at the specified index.
virtual void SetupPhy(const Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
bool GetUseNonErpProtection() const
Return whether the device supports protection of non-ERP stations.
bool GetVhtSupported() const
Return whether the device has VHT capability support enabled on the link this manager is associated w...
bool GetShortPreambleEnabled() const
Return whether the device uses short PHY preambles.
WifiMode GetSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether mode associated with the specified station at the specified index.
bool GetHeSupported() const
Return whether the device has HE capability support enabled.
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,...
Definition assert.h:55
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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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 NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1405
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double MHz_u
MHz weak type.
Definition wifi-units.h:31
WifiPreamble GetPreambleForTransmission(WifiModulationClass modulation, bool useShortPreamble)
Return the preamble to be used for the transmission.
Hold per-remote-station state for PARF Wifi manager.
uint32_t m_nRetry
Number of transmission retries.
bool m_usingRecoveryPower
If using recovery power.
uint32_t m_nFail
Number of failed transmission attempts.
bool m_usingRecoveryRate
If using recovery rate.
uint8_t m_rateIndex
Current rate index used by the remote station.
uint32_t m_nSuccess
Number of successful transmission attempts.
uint8_t m_prevRateIndex
Rate index of the previous transmission.
uint8_t m_powerLevel
Current power level used by the remote station.
uint8_t m_nSupported
Number of supported rates by the remote station.
bool m_initialized
For initializing variables.
uint8_t m_prevPowerLevel
Power level of the previous transmission.
uint32_t m_nAttempt
Number of transmission attempts.
hold per-remote-station state.
WifiRemoteStationState * m_state
Remote station state.
Mac48Address m_address
Mac48Address of the remote station.