A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
amrr-wifi-manager.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003,2007 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "amrr-wifi-manager.h"
10
11#include "ns3/log.h"
12#include "ns3/simulator.h"
13#include "ns3/wifi-tx-vector.h"
14
15namespace ns3
16{
17
18NS_LOG_COMPONENT_DEFINE("AmrrWifiManager");
19
20/**
21 * @brief hold per-remote-station state for AMRR Wifi manager.
22 *
23 * This struct extends from WifiRemoteStation struct to hold additional
24 * information required by the AMRR Wifi manager
25 */
27{
28 Time m_nextModeUpdate; ///< next mode update time
29 uint32_t m_tx_ok; ///< transmit OK
30 uint32_t m_tx_err; ///< transmit error
31 uint32_t m_tx_retr; ///< transmit retry
32 uint32_t m_retry; ///< retry
33 uint8_t m_txrate; ///< transmit rate
34 uint32_t m_successThreshold; ///< success threshold
35 uint32_t m_success; ///< success
36 bool m_recovery; ///< recovery
37};
38
40
43{
44 static TypeId tid =
45 TypeId("ns3::AmrrWifiManager")
47 .SetGroupName("Wifi")
48 .AddConstructor<AmrrWifiManager>()
49 .AddAttribute("UpdatePeriod",
50 "The interval between decisions about rate control changes",
54 .AddAttribute(
55 "FailureRatio",
56 "Ratio of minimum erroneous transmissions needed to switch to a lower rate",
57 DoubleValue(1.0 / 3.0),
60 .AddAttribute(
61 "SuccessRatio",
62 "Ratio of maximum erroneous transmissions needed to switch to a higher rate",
63 DoubleValue(1.0 / 10.0),
66 .AddAttribute(
67 "MaxSuccessThreshold",
68 "Maximum number of consecutive success periods needed to switch to a higher rate",
69 UintegerValue(10),
72 .AddAttribute(
73 "MinSuccessThreshold",
74 "Minimum number of consecutive success periods needed to switch to a higher rate",
78 .AddTraceSource("Rate",
79 "Traced value for rate changes (b/s)",
81 "ns3::TracedValueCallback::Uint64");
82 return tid;
83}
84
91
96
97void
99{
100 NS_LOG_FUNCTION(this);
101 if (GetHtSupported())
102 {
103 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HT rates");
104 }
105 if (GetVhtSupported())
106 {
107 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support VHT rates");
108 }
109 if (GetHeSupported())
110 {
111 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HE rates");
112 }
113}
114
117{
118 NS_LOG_FUNCTION(this);
119 auto station = new AmrrWifiRemoteStation();
120 station->m_nextModeUpdate = Simulator::Now() + m_updatePeriod;
121 station->m_tx_ok = 0;
122 station->m_tx_err = 0;
123 station->m_tx_retr = 0;
124 station->m_retry = 0;
125 station->m_txrate = 0;
126 station->m_successThreshold = m_minSuccessThreshold;
127 station->m_success = 0;
128 station->m_recovery = false;
129 return station;
130}
131
132void
134{
135 NS_LOG_FUNCTION(this << station << rxSnr << txMode);
136}
137
138void
143
144void
146{
147 NS_LOG_FUNCTION(this << st);
148 auto station = static_cast<AmrrWifiRemoteStation*>(st);
149 station->m_retry++;
150 station->m_tx_retr++;
151}
152
153void
155 double ctsSnr,
156 WifiMode ctsMode,
157 double rtsSnr)
158{
159 NS_LOG_FUNCTION(this << st << ctsSnr << ctsMode << rtsSnr);
160}
161
162void
164 double ackSnr,
165 WifiMode ackMode,
166 double dataSnr,
167 MHz_u dataChannelWidth,
168 uint8_t dataNss)
169{
170 NS_LOG_FUNCTION(this << st << ackSnr << ackMode << dataSnr << dataChannelWidth << +dataNss);
171 auto station = static_cast<AmrrWifiRemoteStation*>(st);
172 station->m_retry = 0;
173 station->m_tx_ok++;
174}
175
176void
181
182void
184{
185 NS_LOG_FUNCTION(this << st);
186 auto station = static_cast<AmrrWifiRemoteStation*>(st);
187 station->m_retry = 0;
188 station->m_tx_err++;
189}
190
191bool
193{
194 NS_LOG_FUNCTION(this << station);
195 return (station->m_txrate == 0);
196}
197
198bool
200{
201 NS_LOG_FUNCTION(this << station);
202 NS_ASSERT(station->m_txrate + 1 <= GetNSupported(station));
203 return (station->m_txrate + 1 == GetNSupported(station));
204}
205
206bool
208{
209 NS_LOG_FUNCTION(this << station);
210 return (station->m_tx_retr + station->m_tx_err) < station->m_tx_ok * m_successRatio;
211}
212
213bool
215{
216 NS_LOG_FUNCTION(this << station);
217 return (station->m_tx_retr + station->m_tx_err) > station->m_tx_ok * m_failureRatio;
218}
219
220bool
222{
223 NS_LOG_FUNCTION(this << station);
224 return (station->m_tx_retr + station->m_tx_err + station->m_tx_ok) > 10;
225}
226
227void
229{
230 NS_LOG_FUNCTION(this << station);
231 station->m_tx_ok = 0;
232 station->m_tx_err = 0;
233 station->m_tx_retr = 0;
234}
235
236void
238{
239 NS_LOG_FUNCTION(this << station);
240 station->m_txrate++;
241 NS_ASSERT(station->m_txrate < GetNSupported(station));
242}
243
244void
246{
247 NS_LOG_FUNCTION(this << station);
248 station->m_txrate--;
249}
250
251void
253{
254 NS_LOG_FUNCTION(this << station);
255 if (Simulator::Now() < station->m_nextModeUpdate)
256 {
257 return;
258 }
260 NS_LOG_DEBUG("Update");
261
262 bool needChange = false;
263
264 if (IsSuccess(station) && IsEnough(station))
265 {
266 station->m_success++;
267 NS_LOG_DEBUG("++ success="
268 << station->m_success << " successThreshold=" << station->m_successThreshold
269 << " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err
270 << " tx_retr=" << station->m_tx_retr << " rate=" << +station->m_txrate
271 << " n-supported-rates=" << +GetNSupported(station));
272 if (station->m_success >= station->m_successThreshold && !IsMaxRate(station))
273 {
274 station->m_recovery = true;
275 station->m_success = 0;
276 IncreaseRate(station);
277 needChange = true;
278 }
279 else
280 {
281 station->m_recovery = false;
282 }
283 }
284 else if (IsFailure(station))
285 {
286 station->m_success = 0;
287 NS_LOG_DEBUG("-- success="
288 << station->m_success << " successThreshold=" << station->m_successThreshold
289 << " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err
290 << " tx_retr=" << station->m_tx_retr << " rate=" << +station->m_txrate
291 << " n-supported-rates=" << +GetNSupported(station));
292 if (!IsMinRate(station))
293 {
294 if (station->m_recovery)
295 {
296 station->m_successThreshold *= 2;
297 station->m_successThreshold =
298 std::min(station->m_successThreshold, m_maxSuccessThreshold);
299 }
300 else
301 {
303 }
304 station->m_recovery = false;
305 DecreaseRate(station);
306 needChange = true;
307 }
308 else
309 {
310 station->m_recovery = false;
311 }
312 }
313 if (IsEnough(station) || needChange)
314 {
315 NS_LOG_DEBUG("Reset");
316 ResetCnt(station);
317 }
318}
319
322{
323 NS_LOG_FUNCTION(this << st << allowedWidth);
324 auto station = static_cast<AmrrWifiRemoteStation*>(st);
325 UpdateMode(station);
326 NS_ASSERT(station->m_txrate < GetNSupported(station));
327 uint8_t rateIndex;
328 if (station->m_retry < 1)
329 {
330 rateIndex = station->m_txrate;
331 }
332 else if (station->m_retry < 2)
333 {
334 if (station->m_txrate > 0)
335 {
336 rateIndex = station->m_txrate - 1;
337 }
338 else
339 {
340 rateIndex = station->m_txrate;
341 }
342 }
343 else if (station->m_retry < 3)
344 {
345 if (station->m_txrate > 1)
346 {
347 rateIndex = station->m_txrate - 2;
348 }
349 else
350 {
351 rateIndex = station->m_txrate;
352 }
353 }
354 else
355 {
356 if (station->m_txrate > 2)
357 {
358 rateIndex = station->m_txrate - 3;
359 }
360 else
361 {
362 rateIndex = station->m_txrate;
363 }
364 }
365 auto channelWidth = GetChannelWidth(station);
366 if (channelWidth > MHz_u{20} && channelWidth != MHz_u{22})
367 {
368 channelWidth = MHz_u{20};
369 }
370 WifiMode mode = GetSupported(station, rateIndex);
371 uint64_t rate = mode.GetDataRate(channelWidth);
372 if (m_currentRate != rate)
373 {
374 NS_LOG_DEBUG("New datarate: " << rate);
375 m_currentRate = rate;
376 }
377 return WifiTxVector(
378 mode,
381 NanoSeconds(800),
382 1,
383 1,
384 0,
385 channelWidth,
386 GetAggregation(station));
387}
388
391{
392 NS_LOG_FUNCTION(this << st);
393 auto station = static_cast<AmrrWifiRemoteStation*>(st);
394 auto channelWidth = GetChannelWidth(station);
395 if (channelWidth > MHz_u{20} && channelWidth != MHz_u{22})
396 {
397 channelWidth = MHz_u{20};
398 }
399 UpdateMode(station);
400 WifiMode mode;
402 {
403 mode = GetSupported(station, 0);
404 }
405 else
406 {
407 mode = GetNonErpSupported(station, 0);
408 }
409 return WifiTxVector(
410 mode,
413 NanoSeconds(800),
414 1,
415 1,
416 0,
417 channelWidth,
418 GetAggregation(station));
419}
420
421} // namespace ns3
AMRR Rate control algorithm.
double m_failureRatio
failure ratio
static TypeId GetTypeId()
Get the type ID.
void UpdateMode(AmrrWifiRemoteStation *station)
Update the mode used to send to the given station.
void DoReportFinalRtsFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
uint32_t m_minSuccessThreshold
minimum success threshold
bool IsMaxRate(AmrrWifiRemoteStation *station) const
Check if the current rate for the given station is the maximum rate.
TracedValue< uint64_t > m_currentRate
Trace rate changes.
bool IsMinRate(AmrrWifiRemoteStation *station) const
Check if the current rate for the given station is the minimum rate.
void DoInitialize() override
Initialize() implementation.
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 ResetCnt(AmrrWifiRemoteStation *station)
Reset transmission statistics of the given station.
uint32_t m_maxSuccessThreshold
maximum success threshold
bool IsEnough(AmrrWifiRemoteStation *station) const
Check if the number of retransmission, transmission error, and successful transmission are greater th...
void DoReportRtsFailed(WifiRemoteStation *station) 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.
void DecreaseRate(AmrrWifiRemoteStation *station)
Decrease the transmission rate to the given station.
void DoReportFinalDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
bool IsSuccess(AmrrWifiRemoteStation *station) const
Check if the number of retransmission and transmission error is less than the number of successful tr...
WifiRemoteStation * DoCreateStation() const override
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 DoReportDataFailed(WifiRemoteStation *station) override
This method is a pure virtual method that must be implemented by the sub-class.
Time m_updatePeriod
update period
WifiTxVector DoGetDataTxVector(WifiRemoteStation *station, MHz_u allowedWidth) override
void IncreaseRate(AmrrWifiRemoteStation *station)
Increase the transmission rate to the given station.
WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station) override
bool IsFailure(AmrrWifiRemoteStation *station) const
Check if the number of retransmission and transmission error is greater than the number of successful...
double m_successRatio
success ratio
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
AttributeValue implementation for Time.
Definition nstime.h:1456
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.
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.
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 > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition double.h:32
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition nstime.h:1457
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1477
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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
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 AMRR Wifi manager.
uint8_t m_txrate
transmit rate
Time m_nextModeUpdate
next mode update time
uint32_t m_tx_err
transmit error
uint32_t m_tx_retr
transmit retry
uint32_t m_successThreshold
success threshold
hold per-remote-station state.