A Discrete-Event Network Simulator
API
amrr-wifi-manager.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2003,2007 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/simulator.h"
23 #include "amrr-wifi-manager.h"
24 #include "wifi-tx-vector.h"
25 
26 #define Min(a,b) ((a < b) ? a : b)
27 
28 namespace ns3 {
29 
30 NS_LOG_COMPONENT_DEFINE ("AmrrWifiManager");
31 
39 {
41  uint32_t m_tx_ok;
42  uint32_t m_tx_err;
43  uint32_t m_tx_retr;
44  uint32_t m_retry;
45  uint8_t m_txrate;
46  uint32_t m_successThreshold;
47  uint32_t m_success;
48  bool m_recovery;
49 };
50 
51 
53 
54 TypeId
56 {
57  static TypeId tid = TypeId ("ns3::AmrrWifiManager")
59  .SetGroupName ("Wifi")
60  .AddConstructor<AmrrWifiManager> ()
61  .AddAttribute ("UpdatePeriod",
62  "The interval between decisions about rate control changes",
63  TimeValue (Seconds (1.0)),
65  MakeTimeChecker ())
66  .AddAttribute ("FailureRatio",
67  "Ratio of minimum erroneous transmissions needed to switch to a lower rate",
68  DoubleValue (1.0 / 3.0),
70  MakeDoubleChecker<double> (0.0, 1.0))
71  .AddAttribute ("SuccessRatio",
72  "Ratio of maximum erroneous transmissions needed to switch to a higher rate",
73  DoubleValue (1.0 / 10.0),
75  MakeDoubleChecker<double> (0.0, 1.0))
76  .AddAttribute ("MaxSuccessThreshold",
77  "Maximum number of consecutive success periods needed to switch to a higher rate",
78  UintegerValue (10),
80  MakeUintegerChecker<uint32_t> ())
81  .AddAttribute ("MinSuccessThreshold",
82  "Minimum number of consecutive success periods needed to switch to a higher rate",
83  UintegerValue (1),
85  MakeUintegerChecker<uint32_t> ())
86  .AddTraceSource ("Rate",
87  "Traced value for rate changes (b/s)",
89  "ns3::TracedValueCallback::Uint64")
90  ;
91  return tid;
92 }
93 
96  m_currentRate (0)
97 {
98  NS_LOG_FUNCTION (this);
99 }
100 
102 {
103  NS_LOG_FUNCTION (this);
104 }
105 
108 {
109  NS_LOG_FUNCTION (this);
112  station->m_tx_ok = 0;
113  station->m_tx_err = 0;
114  station->m_tx_retr = 0;
115  station->m_retry = 0;
116  station->m_txrate = 0;
118  station->m_success = 0;
119  station->m_recovery = false;
120  return station;
121 }
122 
123 void
125  double rxSnr, WifiMode txMode)
126 {
127  NS_LOG_FUNCTION (this << station << rxSnr << txMode);
128 }
129 
130 void
132 {
133  NS_LOG_FUNCTION (this << station);
134 }
135 
136 void
138 {
139  NS_LOG_FUNCTION (this << st);
141  station->m_retry++;
142  station->m_tx_retr++;
143 }
144 
145 void
147  double ctsSnr, WifiMode ctsMode, double rtsSnr)
148 {
149  NS_LOG_FUNCTION (this << st << ctsSnr << ctsMode << rtsSnr);
150 }
151 
152 void
154  double ackSnr, WifiMode ackMode, double dataSnr)
155 {
156  NS_LOG_FUNCTION (this << st << ackSnr << ackMode << dataSnr);
158  station->m_retry = 0;
159  station->m_tx_ok++;
160 }
161 
162 void
164 {
165  NS_LOG_FUNCTION (this << station);
166 }
167 
168 void
170 {
171  NS_LOG_FUNCTION (this << st);
173  station->m_retry = 0;
174  station->m_tx_err++;
175 }
176 
177 bool
179 {
180  NS_LOG_FUNCTION (this << station);
181  return (station->m_txrate == 0);
182 }
183 
184 bool
186 {
187  NS_LOG_FUNCTION (this << station);
188  NS_ASSERT (station->m_txrate + 1 <= GetNSupported (station));
189  return (station->m_txrate + 1 == GetNSupported (station));
190 }
191 
192 bool
194 {
195  NS_LOG_FUNCTION (this << station);
196  return (station->m_tx_retr + station->m_tx_err) < station->m_tx_ok * m_successRatio;
197 }
198 
199 bool
201 {
202  NS_LOG_FUNCTION (this << station);
203  return (station->m_tx_retr + station->m_tx_err) > station->m_tx_ok * m_failureRatio;
204 }
205 
206 bool
208 {
209  NS_LOG_FUNCTION (this << station);
210  return (station->m_tx_retr + station->m_tx_err + station->m_tx_ok) > 10;
211 }
212 
213 void
215 {
216  NS_LOG_FUNCTION (this << station);
217  station->m_tx_ok = 0;
218  station->m_tx_err = 0;
219  station->m_tx_retr = 0;
220 }
221 
222 void
224 {
225  NS_LOG_FUNCTION (this << station);
226  station->m_txrate++;
227  NS_ASSERT (station->m_txrate < GetNSupported (station));
228 }
229 
230 void
232 {
233  NS_LOG_FUNCTION (this << station);
234  station->m_txrate--;
235 }
236 
237 void
239 {
240  NS_LOG_FUNCTION (this << station);
241  if (Simulator::Now () < station->m_nextModeUpdate)
242  {
243  return;
244  }
246  NS_LOG_DEBUG ("Update");
247 
248  bool needChange = false;
249 
250  if (IsSuccess (station) && IsEnough (station))
251  {
252  station->m_success++;
253  NS_LOG_DEBUG ("++ success=" << station->m_success << " successThreshold=" << station->m_successThreshold <<
254  " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err << " tx_retr=" << station->m_tx_retr <<
255  " rate=" << +station->m_txrate << " n-supported-rates=" << +GetNSupported (station));
256  if (station->m_success >= station->m_successThreshold
257  && !IsMaxRate (station))
258  {
259  station->m_recovery = true;
260  station->m_success = 0;
261  IncreaseRate (station);
262  needChange = true;
263  }
264  else
265  {
266  station->m_recovery = false;
267  }
268  }
269  else if (IsFailure (station))
270  {
271  station->m_success = 0;
272  NS_LOG_DEBUG ("-- success=" << station->m_success << " successThreshold=" << station->m_successThreshold <<
273  " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err << " tx_retr=" << station->m_tx_retr <<
274  " rate=" << +station->m_txrate << " n-supported-rates=" << +GetNSupported (station));
275  if (!IsMinRate (station))
276  {
277  if (station->m_recovery)
278  {
279  station->m_successThreshold *= 2;
280  station->m_successThreshold = std::min (station->m_successThreshold,
282  }
283  else
284  {
286  }
287  station->m_recovery = false;
288  DecreaseRate (station);
289  needChange = true;
290  }
291  else
292  {
293  station->m_recovery = false;
294  }
295  }
296  if (IsEnough (station) || needChange)
297  {
298  NS_LOG_DEBUG ("Reset");
299  ResetCnt (station);
300  }
301 }
302 
305 {
306  NS_LOG_FUNCTION (this << st);
308  UpdateMode (station);
309  NS_ASSERT (station->m_txrate < GetNSupported (station));
310  uint8_t rateIndex;
311  if (station->m_retry < 1)
312  {
313  rateIndex = station->m_txrate;
314  }
315  else if (station->m_retry < 2)
316  {
317  if (station->m_txrate > 0)
318  {
319  rateIndex = station->m_txrate - 1;
320  }
321  else
322  {
323  rateIndex = station->m_txrate;
324  }
325  }
326  else if (station->m_retry < 3)
327  {
328  if (station->m_txrate > 1)
329  {
330  rateIndex = station->m_txrate - 2;
331  }
332  else
333  {
334  rateIndex = station->m_txrate;
335  }
336  }
337  else
338  {
339  if (station->m_txrate > 2)
340  {
341  rateIndex = station->m_txrate - 3;
342  }
343  else
344  {
345  rateIndex = station->m_txrate;
346  }
347  }
348  uint16_t channelWidth = GetChannelWidth (station);
349  if (channelWidth > 20 && channelWidth != 22)
350  {
351  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
352  channelWidth = 20;
353  }
354  WifiMode mode = GetSupported (station, rateIndex);
355  if (m_currentRate != mode.GetDataRate (channelWidth))
356  {
357  NS_LOG_DEBUG ("New datarate: " << mode.GetDataRate (channelWidth));
358  m_currentRate = mode.GetDataRate (channelWidth);
359  }
360  return WifiTxVector (mode, GetDefaultTxPowerLevel (), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
361 }
362 
365 {
366  NS_LOG_FUNCTION (this << st);
368  uint16_t channelWidth = GetChannelWidth (station);
369  if (channelWidth > 20 && channelWidth != 22)
370  {
371  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
372  channelWidth = 20;
373  }
374  UpdateMode (station);
375  WifiTxVector rtsTxVector;
376  WifiMode mode;
377  if (GetUseNonErpProtection () == false)
378  {
379  mode = GetSupported (station, 0);
380  }
381  else
382  {
383  mode = GetNonErpSupported (station, 0);
384  }
385  rtsTxVector = WifiTxVector (mode, GetDefaultTxPowerLevel (), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
386  return rtsTxVector;
387 }
388 
389 bool
391 {
392  return true;
393 }
394 
395 void
397 {
398  //HT is not supported by this algorithm.
399  if (enable)
400  {
401  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HT rates");
402  }
403 }
404 
405 void
407 {
408  //VHT is not supported by this algorithm.
409  if (enable)
410  {
411  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support VHT rates");
412  }
413 }
414 
415 void
417 {
418  //HE is not supported by this algorithm.
419  if (enable)
420  {
421  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates");
422  }
423 }
424 
425 } //namespace ns3
uint32_t m_minSuccessThreshold
mnimum success threshold
bool IsMinRate(AmrrWifiRemoteStation *station) const
Check if the current rate for the given station is the minimum rate.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
AMRR Rate control algorithmThis class implements the AMRR rate control algorithm which was initially ...
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:156
WifiRemoteStation * DoCreateStation(void) const
uint32_t m_successThreshold
success threshold
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Time m_nextModeUpdate
next mode update time
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void DoReportFinalRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
#define min(a, b)
Definition: 80211b.c:42
bool GetUseNonErpProtection(void) const
Return whether the device supports protection of non-ERP stations.
void ResetCnt(AmrrWifiRemoteStation *station)
Reset transmission statistics of the given station.
hold per-remote-station state for AMRR Wifi manager.
WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
void SetHeSupported(bool enable)
Enable or disable HE capability support.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
uint32_t m_tx_err
transmit error
Time m_updatePeriod
update period
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
void DoReportRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
bool GetAggregation(const WifiRemoteStation *station) const
Return whether the given station supports A-MPDU.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
WifiTxVector DoGetDataTxVector(WifiRemoteStation *station)
TracedValue< uint64_t > m_currentRate
Trace rate changes.
bool IsLowLatency(void) const
bool IsFailure(AmrrWifiRemoteStation *station) const
Check if the number of retransmission and transmission error is greater than the number of successful...
AttributeValue implementation for Time.
Definition: nstime.h:1069
Hold an unsigned integer type.
Definition: uinteger.h:44
WifiPreamble GetPreambleForTransmission(WifiMode mode, Mac48Address dest)
Return the preamble to be used for the transmission.
uint8_t m_txrate
transmit rate
void DoReportDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
void SetHtSupported(bool enable)
Enable or disable HT capability support.
void DecreaseRate(AmrrWifiRemoteStation *station)
Decrease the transmission rate to the given station.
Mac48Address GetAddress(const WifiRemoteStation *station) const
Return the address of the station.
hold a list of per-remote-station state.
uint32_t m_tx_ok
transmit ok
void IncreaseRate(AmrrWifiRemoteStation *station)
Increase the transmission rate to the given station.
void DoReportRtsOk(WifiRemoteStation *station, double ctsSnr, WifiMode ctsMode, double rtsSnr)
This method is a pure virtual method that must be implemented by the sub-class.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double m_successRatio
success ratio
void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode)
This method is a pure virtual method that must be implemented by the sub-class.
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:1070
static TypeId GetTypeId(void)
Get the type ID.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
void DoReportDataOk(WifiRemoteStation *station, double ackSnr, WifiMode ackMode, double dataSnr)
This method is a pure virtual method that must be implemented by the sub-class.
WifiMode GetSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether mode associated with the specified station at the specified index. ...
uint32_t m_tx_retr
transmit retry
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:42
bool IsSuccess(AmrrWifiRemoteStation *station) const
Check if the number of retransmission and transmission error is less than the number of successful tr...
WifiMode GetNonErpSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether non-ERP mode associated with the specified station at the specified index...
double m_failureRatio
failure ratio
uint32_t m_maxSuccessThreshold
maximum success threshold
void DoReportFinalDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:270
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1007
void UpdateMode(AmrrWifiRemoteStation *station)
Update the mode used to send to the given station.
bool IsMaxRate(AmrrWifiRemoteStation *station) const
Check if the current rate for the given station is the maximum rate.
bool IsEnough(AmrrWifiRemoteStation *station) const
Check if the number of retransmission, transmission error, and successful transmission are greater th...
uint8_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
void SetVhtSupported(bool enable)
Enable or disable VHT capability support.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
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:45
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
hold per-remote-station state.
uint16_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.