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 
52  uint32_t m_nRate;
53 
54  uint32_t m_rateIndex;
55 
57 };
58 
60 
61 TypeId
63 {
64  static TypeId tid = TypeId ("ns3::RraaWifiManager")
66  .SetGroupName ("Wifi")
67  .AddConstructor<RraaWifiManager> ()
68  .AddAttribute ("Basic",
69  "If true the RRAA-BASIC algorithm will be used, otherwise the RRAA wil be used",
70  BooleanValue (false),
73  .AddAttribute ("Timeout",
74  "Timeout for the RRAA BASIC loss estimation block (s)",
75  TimeValue (Seconds (0.05)),
77  MakeTimeChecker ())
78  .AddAttribute ("FrameLength",
79  "The data frame length (in bytes) used for calculating mode TxTime.",
80  UintegerValue (1420),
82  MakeUintegerChecker <uint32_t> ())
83  .AddAttribute ("AckFrameLength",
84  "The ACK frame length (in bytes) used for calculating mode TxTime.",
85  UintegerValue (14),
87  MakeUintegerChecker <uint32_t> ())
88  .AddAttribute ("Alpha",
89  "Constant for calculating the MTL threshold.",
90  DoubleValue (1.25),
92  MakeDoubleChecker<double> (1))
93  .AddAttribute ("Beta",
94  "Constant for calculating the ORI threshold.",
95  DoubleValue (2),
97  MakeDoubleChecker<double> (1))
98  .AddAttribute ("Tau",
99  "Constant for calculating the EWND size.",
100  DoubleValue (0.012),
102  MakeDoubleChecker<double> (0))
103  .AddTraceSource ("Rate",
104  "Traced value for rate changes (b/s)",
106  "ns3::TracedValueCallback::Uint64")
107  ;
108  return tid;
109 }
110 
111 
114  m_currentRate (0)
115 {
116 }
117 
119 {
120 }
121 
122 void
124 {
125  NS_LOG_FUNCTION (this);
126  uint32_t nModes = phy->GetNModes ();
127  for (uint32_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 (uint32_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 == GetMinRate (station))
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 uint32_t
273 {
274  return station->m_nRate - 1;
275 }
276 
277 uint32_t
279 {
280  return 0;
281 }
282 
283 void
285 {
286  NS_LOG_FUNCTION (this << st);
287 }
288 
289 void
291 {
292  NS_LOG_FUNCTION (this << st);
294  station->m_lastFrameFail = true;
295  CheckTimeout (station);
296  station->m_counter--;
297  station->m_nFailed++;
298  RunBasicAlgorithm (station);
299 }
300 
301 void
303  double rxSnr, WifiMode txMode)
304 {
305  NS_LOG_FUNCTION (this << st << rxSnr << txMode);
306 }
307 
308 void
310  double ctsSnr, WifiMode ctsMode, double rtsSnr)
311 {
312  NS_LOG_FUNCTION (this << st << ctsSnr << ctsMode << rtsSnr);
313  NS_LOG_DEBUG ("self=" << st << " rts ok");
314 }
315 
316 void
318  double ackSnr, WifiMode ackMode, double dataSnr)
319 {
320  NS_LOG_FUNCTION (this << st << ackSnr << ackMode << dataSnr);
322  station->m_lastFrameFail = false;
323  CheckTimeout (station);
324  station->m_counter--;
325  RunBasicAlgorithm (station);
326 }
327 
328 void
330 {
331  NS_LOG_FUNCTION (this << st);
332 }
333 
334 void
336 {
337  NS_LOG_FUNCTION (this << st);
338 }
339 
342 {
343  NS_LOG_FUNCTION (this << st);
345  uint32_t channelWidth = GetChannelWidth (station);
346  if (channelWidth > 20 && channelWidth != 22)
347  {
348  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
349  channelWidth = 20;
350  }
351  CheckInit (station);
352  WifiMode mode = GetSupported (station, station->m_rateIndex);
353  if (m_currentRate != mode.GetDataRate (channelWidth))
354  {
355  NS_LOG_DEBUG ("New datarate: " << mode.GetDataRate (channelWidth));
356  m_currentRate = mode.GetDataRate (channelWidth);
357  }
358  return WifiTxVector (mode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
359 }
360 
363 {
364  NS_LOG_FUNCTION (this << st);
366  uint32_t channelWidth = GetChannelWidth (station);
367  if (channelWidth > 20 && channelWidth != 22)
368  {
369  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
370  channelWidth = 20;
371  }
372  WifiTxVector rtsTxVector;
373  WifiMode mode;
374  if (GetUseNonErpProtection () == false)
375  {
376  mode = GetSupported (station, 0);
377  }
378  else
379  {
380  mode = GetNonErpSupported (station, 0);
381  }
382  rtsTxVector = WifiTxVector (mode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
383  return rtsTxVector;
384 }
385 
386 bool
388  Ptr<const Packet> packet, bool normally)
389 {
390  NS_LOG_FUNCTION (this << st << packet << normally);
392  CheckInit (station);
393  if (m_basic)
394  {
395  return normally;
396  }
397  ARts (station);
398  return station->m_adaptiveRtsOn;
399 }
400 
401 void
403 {
404  NS_LOG_FUNCTION (this << station);
405  Time d = Simulator::Now () - station->m_lastReset;
406  if (station->m_counter == 0 || d > m_timeout)
407  {
408  ResetCountersBasic (station);
409  }
410 }
411 
412 void
414 {
415  NS_LOG_FUNCTION (this << station);
416  WifiRraaThresholds thresholds = GetThresholds (station, station->m_rateIndex);
417  double ploss = (double) station->m_nFailed / (double) thresholds.m_ewnd;
418  if (station->m_counter == 0
419  || ploss > thresholds.m_mtl)
420  {
421  if (station->m_rateIndex > GetMinRate (station)
422  && ploss > thresholds.m_mtl)
423  {
424  station->m_rateIndex--;
425  }
426  else if (station->m_rateIndex < GetMaxRate (station)
427  && ploss < thresholds.m_ori)
428  {
429  station->m_rateIndex++;
430  }
431  ResetCountersBasic (station);
432  }
433 }
434 
435 void
437 {
438  if (!station->m_adaptiveRtsOn
439  && station->m_lastFrameFail)
440  {
441  station->m_adaptiveRtsWnd++;
442  station->m_rtsCounter = station->m_adaptiveRtsWnd;
443  }
444  else if ((station->m_adaptiveRtsOn && station->m_lastFrameFail)
445  || (!station->m_adaptiveRtsOn && !station->m_lastFrameFail))
446  {
447  station->m_adaptiveRtsWnd = station->m_adaptiveRtsWnd / 2;
448  station->m_rtsCounter = station->m_adaptiveRtsWnd;
449  }
450  if (station->m_rtsCounter > 0)
451  {
452  station->m_adaptiveRtsOn = true;
453  station->m_rtsCounter--;
454  }
455  else
456  {
457  station->m_adaptiveRtsOn = false;
458  }
459 }
460 
463  uint32_t rate) const
464 {
465  NS_LOG_FUNCTION (this << station << rate);
466  WifiMode mode = GetSupported (station, rate);
467  return GetThresholds (station, mode);
468 }
469 
470 bool
472 {
473  return true;
474 }
475 
476 void
478 {
479  //HT is not supported by this algorithm.
480  if (enable)
481  {
482  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HT rates");
483  }
484 }
485 
486 void
488 {
489  //VHT is not supported by this algorithm.
490  if (enable)
491  {
492  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support VHT rates");
493  }
494 }
495 
496 void
498 {
499  //HE is not supported by this algorithm.
500  if (enable)
501  {
502  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates");
503  }
504 }
505 
506 } //namespace ns3
uint32_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
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...
uint32_t GetMaxRate(RraaWifiRemoteStation *station)
Return the index for the maximum transmission rate for the given station.
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_rateIndex
Current rate index.
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:1270
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.
WifiMode GetSupported(const WifiRemoteStation *station, uint32_t i) const
Return whether mode associated with the specified station at the specified index. ...
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:2262
uint32_t m_nRate
Number of supported rates.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
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:1055
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
WifiMode GetNonErpSupported(const WifiRemoteStation *station, uint32_t i) const
Return whether non-ERP mode associated with the specified station at the specified index...
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 GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
uint32_t m_rtsCounter
Counter for RTS transmission attempts.
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.
uint32_t GetNModes(void) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:3541
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:1056
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
void SetVhtSupported(bool enable)
Enable or disable VHT capability support.
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...
WifiRraaThresholds structure.
void AddCalcTxTime(WifiMode mode, Time t)
Add transmission time for the given mode to an internal list.
uint32_t GetLongRetryCount(const WifiRemoteStation *station) const
Return the long retry limit of the given station.
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:993
void InitThresholds(RraaWifiRemoteStation *station)
Initialize the thresholds internal list for the given station.
void SetHeSupported(bool enable)
Enable or disable HE capability support.
hold per-remote-station state for RRAA Wifi manager.
uint32_t GetShortRetryCount(const WifiRemoteStation *station) const
Return the short retry limit of the given station.
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.
uint32_t GetMinRate(RraaWifiRemoteStation *station)
Return the index for the minimum 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.
WifiMode GetMode(uint32_t mode) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:3547
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.