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 "amrr-wifi-manager.h"
22 #include "ns3/simulator.h"
23 #include "ns3/log.h"
24 #include "ns3/uinteger.h"
25 #include "ns3/double.h"
26 
27 #define Min(a,b) ((a < b) ? a : b)
28 
29 namespace ns3 {
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  uint32_t m_txrate;
47  uint32_t m_successThreshold;
48  uint32_t m_success;
49  bool m_recovery;
50 };
51 
52 
54 
55 TypeId
57 {
58  static TypeId tid = 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)),
66  MakeTimeChecker ())
67  .AddAttribute ("FailureRatio",
68  "Ratio of minimum erroneous transmissions needed to switch to a lower rate",
69  DoubleValue (1.0 / 3.0),
71  MakeDoubleChecker<double> (0.0, 1.0))
72  .AddAttribute ("SuccessRatio",
73  "Ratio of maximum erroneous transmissions needed to switch to a higher rate",
74  DoubleValue (1.0 / 10.0),
76  MakeDoubleChecker<double> (0.0, 1.0))
77  .AddAttribute ("MaxSuccessThreshold",
78  "Maximum number of consecutive success periods needed to switch to a higher rate",
79  UintegerValue (10),
81  MakeUintegerChecker<uint32_t> ())
82  .AddAttribute ("MinSuccessThreshold",
83  "Minimum number of consecutive success periods needed to switch to a higher rate",
84  UintegerValue (1),
86  MakeUintegerChecker<uint32_t> ())
87  .AddTraceSource ("Rate",
88  "Traced value for rate changes (b/s)",
90  "ns3::TracedValueCallback::Uint64")
91  ;
92  return tid;
93 }
94 
97  m_currentRate (0)
98 {
99  NS_LOG_FUNCTION (this);
100 }
101 
103 {
104  NS_LOG_FUNCTION (this);
105 }
106 
109 {
110  NS_LOG_FUNCTION (this);
113  station->m_tx_ok = 0;
114  station->m_tx_err = 0;
115  station->m_tx_retr = 0;
116  station->m_retry = 0;
117  station->m_txrate = 0;
119  station->m_success = 0;
120  station->m_recovery = false;
121  return station;
122 }
123 
124 void
126  double rxSnr, WifiMode txMode)
127 {
128  NS_LOG_FUNCTION (this << station << rxSnr << txMode);
129 }
130 
131 void
133 {
134  NS_LOG_FUNCTION (this << station);
135 }
136 
137 void
139 {
140  NS_LOG_FUNCTION (this << st);
142  station->m_retry++;
143  station->m_tx_retr++;
144 }
145 
146 void
148  double ctsSnr, WifiMode ctsMode, double rtsSnr)
149 {
150  NS_LOG_FUNCTION (this << st << ctsSnr << ctsMode << rtsSnr);
151 }
152 
153 void
155  double ackSnr, WifiMode ackMode, double dataSnr)
156 {
157  NS_LOG_FUNCTION (this << st << ackSnr << ackMode << dataSnr);
159  station->m_retry = 0;
160  station->m_tx_ok++;
161 }
162 
163 void
165 {
166  NS_LOG_FUNCTION (this << station);
167 }
168 
169 void
171 {
172  NS_LOG_FUNCTION (this << st);
174  station->m_retry = 0;
175  station->m_tx_err++;
176 }
177 
178 bool
180 {
181  NS_LOG_FUNCTION (this << station);
182  return (station->m_txrate == 0);
183 }
184 
185 bool
187 {
188  NS_LOG_FUNCTION (this << station);
189  NS_ASSERT (station->m_txrate + 1 <= GetNSupported (station));
190  return (station->m_txrate + 1 == GetNSupported (station));
191 }
192 
193 bool
195 {
196  NS_LOG_FUNCTION (this << station);
197  return (station->m_tx_retr + station->m_tx_err) < station->m_tx_ok * m_successRatio;
198 }
199 
200 bool
202 {
203  NS_LOG_FUNCTION (this << station);
204  return (station->m_tx_retr + station->m_tx_err) > station->m_tx_ok * m_failureRatio;
205 }
206 
207 bool
209 {
210  NS_LOG_FUNCTION (this << station);
211  return (station->m_tx_retr + station->m_tx_err + station->m_tx_ok) > 10;
212 }
213 
214 void
216 {
217  NS_LOG_FUNCTION (this << station);
218  station->m_tx_ok = 0;
219  station->m_tx_err = 0;
220  station->m_tx_retr = 0;
221 }
222 
223 void
225 {
226  NS_LOG_FUNCTION (this << station);
227  station->m_txrate++;
228  NS_ASSERT (station->m_txrate < GetNSupported (station));
229 }
230 
231 void
233 {
234  NS_LOG_FUNCTION (this << station);
235  station->m_txrate--;
236 }
237 
238 void
240 {
241  NS_LOG_FUNCTION (this << station);
242  if (Simulator::Now () < station->m_nextModeUpdate)
243  {
244  return;
245  }
247  NS_LOG_DEBUG ("Update");
248 
249  bool needChange = false;
250 
251  if (IsSuccess (station) && IsEnough (station))
252  {
253  station->m_success++;
254  NS_LOG_DEBUG ("++ success=" << station->m_success << " successThreshold=" << station->m_successThreshold <<
255  " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err << " tx_retr=" << station->m_tx_retr <<
256  " rate=" << station->m_txrate << " n-supported-rates=" << GetNSupported (station));
257  if (station->m_success >= station->m_successThreshold
258  && !IsMaxRate (station))
259  {
260  station->m_recovery = true;
261  station->m_success = 0;
262  IncreaseRate (station);
263  needChange = true;
264  }
265  else
266  {
267  station->m_recovery = false;
268  }
269  }
270  else if (IsFailure (station))
271  {
272  station->m_success = 0;
273  NS_LOG_DEBUG ("-- success=" << station->m_success << " successThreshold=" << station->m_successThreshold <<
274  " tx_ok=" << station->m_tx_ok << " tx_err=" << station->m_tx_err << " tx_retr=" << station->m_tx_retr <<
275  " rate=" << station->m_txrate << " n-supported-rates=" << GetNSupported (station));
276  if (!IsMinRate (station))
277  {
278  if (station->m_recovery)
279  {
280  station->m_successThreshold *= 2;
281  station->m_successThreshold = std::min (station->m_successThreshold,
283  }
284  else
285  {
287  }
288  station->m_recovery = false;
289  DecreaseRate (station);
290  needChange = true;
291  }
292  else
293  {
294  station->m_recovery = false;
295  }
296  }
297  if (IsEnough (station) || needChange)
298  {
299  NS_LOG_DEBUG ("Reset");
300  ResetCnt (station);
301  }
302 }
303 
306 {
307  NS_LOG_FUNCTION (this << st);
309  UpdateMode (station);
310  NS_ASSERT (station->m_txrate < GetNSupported (station));
311  uint32_t rateIndex;
312  if (station->m_retry < 1)
313  {
314  rateIndex = station->m_txrate;
315  }
316  else if (station->m_retry < 2)
317  {
318  if (station->m_txrate > 0)
319  {
320  rateIndex = station->m_txrate - 1;
321  }
322  else
323  {
324  rateIndex = station->m_txrate;
325  }
326  }
327  else if (station->m_retry < 3)
328  {
329  if (station->m_txrate > 1)
330  {
331  rateIndex = station->m_txrate - 2;
332  }
333  else
334  {
335  rateIndex = station->m_txrate;
336  }
337  }
338  else
339  {
340  if (station->m_txrate > 2)
341  {
342  rateIndex = station->m_txrate - 3;
343  }
344  else
345  {
346  rateIndex = station->m_txrate;
347  }
348  }
349  uint32_t channelWidth = GetChannelWidth (station);
350  if (channelWidth > 20 && channelWidth != 22)
351  {
352  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
353  channelWidth = 20;
354  }
355  WifiMode mode = GetSupported (station, rateIndex);
356  if (m_currentRate != mode.GetDataRate (channelWidth))
357  {
358  NS_LOG_DEBUG ("New datarate: " << mode.GetDataRate (channelWidth));
359  m_currentRate = mode.GetDataRate (channelWidth);
360  }
361  return WifiTxVector (mode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
362 }
363 
366 {
367  NS_LOG_FUNCTION (this << st);
369  uint32_t channelWidth = GetChannelWidth (station);
370  if (channelWidth > 20 && channelWidth != 22)
371  {
372  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
373  channelWidth = 20;
374  }
375  UpdateMode (station);
376  WifiTxVector rtsTxVector;
377  WifiMode mode;
378  if (GetUseNonErpProtection () == false)
379  {
380  mode = GetSupported (station, 0);
381  }
382  else
383  {
384  mode = GetNonErpSupported (station, 0);
385  }
386  rtsTxVector = WifiTxVector (mode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
387  return rtsTxVector;
388 }
389 
390 bool
392 {
393  NS_LOG_FUNCTION (this);
394  return true;
395 }
396 
397 void
399 {
400  //HT is not supported by this algorithm.
401  if (enable)
402  {
403  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HT rates");
404  }
405 }
406 
407 void
409 {
410  //VHT is not supported by this algorithm.
411  if (enable)
412  {
413  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support VHT rates");
414  }
415 }
416 
417 void
419 {
420  //HE is not supported by this algorithm.
421  if (enable)
422  {
423  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates");
424  }
425 }
426 
427 } //namespace ns3
uint32_t m_minSuccessThreshold
mnimum success threshold
uint32_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
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 ...
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:44
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:201
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.
WifiMode GetSupported(const WifiRemoteStation *station, uint32_t i) const
Return whether mode associated with the specified station at the specified index. ...
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:1055
uint32_t m_txrate
transmit rate
Hold an unsigned integer type.
Definition: uinteger.h:44
WifiMode GetNonErpSupported(const WifiRemoteStation *station, uint32_t i) const
Return whether non-ERP mode associated with the specified station at the specified index...
WifiPreamble GetPreambleForTransmission(WifiMode mode, Mac48Address dest)
Return the preamble to be used for the transmission.
uint64_t GetDataRate(uint8_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:143
uint8_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
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:1056
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.
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...
uint32_t GetLongRetryCount(const WifiRemoteStation *station) const
Return the long retry limit of the given station.
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:269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
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...
void SetVhtSupported(bool enable)
Enable or disable VHT capability support.
This class can be used to hold variables of floating point type such as 'double' or 'float'...
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:914
hold per-remote-station state.