A Discrete-Event Network Simulator
API
amrr-wifi-manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003,2007 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 
20 #include "amrr-wifi-manager.h"
21 
22 #include "ns3/log.h"
23 #include "ns3/simulator.h"
24 #include "ns3/wifi-tx-vector.h"
25 
26 #define Min(a, b) ((a < b) ? a : b)
27 
28 namespace ns3
29 {
30 
31 NS_LOG_COMPONENT_DEFINE("AmrrWifiManager");
32 
40 {
42  uint32_t m_tx_ok;
43  uint32_t m_tx_err;
44  uint32_t m_tx_retr;
45  uint32_t m_retry;
46  uint8_t m_txrate;
47  uint32_t m_successThreshold;
48  uint32_t m_success;
49  bool m_recovery;
50 };
51 
53 
54 TypeId
56 {
57  static TypeId tid =
58  TypeId("ns3::AmrrWifiManager")
60  .SetGroupName("Wifi")
61  .AddConstructor<AmrrWifiManager>()
62  .AddAttribute("UpdatePeriod",
63  "The interval between decisions about rate control changes",
64  TimeValue(Seconds(1.0)),
67  .AddAttribute(
68  "FailureRatio",
69  "Ratio of minimum erroneous transmissions needed to switch to a lower rate",
70  DoubleValue(1.0 / 3.0),
72  MakeDoubleChecker<double>(0.0, 1.0))
73  .AddAttribute(
74  "SuccessRatio",
75  "Ratio of maximum erroneous transmissions needed to switch to a higher rate",
76  DoubleValue(1.0 / 10.0),
78  MakeDoubleChecker<double>(0.0, 1.0))
79  .AddAttribute(
80  "MaxSuccessThreshold",
81  "Maximum number of consecutive success periods needed to switch to a higher rate",
82  UintegerValue(10),
84  MakeUintegerChecker<uint32_t>())
85  .AddAttribute(
86  "MinSuccessThreshold",
87  "Minimum number of consecutive success periods needed to switch to a higher rate",
88  UintegerValue(1),
90  MakeUintegerChecker<uint32_t>())
91  .AddTraceSource("Rate",
92  "Traced value for rate changes (b/s)",
94  "ns3::TracedValueCallback::Uint64");
95  return tid;
96 }
97 
100  m_currentRate(0)
101 {
102  NS_LOG_FUNCTION(this);
103 }
104 
106 {
107  NS_LOG_FUNCTION(this);
108 }
109 
110 void
112 {
113  NS_LOG_FUNCTION(this);
114  if (GetHtSupported())
115  {
116  NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HT rates");
117  }
118  if (GetVhtSupported())
119  {
120  NS_FATAL_ERROR("WifiRemoteStationManager selected does not support VHT rates");
121  }
122  if (GetHeSupported())
123  {
124  NS_FATAL_ERROR("WifiRemoteStationManager selected does not support HE rates");
125  }
126 }
127 
130 {
131  NS_LOG_FUNCTION(this);
132  auto station = new AmrrWifiRemoteStation();
133  station->m_nextModeUpdate = Simulator::Now() + m_updatePeriod;
134  station->m_tx_ok = 0;
135  station->m_tx_err = 0;
136  station->m_tx_retr = 0;
137  station->m_retry = 0;
138  station->m_txrate = 0;
139  station->m_successThreshold = m_minSuccessThreshold;
140  station->m_success = 0;
141  station->m_recovery = false;
142  return station;
143 }
144 
145 void
147 {
148  NS_LOG_FUNCTION(this << station << rxSnr << txMode);
149 }
150 
151 void
153 {
154  NS_LOG_FUNCTION(this << station);
155 }
156 
157 void
159 {
160  NS_LOG_FUNCTION(this << st);
161  auto station = static_cast<AmrrWifiRemoteStation*>(st);
162  station->m_retry++;
163  station->m_tx_retr++;
164 }
165 
166 void
168  double ctsSnr,
169  WifiMode ctsMode,
170  double rtsSnr)
171 {
172  NS_LOG_FUNCTION(this << st << ctsSnr << ctsMode << rtsSnr);
173 }
174 
175 void
177  double ackSnr,
178  WifiMode ackMode,
179  double dataSnr,
180  uint16_t dataChannelWidth,
181  uint8_t dataNss)
182 {
183  NS_LOG_FUNCTION(this << st << ackSnr << ackMode << dataSnr << dataChannelWidth << +dataNss);
184  auto station = static_cast<AmrrWifiRemoteStation*>(st);
185  station->m_retry = 0;
186  station->m_tx_ok++;
187 }
188 
189 void
191 {
192  NS_LOG_FUNCTION(this << station);
193 }
194 
195 void
197 {
198  NS_LOG_FUNCTION(this << st);
199  auto station = static_cast<AmrrWifiRemoteStation*>(st);
200  station->m_retry = 0;
201  station->m_tx_err++;
202 }
203 
204 bool
206 {
207  NS_LOG_FUNCTION(this << station);
208  return (station->m_txrate == 0);
209 }
210 
211 bool
213 {
214  NS_LOG_FUNCTION(this << station);
215  NS_ASSERT(station->m_txrate + 1 <= GetNSupported(station));
216  return (station->m_txrate + 1 == GetNSupported(station));
217 }
218 
219 bool
221 {
222  NS_LOG_FUNCTION(this << station);
223  return (station->m_tx_retr + station->m_tx_err) < station->m_tx_ok * m_successRatio;
224 }
225 
226 bool
228 {
229  NS_LOG_FUNCTION(this << station);
230  return (station->m_tx_retr + station->m_tx_err) > station->m_tx_ok * m_failureRatio;
231 }
232 
233 bool
235 {
236  NS_LOG_FUNCTION(this << station);
237  return (station->m_tx_retr + station->m_tx_err + station->m_tx_ok) > 10;
238 }
239 
240 void
242 {
243  NS_LOG_FUNCTION(this << station);
244  station->m_tx_ok = 0;
245  station->m_tx_err = 0;
246  station->m_tx_retr = 0;
247 }
248 
249 void
251 {
252  NS_LOG_FUNCTION(this << station);
253  station->m_txrate++;
254  NS_ASSERT(station->m_txrate < GetNSupported(station));
255 }
256 
257 void
259 {
260  NS_LOG_FUNCTION(this << station);
261  station->m_txrate--;
262 }
263 
264 void
266 {
267  NS_LOG_FUNCTION(this << station);
268  if (Simulator::Now() < station->m_nextModeUpdate)
269  {
270  return;
271  }
273  NS_LOG_DEBUG("Update");
274 
275  bool needChange = false;
276 
277  if (IsSuccess(station) && IsEnough(station))
278  {
279  station->m_success++;
280  NS_LOG_DEBUG("++ success="
281  << station->m_success << " successThreshold=" << station->m_successThreshold
282  << " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err
283  << " tx_retr=" << station->m_tx_retr << " rate=" << +station->m_txrate
284  << " n-supported-rates=" << +GetNSupported(station));
285  if (station->m_success >= station->m_successThreshold && !IsMaxRate(station))
286  {
287  station->m_recovery = true;
288  station->m_success = 0;
289  IncreaseRate(station);
290  needChange = true;
291  }
292  else
293  {
294  station->m_recovery = false;
295  }
296  }
297  else if (IsFailure(station))
298  {
299  station->m_success = 0;
300  NS_LOG_DEBUG("-- success="
301  << station->m_success << " successThreshold=" << station->m_successThreshold
302  << " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err
303  << " tx_retr=" << station->m_tx_retr << " rate=" << +station->m_txrate
304  << " n-supported-rates=" << +GetNSupported(station));
305  if (!IsMinRate(station))
306  {
307  if (station->m_recovery)
308  {
309  station->m_successThreshold *= 2;
310  station->m_successThreshold =
312  }
313  else
314  {
316  }
317  station->m_recovery = false;
318  DecreaseRate(station);
319  needChange = true;
320  }
321  else
322  {
323  station->m_recovery = false;
324  }
325  }
326  if (IsEnough(station) || needChange)
327  {
328  NS_LOG_DEBUG("Reset");
329  ResetCnt(station);
330  }
331 }
332 
335 {
336  NS_LOG_FUNCTION(this << st << allowedWidth);
337  auto station = static_cast<AmrrWifiRemoteStation*>(st);
338  UpdateMode(station);
339  NS_ASSERT(station->m_txrate < GetNSupported(station));
340  uint8_t rateIndex;
341  if (station->m_retry < 1)
342  {
343  rateIndex = station->m_txrate;
344  }
345  else if (station->m_retry < 2)
346  {
347  if (station->m_txrate > 0)
348  {
349  rateIndex = station->m_txrate - 1;
350  }
351  else
352  {
353  rateIndex = station->m_txrate;
354  }
355  }
356  else if (station->m_retry < 3)
357  {
358  if (station->m_txrate > 1)
359  {
360  rateIndex = station->m_txrate - 2;
361  }
362  else
363  {
364  rateIndex = station->m_txrate;
365  }
366  }
367  else
368  {
369  if (station->m_txrate > 2)
370  {
371  rateIndex = station->m_txrate - 3;
372  }
373  else
374  {
375  rateIndex = station->m_txrate;
376  }
377  }
378  uint16_t channelWidth = GetChannelWidth(station);
379  if (channelWidth > 20 && channelWidth != 22)
380  {
381  channelWidth = 20;
382  }
383  WifiMode mode = GetSupported(station, rateIndex);
384  uint64_t rate = mode.GetDataRate(channelWidth);
385  if (m_currentRate != rate)
386  {
387  NS_LOG_DEBUG("New datarate: " << rate);
388  m_currentRate = rate;
389  }
390  return WifiTxVector(
391  mode,
394  800,
395  1,
396  1,
397  0,
398  channelWidth,
399  GetAggregation(station));
400 }
401 
404 {
405  NS_LOG_FUNCTION(this << st);
406  auto station = static_cast<AmrrWifiRemoteStation*>(st);
407  uint16_t channelWidth = GetChannelWidth(station);
408  if (channelWidth > 20 && channelWidth != 22)
409  {
410  channelWidth = 20;
411  }
412  UpdateMode(station);
413  WifiMode mode;
414  if (!GetUseNonErpProtection())
415  {
416  mode = GetSupported(station, 0);
417  }
418  else
419  {
420  mode = GetNonErpSupported(station, 0);
421  }
422  return WifiTxVector(
423  mode,
426  800,
427  1,
428  1,
429  0,
430  channelWidth,
431  GetAggregation(station));
432 }
433 
434 } // namespace ns3
#define min(a, b)
Definition: 80211b.c:41
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 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, uint16_t allowedWidth) override
void IncreaseRate(AmrrWifiRemoteStation *station)
Increase the transmission rate to the given station.
void DoReportDataOk(WifiRemoteStation *station, double ackSnr, WifiMode ackMode, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss) override
This method is a pure virtual method that must be implemented by the sub-class.
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:42
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
represent a single transmission mode
Definition: wifi-mode.h:51
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
hold a list of per-remote-station state.
uint16_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
uint8_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given 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.
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.
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:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
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 AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
WifiPreamble GetPreambleForTransmission(WifiModulationClass modulation, bool useShortPreamble)
Return the preamble to be used for the transmission.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
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_ok
transmit OK
uint32_t m_tx_retr
transmit retry
uint32_t m_successThreshold
success threshold
hold per-remote-station state.