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
15#define Min(a, b) ((a < b) ? a : b)
16
17namespace ns3
18{
19
20NS_LOG_COMPONENT_DEFINE("AmrrWifiManager");
21
22/**
23 * \brief hold per-remote-station state for AMRR Wifi manager.
24 *
25 * This struct extends from WifiRemoteStation struct to hold additional
26 * information required by the AMRR Wifi manager
27 */
29{
30 Time m_nextModeUpdate; ///< next mode update time
31 uint32_t m_tx_ok; ///< transmit OK
32 uint32_t m_tx_err; ///< transmit error
33 uint32_t m_tx_retr; ///< transmit retry
34 uint32_t m_retry; ///< retry
35 uint8_t m_txrate; ///< transmit rate
36 uint32_t m_successThreshold; ///< success threshold
37 uint32_t m_success; ///< success
38 bool m_recovery; ///< recovery
39};
40
42
45{
46 static TypeId tid =
47 TypeId("ns3::AmrrWifiManager")
49 .SetGroupName("Wifi")
50 .AddConstructor<AmrrWifiManager>()
51 .AddAttribute("UpdatePeriod",
52 "The interval between decisions about rate control changes",
53 TimeValue(Seconds(1.0)),
56 .AddAttribute(
57 "FailureRatio",
58 "Ratio of minimum erroneous transmissions needed to switch to a lower rate",
59 DoubleValue(1.0 / 3.0),
62 .AddAttribute(
63 "SuccessRatio",
64 "Ratio of maximum erroneous transmissions needed to switch to a higher rate",
65 DoubleValue(1.0 / 10.0),
68 .AddAttribute(
69 "MaxSuccessThreshold",
70 "Maximum number of consecutive success periods needed to switch to a higher rate",
71 UintegerValue(10),
74 .AddAttribute(
75 "MinSuccessThreshold",
76 "Minimum number of consecutive success periods needed to switch to a higher rate",
80 .AddTraceSource("Rate",
81 "Traced value for rate changes (b/s)",
83 "ns3::TracedValueCallback::Uint64");
84 return tid;
85}
86
89 m_currentRate(0)
90{
91 NS_LOG_FUNCTION(this);
92}
93
98
99void
101{
102 NS_LOG_FUNCTION(this);
103 if (GetHtSupported())
104 {
105 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HT rates");
106 }
107 if (GetVhtSupported())
108 {
109 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support VHT rates");
110 }
111 if (GetHeSupported())
112 {
113 NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HE rates");
114 }
115}
116
119{
120 NS_LOG_FUNCTION(this);
121 auto station = new AmrrWifiRemoteStation();
122 station->m_nextModeUpdate = Simulator::Now() + m_updatePeriod;
123 station->m_tx_ok = 0;
124 station->m_tx_err = 0;
125 station->m_tx_retr = 0;
126 station->m_retry = 0;
127 station->m_txrate = 0;
128 station->m_successThreshold = m_minSuccessThreshold;
129 station->m_success = 0;
130 station->m_recovery = false;
131 return station;
132}
133
134void
136{
137 NS_LOG_FUNCTION(this << station << rxSnr << txMode);
138}
139
140void
145
146void
148{
149 NS_LOG_FUNCTION(this << st);
150 auto station = static_cast<AmrrWifiRemoteStation*>(st);
151 station->m_retry++;
152 station->m_tx_retr++;
153}
154
155void
157 double ctsSnr,
158 WifiMode ctsMode,
159 double rtsSnr)
160{
161 NS_LOG_FUNCTION(this << st << ctsSnr << ctsMode << rtsSnr);
162}
163
164void
166 double ackSnr,
167 WifiMode ackMode,
168 double dataSnr,
169 MHz_u dataChannelWidth,
170 uint8_t dataNss)
171{
172 NS_LOG_FUNCTION(this << st << ackSnr << ackMode << dataSnr << dataChannelWidth << +dataNss);
173 auto station = static_cast<AmrrWifiRemoteStation*>(st);
174 station->m_retry = 0;
175 station->m_tx_ok++;
176}
177
178void
183
184void
186{
187 NS_LOG_FUNCTION(this << st);
188 auto station = static_cast<AmrrWifiRemoteStation*>(st);
189 station->m_retry = 0;
190 station->m_tx_err++;
191}
192
193bool
195{
196 NS_LOG_FUNCTION(this << station);
197 return (station->m_txrate == 0);
198}
199
200bool
202{
203 NS_LOG_FUNCTION(this << station);
204 NS_ASSERT(station->m_txrate + 1 <= GetNSupported(station));
205 return (station->m_txrate + 1 == GetNSupported(station));
206}
207
208bool
210{
211 NS_LOG_FUNCTION(this << station);
212 return (station->m_tx_retr + station->m_tx_err) < station->m_tx_ok * m_successRatio;
213}
214
215bool
217{
218 NS_LOG_FUNCTION(this << station);
219 return (station->m_tx_retr + station->m_tx_err) > station->m_tx_ok * m_failureRatio;
220}
221
222bool
224{
225 NS_LOG_FUNCTION(this << station);
226 return (station->m_tx_retr + station->m_tx_err + station->m_tx_ok) > 10;
227}
228
229void
231{
232 NS_LOG_FUNCTION(this << station);
233 station->m_tx_ok = 0;
234 station->m_tx_err = 0;
235 station->m_tx_retr = 0;
236}
237
238void
240{
241 NS_LOG_FUNCTION(this << station);
242 station->m_txrate++;
243 NS_ASSERT(station->m_txrate < GetNSupported(station));
244}
245
246void
248{
249 NS_LOG_FUNCTION(this << station);
250 station->m_txrate--;
251}
252
253void
255{
256 NS_LOG_FUNCTION(this << station);
257 if (Simulator::Now() < station->m_nextModeUpdate)
258 {
259 return;
260 }
262 NS_LOG_DEBUG("Update");
263
264 bool needChange = false;
265
266 if (IsSuccess(station) && IsEnough(station))
267 {
268 station->m_success++;
269 NS_LOG_DEBUG("++ success="
270 << station->m_success << " successThreshold=" << station->m_successThreshold
271 << " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err
272 << " tx_retr=" << station->m_tx_retr << " rate=" << +station->m_txrate
273 << " n-supported-rates=" << +GetNSupported(station));
274 if (station->m_success >= station->m_successThreshold && !IsMaxRate(station))
275 {
276 station->m_recovery = true;
277 station->m_success = 0;
278 IncreaseRate(station);
279 needChange = true;
280 }
281 else
282 {
283 station->m_recovery = false;
284 }
285 }
286 else if (IsFailure(station))
287 {
288 station->m_success = 0;
289 NS_LOG_DEBUG("-- success="
290 << station->m_success << " successThreshold=" << station->m_successThreshold
291 << " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err
292 << " tx_retr=" << station->m_tx_retr << " rate=" << +station->m_txrate
293 << " n-supported-rates=" << +GetNSupported(station));
294 if (!IsMinRate(station))
295 {
296 if (station->m_recovery)
297 {
298 station->m_successThreshold *= 2;
299 station->m_successThreshold =
300 std::min(station->m_successThreshold, m_maxSuccessThreshold);
301 }
302 else
303 {
305 }
306 station->m_recovery = false;
307 DecreaseRate(station);
308 needChange = true;
309 }
310 else
311 {
312 station->m_recovery = false;
313 }
314 }
315 if (IsEnough(station) || needChange)
316 {
317 NS_LOG_DEBUG("Reset");
318 ResetCnt(station);
319 }
320}
321
324{
325 NS_LOG_FUNCTION(this << st << allowedWidth);
326 auto station = static_cast<AmrrWifiRemoteStation*>(st);
327 UpdateMode(station);
328 NS_ASSERT(station->m_txrate < GetNSupported(station));
329 uint8_t rateIndex;
330 if (station->m_retry < 1)
331 {
332 rateIndex = station->m_txrate;
333 }
334 else if (station->m_retry < 2)
335 {
336 if (station->m_txrate > 0)
337 {
338 rateIndex = station->m_txrate - 1;
339 }
340 else
341 {
342 rateIndex = station->m_txrate;
343 }
344 }
345 else if (station->m_retry < 3)
346 {
347 if (station->m_txrate > 1)
348 {
349 rateIndex = station->m_txrate - 2;
350 }
351 else
352 {
353 rateIndex = station->m_txrate;
354 }
355 }
356 else
357 {
358 if (station->m_txrate > 2)
359 {
360 rateIndex = station->m_txrate - 3;
361 }
362 else
363 {
364 rateIndex = station->m_txrate;
365 }
366 }
367 auto channelWidth = GetChannelWidth(station);
368 if (channelWidth > 20 && channelWidth != 22)
369 {
370 channelWidth = 20;
371 }
372 WifiMode mode = GetSupported(station, rateIndex);
373 uint64_t rate = mode.GetDataRate(channelWidth);
374 if (m_currentRate != rate)
375 {
376 NS_LOG_DEBUG("New datarate: " << rate);
377 m_currentRate = rate;
378 }
379 return WifiTxVector(
380 mode,
383 NanoSeconds(800),
384 1,
385 1,
386 0,
387 channelWidth,
388 GetAggregation(station));
389}
390
393{
394 NS_LOG_FUNCTION(this << st);
395 auto station = static_cast<AmrrWifiRemoteStation*>(st);
396 auto channelWidth = GetChannelWidth(station);
397 if (channelWidth > 20 && channelWidth != 22)
398 {
399 channelWidth = 20;
400 }
401 UpdateMode(station);
402 WifiMode mode;
404 {
405 mode = GetSupported(station, 0);
406 }
407 else
408 {
409 mode = GetNonErpSupported(station, 0);
410 }
411 return WifiTxVector(
412 mode,
415 NanoSeconds(800),
416 1,
417 1,
418 0,
419 channelWidth,
420 GetAggregation(station));
421}
422
423} // 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:94
a unique identifier for an interface.
Definition type-id.h:48
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:40
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:174
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:111
hold a list of per-remote-station state.
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
#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:1344
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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.
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1396
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
WifiPreamble GetPreambleForTransmission(WifiModulationClass modulation, bool useShortPreamble)
Return the preamble to be used for the transmission.
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1416
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.