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_maxPowerLevel = WIFI_MIN_TX_PWR_LEVEL + phy->GetNTxPowerLevels() - 1;
91}
92
93void
95{
96 NS_LOG_FUNCTION(this);
97 if (GetHtSupported())
98 {
99 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HT rates");
100 }
101 if (GetVhtSupported())
102 {
103 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support VHT rates");
104 }
105 if (GetHeSupported())
106 {
107 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HE rates");
108 }
109}
110
113{
114 NS_LOG_FUNCTION(this);
115 auto station = new ParfWifiRemoteStation();
116
117 station->m_nSuccess = 0;
118 station->m_nFail = 0;
119 station->m_usingRecoveryRate = false;
120 station->m_usingRecoveryPower = false;
121 station->m_initialized = false;
122 station->m_nRetry = 0;
123 station->m_nAttempt = 0;
124
125 NS_LOG_DEBUG("create station=" << station << ", timer=" << station->m_nAttempt
126 << ", rate=" << +station->m_rateIndex
127 << ", power=" << +station->m_powerLevel);
128
129 return station;
130}
131
132void
134{
135 if (!station->m_initialized)
136 {
137 station->m_nSupported = GetNSupported(station);
138 station->m_rateIndex = station->m_nSupported - 1;
139 station->m_prevRateIndex = station->m_nSupported - 1;
140 station->m_powerLevel = m_maxPowerLevel;
142 WifiMode mode = GetSupported(station, station->m_rateIndex);
143 auto channelWidth = GetChannelWidth(station);
144 DataRate rate(mode.GetDataRate(channelWidth));
145 const auto power = GetPhy()->GetPower(m_maxPowerLevel);
146 m_powerChange(power, power, station->m_state->m_address);
147 m_rateChange(rate, rate, station->m_state->m_address);
148 station->m_initialized = true;
149 }
150}
151
152void
157
158/*
159 * It is important to realize that "recovery" mode starts after failure of
160 * the first transmission after a rate increase and ends at the first successful
161 * transmission. Specifically, recovery mode spans retransmissions boundaries.
162 * Fundamentally, ARF handles each data transmission independently, whether it
163 * is the initial transmission of a packet or the retransmission of a packet.
164 * The fundamental reason for this is that there is a backoff between each data
165 * transmission, be it an initial transmission or a retransmission.
166 */
167void
169{
170 NS_LOG_FUNCTION(this << st);
171 auto station = static_cast<ParfWifiRemoteStation*>(st);
172 CheckInit(station);
173 station->m_nAttempt++;
174 station->m_nFail++;
175 station->m_nRetry++;
176 station->m_nSuccess = 0;
177
178 NS_LOG_DEBUG("station=" << station << " data fail retry=" << station->m_nRetry << ", timer="
179 << station->m_nAttempt << ", rate=" << +station->m_rateIndex
180 << ", power=" << +station->m_powerLevel);
181 if (station->m_usingRecoveryRate)
182 {
183 NS_ASSERT(station->m_nRetry >= 1);
184 if (station->m_nRetry == 1)
185 {
186 // need recovery fallback
187 if (station->m_rateIndex != 0)
188 {
189 NS_LOG_DEBUG("station=" << station << " dec rate");
190 station->m_rateIndex--;
191 station->m_usingRecoveryRate = false;
192 }
193 }
194 station->m_nAttempt = 0;
195 }
196 else if (station->m_usingRecoveryPower)
197 {
198 NS_ASSERT(station->m_nRetry >= 1);
199 if (station->m_nRetry == 1)
200 {
201 // need recovery fallback
202 if (station->m_powerLevel < m_maxPowerLevel)
203 {
204 NS_LOG_DEBUG("station=" << station << " inc power");
205 station->m_powerLevel++;
206 station->m_usingRecoveryPower = false;
207 }
208 }
209 station->m_nAttempt = 0;
210 }
211 else
212 {
213 NS_ASSERT(station->m_nRetry >= 1);
214 if (((station->m_nRetry - 1) % 2) == 1)
215 {
216 // need normal fallback
217 if (station->m_powerLevel == m_maxPowerLevel)
218 {
219 if (station->m_rateIndex != 0)
220 {
221 NS_LOG_DEBUG("station=" << station << " dec rate");
222 station->m_rateIndex--;
223 }
224 }
225 else
226 {
227 NS_LOG_DEBUG("station=" << station << " inc power");
228 station->m_powerLevel++;
229 }
230 }
231 if (station->m_nRetry >= 2)
232 {
233 station->m_nAttempt = 0;
234 }
235 }
236}
237
238void
240{
241 NS_LOG_FUNCTION(this << station << rxSnr << txMode);
242}
243
244void
246 double ctsSnr,
247 WifiMode ctsMode,
248 double rtsSnr)
249{
250 NS_LOG_FUNCTION(this << station << ctsSnr << ctsMode << rtsSnr);
251}
252
253void
255 double ackSnr,
256 WifiMode ackMode,
257 double dataSnr,
258 MHz_u dataChannelWidth,
259 uint8_t dataNss)
260{
261 NS_LOG_FUNCTION(this << st << ackSnr << ackMode << dataSnr << dataChannelWidth << +dataNss);
262 auto station = static_cast<ParfWifiRemoteStation*>(st);
263 CheckInit(station);
264 station->m_nAttempt++;
265 station->m_nSuccess++;
266 station->m_nFail = 0;
267 station->m_usingRecoveryRate = false;
268 station->m_usingRecoveryPower = false;
269 station->m_nRetry = 0;
270 NS_LOG_DEBUG("station=" << station << " data ok success=" << station->m_nSuccess << ", timer="
271 << station->m_nAttempt << ", rate=" << +station->m_rateIndex
272 << ", power=" << +station->m_powerLevel);
273 if ((station->m_nSuccess == m_successThreshold || station->m_nAttempt == m_attemptThreshold) &&
274 (station->m_rateIndex < (station->m_state->m_operationalRateSet.size() - 1)))
275 {
276 NS_LOG_DEBUG("station=" << station << " inc rate");
277 station->m_rateIndex++;
278 station->m_nAttempt = 0;
279 station->m_nSuccess = 0;
280 station->m_usingRecoveryRate = true;
281 }
282 else if (station->m_nSuccess == m_successThreshold || station->m_nAttempt == m_attemptThreshold)
283 {
284 // we are at the maximum rate, we decrease power
285 if (station->m_powerLevel != m_minPowerLevel)
286 {
287 NS_LOG_DEBUG("station=" << station << " dec power");
288 station->m_powerLevel--;
289 }
290 station->m_nAttempt = 0;
291 station->m_nSuccess = 0;
292 station->m_usingRecoveryPower = true;
293 }
294}
295
296void
301
302void
307
310{
311 NS_LOG_FUNCTION(this << st << allowedWidth);
312 auto station = static_cast<ParfWifiRemoteStation*>(st);
313 auto channelWidth = GetChannelWidth(station);
314 if (channelWidth > MHz_u{20} && channelWidth != MHz_u{22})
315 {
316 channelWidth = MHz_u{20};
317 }
318 CheckInit(station);
319 WifiMode mode = GetSupported(station, station->m_rateIndex);
320 DataRate rate(mode.GetDataRate(channelWidth));
321 DataRate prevRate(GetSupported(station, station->m_prevRateIndex).GetDataRate(channelWidth));
322 const auto power = GetPhy()->GetPower(station->m_powerLevel);
323 const auto prevPower = GetPhy()->GetPower(station->m_prevPowerLevel);
324 if (station->m_prevPowerLevel != station->m_powerLevel)
325 {
326 m_powerChange(prevPower, power, station->m_state->m_address);
327 station->m_prevPowerLevel = station->m_powerLevel;
328 }
329 if (station->m_prevRateIndex != station->m_rateIndex)
330 {
331 m_rateChange(prevRate, rate, station->m_state->m_address);
332 station->m_prevRateIndex = station->m_rateIndex;
333 }
334 return WifiTxVector(
335 mode,
336 station->m_powerLevel,
338 NanoSeconds(800),
339 1,
340 1,
341 0,
342 channelWidth,
343 GetAggregation(station));
344}
345
348{
349 NS_LOG_FUNCTION(this << st);
350 /// @todo we could/should implement the ARF algorithm for
351 /// RTS only by picking a single rate within the BasicRateSet.
352 auto station = static_cast<ParfWifiRemoteStation*>(st);
353 auto channelWidth = GetChannelWidth(station);
354 if (channelWidth > MHz_u{20} && channelWidth != MHz_u{22})
355 {
356 channelWidth = MHz_u{20};
357 }
358 WifiMode mode;
360 {
361 mode = GetSupported(station, 0);
362 }
363 else
364 {
365 mode = GetNonErpSupported(station, 0);
366 }
367 return WifiTxVector(
368 mode,
371 NanoSeconds(800),
372 1,
373 1,
374 0,
375 channelWidth,
376 GetAggregation(station));
377}
378
379} // 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.
uint8_t m_maxPowerLevel
Maximal power level.
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.
uint8_t m_minPowerLevel
Minimal power level.
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...
WifiRemoteStation * DoCreateStation() const override
static TypeId GetTypeId()
Register this type.
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.
static constexpr uint8_t WIFI_MIN_TX_PWR_LEVEL
minimum TX power level value
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.