A Discrete-Event Network Simulator
API
rraa-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) 2004,2005,2006 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: Federico Maguolo <maguolof@dei.unipd.it>
19  */
20 
21 #include "rraa-wifi-manager.h"
22 #include "wifi-mac.h"
23 #include "ns3/log.h"
24 #include "ns3/boolean.h"
25 #include "ns3/double.h"
26 #include "ns3/uinteger.h"
27 #include "ns3/simulator.h"
28 
29 #define Min(a,b) ((a < b) ? a : b)
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("RraaWifiManager");
34 
42 {
43  uint32_t m_counter;
44  uint32_t m_nFailed;
45  uint32_t m_adaptiveRtsWnd;
46  uint32_t m_rtsCounter;
51  uint8_t m_nRate;
52  uint8_t m_rateIndex;
53 
55 };
56 
58 
59 TypeId
61 {
62  static TypeId tid = TypeId ("ns3::RraaWifiManager")
64  .SetGroupName ("Wifi")
65  .AddConstructor<RraaWifiManager> ()
66  .AddAttribute ("Basic",
67  "If true the RRAA-BASIC algorithm will be used, otherwise the RRAA wil be used",
68  BooleanValue (false),
71  .AddAttribute ("Timeout",
72  "Timeout for the RRAA BASIC loss estimation block (s)",
73  TimeValue (Seconds (0.05)),
75  MakeTimeChecker ())
76  .AddAttribute ("FrameLength",
77  "The data frame length (in bytes) used for calculating mode TxTime.",
78  UintegerValue (1420),
80  MakeUintegerChecker <uint32_t> ())
81  .AddAttribute ("AckFrameLength",
82  "The ACK frame length (in bytes) used for calculating mode TxTime.",
83  UintegerValue (14),
85  MakeUintegerChecker <uint32_t> ())
86  .AddAttribute ("Alpha",
87  "Constant for calculating the MTL threshold.",
88  DoubleValue (1.25),
90  MakeDoubleChecker<double> (1))
91  .AddAttribute ("Beta",
92  "Constant for calculating the ORI threshold.",
93  DoubleValue (2),
95  MakeDoubleChecker<double> (1))
96  .AddAttribute ("Tau",
97  "Constant for calculating the EWND size.",
98  DoubleValue (0.012),
100  MakeDoubleChecker<double> (0))
101  .AddTraceSource ("Rate",
102  "Traced value for rate changes (b/s)",
104  "ns3::TracedValueCallback::Uint64")
105  ;
106  return tid;
107 }
108 
109 
112  m_currentRate (0)
113 {
114  NS_LOG_FUNCTION (this);
115 }
116 
118 {
119  NS_LOG_FUNCTION (this);
120 }
121 
122 void
124 {
125  NS_LOG_FUNCTION (this << phy);
126  uint8_t nModes = phy->GetNModes ();
127  for (uint8_t i = 0; i < nModes; i++)
128  {
129  WifiMode mode = phy->GetMode (i);
130  WifiTxVector txVector;
131  txVector.SetMode (mode);
133  /* Calculate the TX Time of the data and the corresponding ACK*/
134  Time dataTxTime = phy->CalculateTxDuration (m_frameLength, txVector, phy->GetFrequency ());
135  Time ackTxTime = phy->CalculateTxDuration (m_ackLength, txVector, phy->GetFrequency ());
136  NS_LOG_DEBUG ("Calculating TX times: Mode= " << mode << " DataTxTime= " << dataTxTime << " AckTxTime= " << ackTxTime);
137  AddCalcTxTime (mode, dataTxTime + ackTxTime);
138  }
140 }
141 
142 void
144 {
145  NS_LOG_FUNCTION (this);
146  m_sifs = mac->GetSifs ();
147  m_difs = m_sifs + 2 * mac->GetSlot ();
149 }
150 
151 Time
153 {
154  NS_LOG_FUNCTION (this << mode);
155  for (TxTime::const_iterator i = m_calcTxTime.begin (); i != m_calcTxTime.end (); i++)
156  {
157  if (mode == i->second)
158  {
159  return i->first;
160  }
161  }
162  NS_ASSERT (false);
163  return Seconds (0);
164 }
165 
166 void
168 {
169  NS_LOG_FUNCTION (this << mode << t);
170  m_calcTxTime.push_back (std::make_pair (t, mode));
171 }
172 
175 {
176  NS_LOG_FUNCTION (this << station << mode);
177  struct WifiRraaThresholds threshold;
178  for (RraaThresholdsTable::const_iterator i = station->m_thresholds.begin (); i != station->m_thresholds.end (); i++)
179  {
180  if (mode == i->second)
181  {
182  return i->first;
183  }
184  }
185  NS_ABORT_MSG ("No thresholds for mode " << mode << " found");
186  return threshold; // Silence compiler warning
187 }
188 
191 {
193  station->m_initialized = false;
194  station->m_adaptiveRtsWnd = 0;
195  station->m_rtsCounter = 0;
196  station->m_adaptiveRtsOn = false;
197  station->m_lastFrameFail = false;
198  return station;
199 }
200 
201 void
203 {
204  NS_LOG_FUNCTION (this << station);
205  if (!station->m_initialized)
206  {
207  //Note: we appear to be doing late initialization of the table
208  //to make sure that the set of supported rates has been initialized
209  //before we perform our own initialization.
210  station->m_nRate = GetNSupported (station);
211  //Initialize at maximal rate
212  station->m_rateIndex = GetMaxRate (station);
213 
214  station->m_initialized = true;
215 
216  station->m_thresholds = RraaThresholdsTable (station->m_nRate);
217  InitThresholds (station);
218  ResetCountersBasic (station);
219  }
220 }
221 
222 void
224 {
225  NS_LOG_FUNCTION (this << station);
226  NS_LOG_DEBUG ("InitThresholds = " << station);
227 
228  double nextCritical = 0;
229  double nextMtl = 0;
230  double mtl = 0;
231  double ori = 0;
232  for (uint8_t i = 0; i < station->m_nRate; i++)
233  {
234  WifiMode mode = GetSupported (station, i);
235  Time totalTxTime = GetCalcTxTime (mode) + m_sifs + m_difs;
236  if (i == GetMaxRate (station))
237  {
238  ori = 0;
239  }
240  else
241  {
242  WifiMode nextMode = GetSupported (station, i + 1);
243  Time nextTotalTxTime = GetCalcTxTime (nextMode) + m_sifs + m_difs;
244  nextCritical = 1 - (nextTotalTxTime.GetSeconds () / totalTxTime.GetSeconds ());
245  nextMtl = m_alpha * nextCritical;
246  ori = nextMtl / m_beta;
247  }
248  if (i == 0)
249  {
250  mtl = 1;
251  }
253  th.m_ewnd = ceil (m_tau / totalTxTime.GetSeconds ());
254  th.m_ori = ori;
255  th.m_mtl = mtl;
256  station->m_thresholds.push_back (std::make_pair (th, mode));
257  mtl = nextMtl;
258  NS_LOG_DEBUG (mode << " " << th.m_ewnd << " " << th.m_mtl << " " << th.m_ori);
259  }
260 }
261 
262 void
264 {
265  NS_LOG_FUNCTION (this << station);
266  station->m_nFailed = 0;
267  station->m_counter = GetThresholds (station, station->m_rateIndex).m_ewnd;
268  station->m_lastReset = Simulator::Now ();
269 }
270 
271 uint8_t
273 {
274  return station->m_nRate - 1;
275 }
276 
277 void
279 {
280  NS_LOG_FUNCTION (this << st);
281 }
282 
283 void
285 {
286  NS_LOG_FUNCTION (this << st);
288  station->m_lastFrameFail = true;
289  CheckTimeout (station);
290  station->m_counter--;
291  station->m_nFailed++;
292  RunBasicAlgorithm (station);
293 }
294 
295 void
297  double rxSnr, WifiMode txMode)
298 {
299  NS_LOG_FUNCTION (this << st << rxSnr << txMode);
300 }
301 
302 void
304  double ctsSnr, WifiMode ctsMode, double rtsSnr)
305 {
306  NS_LOG_FUNCTION (this << st << ctsSnr << ctsMode << rtsSnr);
307 }
308 
309 void
311  double ackSnr, WifiMode ackMode, double dataSnr)
312 {
313  NS_LOG_FUNCTION (this << st << ackSnr << ackMode << dataSnr);
315  station->m_lastFrameFail = false;
316  CheckTimeout (station);
317  station->m_counter--;
318  RunBasicAlgorithm (station);
319 }
320 
321 void
323 {
324  NS_LOG_FUNCTION (this << st);
325 }
326 
327 void
329 {
330  NS_LOG_FUNCTION (this << st);
331 }
332 
335 {
336  NS_LOG_FUNCTION (this << st);
338  uint8_t channelWidth = GetChannelWidth (station);
339  if (channelWidth > 20 && channelWidth != 22)
340  {
341  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
342  channelWidth = 20;
343  }
344  CheckInit (station);
345  WifiMode mode = GetSupported (station, station->m_rateIndex);
346  if (m_currentRate != mode.GetDataRate (channelWidth))
347  {
348  NS_LOG_DEBUG ("New datarate: " << mode.GetDataRate (channelWidth));
349  m_currentRate = mode.GetDataRate (channelWidth);
350  }
351  return WifiTxVector (mode, GetDefaultTxPowerLevel (), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
352 }
353 
356 {
357  NS_LOG_FUNCTION (this << st);
359  uint8_t channelWidth = GetChannelWidth (station);
360  if (channelWidth > 20 && channelWidth != 22)
361  {
362  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
363  channelWidth = 20;
364  }
365  WifiTxVector rtsTxVector;
366  WifiMode mode;
367  if (GetUseNonErpProtection () == false)
368  {
369  mode = GetSupported (station, 0);
370  }
371  else
372  {
373  mode = GetNonErpSupported (station, 0);
374  }
375  rtsTxVector = WifiTxVector (mode, GetDefaultTxPowerLevel (), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
376  return rtsTxVector;
377 }
378 
379 bool
381  Ptr<const Packet> packet, bool normally)
382 {
383  NS_LOG_FUNCTION (this << st << packet << normally);
385  CheckInit (station);
386  if (m_basic)
387  {
388  return normally;
389  }
390  ARts (station);
391  return station->m_adaptiveRtsOn;
392 }
393 
394 void
396 {
397  NS_LOG_FUNCTION (this << station);
398  Time d = Simulator::Now () - station->m_lastReset;
399  if (station->m_counter == 0 || d > m_timeout)
400  {
401  ResetCountersBasic (station);
402  }
403 }
404 
405 void
407 {
408  NS_LOG_FUNCTION (this << station);
409  WifiRraaThresholds thresholds = GetThresholds (station, station->m_rateIndex);
410  double ploss = (static_cast<double> (station->m_nFailed) / thresholds.m_ewnd);
411  if (station->m_counter == 0
412  || ploss > thresholds.m_mtl)
413  {
414  if (ploss > thresholds.m_mtl)
415  {
416  station->m_rateIndex--;
417  }
418  else if (station->m_rateIndex < GetMaxRate (station)
419  && ploss < thresholds.m_ori)
420  {
421  station->m_rateIndex++;
422  }
423  ResetCountersBasic (station);
424  }
425 }
426 
427 void
429 {
430  if (!station->m_adaptiveRtsOn
431  && station->m_lastFrameFail)
432  {
433  station->m_adaptiveRtsWnd++;
434  station->m_rtsCounter = station->m_adaptiveRtsWnd;
435  }
436  else if ((station->m_adaptiveRtsOn && station->m_lastFrameFail)
437  || (!station->m_adaptiveRtsOn && !station->m_lastFrameFail))
438  {
439  station->m_adaptiveRtsWnd = station->m_adaptiveRtsWnd / 2;
440  station->m_rtsCounter = station->m_adaptiveRtsWnd;
441  }
442  if (station->m_rtsCounter > 0)
443  {
444  station->m_adaptiveRtsOn = true;
445  station->m_rtsCounter--;
446  }
447  else
448  {
449  station->m_adaptiveRtsOn = false;
450  }
451 }
452 
455 {
456  NS_LOG_FUNCTION (this << station << +rate);
457  WifiMode mode = GetSupported (station, rate);
458  return GetThresholds (station, mode);
459 }
460 
461 bool
463 {
464  return true;
465 }
466 
467 void
469 {
470  //HT is not supported by this algorithm.
471  if (enable)
472  {
473  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HT rates");
474  }
475 }
476 
477 void
479 {
480  //VHT is not supported by this algorithm.
481  if (enable)
482  {
483  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support VHT rates");
484  }
485 }
486 
487 void
489 {
490  //HE is not supported by this algorithm.
491  if (enable)
492  {
493  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates");
494  }
495 }
496 
497 } //namespace ns3
virtual void SetupMac(const Ptr< WifiMac > mac)
Set up MAC associated with this device since it is the object that knows the full set of timing param...
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 "...
AttributeValue implementation for Boolean.
Definition: boolean.h:36
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode)
This method is a pure virtual method that must be implemented by the sub-class.
bool GetUseNonErpProtection(void) const
Return whether the device supports protection of non-ERP stations.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:84
double m_tau
Tau value for RRAA (value for calculating EWND size).
static TypeId GetTypeId(void)
Get the type ID.
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.
#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 RunBasicAlgorithm(RraaWifiRemoteStation *station)
Find an appropriate rate for the given station, using a basic algorithm.
TracedValue< uint64_t > m_currentRate
Trace rate changes.
uint32_t m_ewnd
Evaluation Window.
bool DoNeedRts(WifiRemoteStation *st, Ptr< const Packet > packet, bool normally)
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
bool IsLowLatency(void) const
void DoReportRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
void ResetCountersBasic(RraaWifiRemoteStation *station)
Reset the counters of the given station.
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1260
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
bool GetAggregation(const WifiRemoteStation *station) const
Return whether the given station supports A-MPDU.
WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
WifiRemoteStation * DoCreateStation(void) const
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
bool m_adaptiveRtsOn
Check if Adaptive RTS mechanism is on.
Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
Definition: wifi-phy.cc:2301
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
void CheckInit(RraaWifiRemoteStation *station)
Check for initializations.
tuple phy
Definition: third.py:86
uint32_t m_frameLength
Data frame length used for calculate mode TxTime.
void CheckTimeout(RraaWifiRemoteStation *station)
Check if the counter should be resetted.
double m_beta
Beta value for RRAA (value for calculating ORI threshold).
AttributeValue implementation for Time.
Definition: nstime.h:1069
void DoReportDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
Hold an unsigned integer type.
Definition: uinteger.h:44
WifiTxVector DoGetDataTxVector(WifiRemoteStation *station)
WifiPreamble GetPreambleForTransmission(WifiMode mode, Mac48Address dest)
Return the preamble to be used for the transmission.
void SetHtSupported(bool enable)
Enable or disable HT capability support.
uint64_t GetDataRate(uint8_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:143
uint32_t m_counter
Counter for transmission attempts.
uint8_t m_nRate
Number of supported rates.
uint8_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
uint32_t m_rtsCounter
Counter for RTS transmission attempts.
WifiMode GetMode(uint8_t mode) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:3576
std::vector< std::pair< WifiRraaThresholds, WifiMode > > RraaThresholdsTable
List of thresholds for each mode.
Mac48Address GetAddress(const WifiRemoteStation *station) const
Return the address of the station.
tuple mac
Definition: third.py:92
virtual void SetupPhy(const Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
hold a list of per-remote-station state.
Robust Rate Adaptation AlgorithmThis is an implementation of RRAA as described in "Robust rate adapta...
Time GetCalcTxTime(WifiMode mode) const
Get the estimated TxTime of a packet with a given mode.
RraaThresholdsTable m_thresholds
RRAA thresholds for this station.
double m_alpha
Alpha value for RRAA (value for calculating MTL threshold)
bool m_initialized
For initializing variables.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
TxTime m_calcTxTime
To hold all the calculated TxTime for all modes.
uint32_t m_ackLength
Ack frame length used for calculate mode TxTime.
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 Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
void SetVhtSupported(bool enable)
Enable or disable VHT capability support.
WifiMode GetSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether mode associated with the specified station at the specified index. ...
double m_ori
Opportunistic Rate Increase threshold.
void ARts(RraaWifiRemoteStation *station)
Activate the use of RTS for the given station if the conditions are met.
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.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
Time m_sifs
Value of SIFS configured in the device.
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
Time m_difs
Value of DIFS configured in the device.
virtual void SetupMac(const Ptr< WifiMac > mac)
Set up MAC associated with this device since it is the object that knows the full set of timing param...
WifiMode GetNonErpSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether non-ERP mode associated with the specified station at the specified index...
WifiRraaThresholds structure.
void AddCalcTxTime(WifiMode mode, Time t)
Add transmission time for the given mode to an internal list.
uint8_t m_rateIndex
Current rate index.
Time m_lastReset
Time of the last reset.
uint32_t m_adaptiveRtsWnd
Window size for the Adaptive RTS mechanism.
#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:1007
void InitThresholds(RraaWifiRemoteStation *station)
Initialize the thresholds internal list for the given station.
void SetHeSupported(bool enable)
Enable or disable HE capability support.
uint8_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
hold per-remote-station state for RRAA Wifi manager.
WifiRraaThresholds GetThresholds(RraaWifiRemoteStation *station, WifiMode mode) const
Get the thresholds for the given station and mode.
bool m_lastFrameFail
Flag if the last frame sent has failed.
uint8_t GetMaxRate(RraaWifiRemoteStation *station) const
Return the index for the maximum transmission rate for the given station.
double m_mtl
Maximum Tolerable Loss threshold.
void DoReportFinalDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
void DoReportFinalRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
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.
uint8_t GetNModes(void) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:3570
virtual void SetupPhy(const Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
uint32_t m_nFailed
Number of failed transmission attempts.