A Discrete-Event Network Simulator
API
parf-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) 2014 Universidad de la República - Uruguay
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: Matias Richart <mrichart@fing.edu.uy>
19  */
20 
21 #include "parf-wifi-manager.h"
22 #include "wifi-phy.h"
23 #include "ns3/log.h"
24 #include "ns3/uinteger.h"
25 
26 #define Min(a,b) ((a < b) ? a : b)
27 
28 namespace ns3 {
29 
30 NS_LOG_COMPONENT_DEFINE ("ParfWifiManager");
31 
39 {
40  uint32_t m_nAttempt;
41  uint32_t m_nSuccess;
42  uint32_t m_nFail;
45  uint32_t m_nRetry;
46  uint32_t m_prevRateIndex;
47  uint32_t m_rateIndex;
48  uint8_t m_prevPowerLevel;
49  uint8_t m_powerLevel;
50  uint32_t m_nSupported;
52 };
53 
55 
56 TypeId
58 {
59  static TypeId tid = TypeId ("ns3::ParfWifiManager")
61  .SetGroupName ("Wifi")
62  .AddConstructor<ParfWifiManager> ()
63  .AddAttribute ("AttemptThreshold",
64  "The minimum number of transmission attempts to try a new power or rate.",
65  UintegerValue (15),
67  MakeUintegerChecker<uint32_t> ())
68  .AddAttribute ("SuccessThreshold",
69  "The minimum number of successful transmissions to try a new power or rate.",
70  UintegerValue (10),
72  MakeUintegerChecker<uint32_t> ())
73  .AddTraceSource ("PowerChange",
74  "The transmission power has change",
76  "ns3::WifiRemoteStationManager::PowerChangeTracedCallback")
77  .AddTraceSource ("RateChange",
78  "The transmission rate has change",
80  "ns3::WifiRemoteStationManager::RateChangeTracedCallback")
81  ;
82  return tid;
83 }
84 
86 {
87  NS_LOG_FUNCTION (this);
88 }
89 
91 {
92  NS_LOG_FUNCTION (this);
93 }
94 
95 void
97 {
98  m_minPower = phy->GetTxPowerStart ();
99  m_maxPower = phy->GetTxPowerEnd ();
101 }
102 
105 {
106  NS_LOG_FUNCTION (this);
108 
109  station->m_nSuccess = 0;
110  station->m_nFail = 0;
111  station->m_usingRecoveryRate = false;
112  station->m_usingRecoveryPower = false;
113  station->m_initialized = false;
114  station->m_nRetry = 0;
115  station->m_nAttempt = 0;
116 
117  NS_LOG_DEBUG ("create station=" << station << ", timer=" << station->m_nAttempt
118  << ", rate=" << station->m_rateIndex << ", power=" << (int)station->m_powerLevel);
119 
120  return station;
121 }
122 
123 void
125 {
126  if (!station->m_initialized)
127  {
128  station->m_nSupported = GetNSupported (station);
129  station->m_rateIndex = station->m_nSupported - 1;
130  station->m_prevRateIndex = station->m_nSupported - 1;
131  station->m_powerLevel = m_maxPower;
132  station->m_prevPowerLevel = m_maxPower;
133  WifiMode mode = GetSupported (station, station->m_rateIndex);
134  uint8_t channelWidth = GetChannelWidth (station);
135  DataRate rate = DataRate (mode.GetDataRate (channelWidth));
136  double power = GetPhy ()->GetPowerDbm (m_maxPower);
137  m_powerChange (power, power, station->m_state->m_address);
138  m_rateChange (rate, rate, station->m_state->m_address);
139  station->m_initialized = true;
140  }
141 }
142 
143 void
145 {
146  NS_LOG_FUNCTION (this << station);
147 }
148 
149 /*
150  * It is important to realize that "recovery" mode starts after failure of
151  * the first transmission after a rate increase and ends at the first successful
152  * transmission. Specifically, recovery mode spans retransmissions boundaries.
153  * Fundamentally, ARF handles each data transmission independently, whether it
154  * is the initial transmission of a packet or the retransmission of a packet.
155  * The fundamental reason for this is that there is a backoff between each data
156  * transmission, be it an initial transmission or a retransmission.
157  */
158 void
160 {
161  NS_LOG_FUNCTION (this << st);
163  CheckInit (station);
164  station->m_nAttempt++;
165  station->m_nFail++;
166  station->m_nRetry++;
167  station->m_nSuccess = 0;
168 
169  NS_LOG_DEBUG ("station=" << station << " data fail retry=" << station->m_nRetry << ", timer=" << station->m_nAttempt
170  << ", rate=" << station->m_rateIndex << ", power=" << (int)station->m_powerLevel);
171  if (station->m_usingRecoveryRate)
172  {
173  NS_ASSERT (station->m_nRetry >= 1);
174  if (station->m_nRetry == 1)
175  {
176  //need recovery fallback
177  if (station->m_rateIndex != 0)
178  {
179  NS_LOG_DEBUG ("station=" << station << " dec rate");
180  station->m_rateIndex--;
181  station->m_usingRecoveryRate = false;
182  }
183  }
184  station->m_nAttempt = 0;
185  }
186  else if (station->m_usingRecoveryPower)
187  {
188  NS_ASSERT (station->m_nRetry >= 1);
189  if (station->m_nRetry == 1)
190  {
191  //need recovery fallback
192  if (station->m_powerLevel < m_maxPower)
193  {
194  NS_LOG_DEBUG ("station=" << station << " inc power");
195  station->m_powerLevel++;
196  station->m_usingRecoveryPower = false;
197  }
198  }
199  station->m_nAttempt = 0;
200  }
201  else
202  {
203  NS_ASSERT (station->m_nRetry >= 1);
204  if (((station->m_nRetry - 1) % 2) == 1)
205  {
206  //need normal fallback
207  if (station->m_powerLevel == m_maxPower)
208  {
209  if (station->m_rateIndex != 0)
210  {
211  NS_LOG_DEBUG ("station=" << station << " dec rate");
212  station->m_rateIndex--;
213  }
214  }
215  else
216  {
217  NS_LOG_DEBUG ("station=" << station << " inc power");
218  station->m_powerLevel++;
219  }
220  }
221  if (station->m_nRetry >= 2)
222  {
223  station->m_nAttempt = 0;
224  }
225  }
226 }
227 
228 void
230  double rxSnr, WifiMode txMode)
231 {
232  NS_LOG_FUNCTION (this << station << rxSnr << txMode);
233 }
234 
236  double ctsSnr, WifiMode ctsMode, double rtsSnr)
237 {
238  NS_LOG_FUNCTION (this << station << ctsSnr << ctsMode << rtsSnr);
239  NS_LOG_DEBUG ("station=" << station << " rts ok");
240 }
241 
243  double ackSnr, WifiMode ackMode, double dataSnr)
244 {
245  NS_LOG_FUNCTION (this << st << ackSnr << ackMode << dataSnr);
247  CheckInit (station);
248  station->m_nAttempt++;
249  station->m_nSuccess++;
250  station->m_nFail = 0;
251  station->m_usingRecoveryRate = false;
252  station->m_usingRecoveryPower = false;
253  station->m_nRetry = 0;
254  NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_nSuccess << ", timer=" << station->m_nAttempt << ", rate=" << station->m_rateIndex << ", power=" << (int)station->m_powerLevel);
255  if ((station->m_nSuccess == m_successThreshold
256  || station->m_nAttempt == m_attemptThreshold)
257  && (station->m_rateIndex < (station->m_state->m_operationalRateSet.size () - 1)))
258  {
259  NS_LOG_DEBUG ("station=" << station << " inc rate");
260  station->m_rateIndex++;
261  station->m_nAttempt = 0;
262  station->m_nSuccess = 0;
263  station->m_usingRecoveryRate = true;
264  }
265  else if (station->m_nSuccess == m_successThreshold || station->m_nAttempt == m_attemptThreshold)
266  {
267  //we are at the maximum rate, we decrease power
268  if (station->m_powerLevel != m_minPower)
269  {
270  NS_LOG_DEBUG ("station=" << station << " dec power");
271  station->m_powerLevel--;
272  }
273  station->m_nAttempt = 0;
274  station->m_nSuccess = 0;
275  station->m_usingRecoveryPower = true;
276  }
277 }
278 
279 void
281 {
282  NS_LOG_FUNCTION (this << station);
283 }
284 
285 void
287 {
288  NS_LOG_FUNCTION (this << station);
289 }
290 
293 {
294  NS_LOG_FUNCTION (this << st);
296  uint32_t channelWidth = GetChannelWidth (station);
297  if (channelWidth > 20 && channelWidth != 22)
298  {
299  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
300  channelWidth = 20;
301  }
302  CheckInit (station);
303  WifiMode mode = GetSupported (station, station->m_rateIndex);
304  DataRate rate = DataRate (mode.GetDataRate (channelWidth));
305  DataRate prevRate = DataRate (GetSupported (station, station->m_prevRateIndex).GetDataRate (channelWidth));
306  double power = GetPhy ()->GetPowerDbm (station->m_powerLevel);
307  double prevPower = GetPhy ()->GetPowerDbm (station->m_prevPowerLevel);
308  if (station->m_prevPowerLevel != station->m_powerLevel)
309  {
310  m_powerChange (prevPower, power, station->m_state->m_address);
311  station->m_prevPowerLevel = station->m_powerLevel;
312  }
313  if (station->m_prevRateIndex != station->m_rateIndex)
314  {
315  m_rateChange (prevRate, rate, station->m_state->m_address);
316  station->m_prevRateIndex = station->m_rateIndex;
317  }
318  return WifiTxVector (mode, station->m_powerLevel, GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
319 }
320 
323 {
324  NS_LOG_FUNCTION (this << st);
328  uint32_t channelWidth = GetChannelWidth (station);
329  if (channelWidth > 20 && channelWidth != 22)
330  {
331  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
332  channelWidth = 20;
333  }
334  WifiTxVector rtsTxVector;
335  WifiMode mode;
336  if (GetUseNonErpProtection () == false)
337  {
338  mode = GetSupported (station, 0);
339  }
340  else
341  {
342  mode = GetNonErpSupported (station, 0);
343  }
344  rtsTxVector = WifiTxVector (mode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
345  return rtsTxVector;
346 }
347 
348 bool
350 {
351  NS_LOG_FUNCTION (this);
352  return true;
353 }
354 
355 void
357 {
358  //HT is not supported by this algorithm.
359  if (enable)
360  {
361  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HT rates");
362  }
363 }
364 
365 void
367 {
368  //VHT is not supported by this algorithm.
369  if (enable)
370  {
371  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support VHT rates");
372  }
373 }
374 
375 void
377 {
378  //HE is not supported by this algorithm.
379  if (enable)
380  {
381  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates");
382  }
383 }
384 
385 } //namespace ns3
uint8_t m_powerLevel
Current power level used by the remote station.
uint32_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Hold per-remote-station state for PARF Wifi manager.
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
uint32_t m_maxPower
Maximal power level.
bool GetUseNonErpProtection(void) const
Return whether the device supports protection of non-ERP stations.
TracedCallback< DataRate, DataRate, Mac48Address > m_rateChange
The trace source fired when the transmission rate changes.
#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
void CheckInit(ParfWifiRemoteStation *station)
Check for initializations.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint32_t m_nAttempt
Number of transmission attempts.
Mac48Address m_address
Mac48Address of the remote station.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
TracedCallback< double, double, Mac48Address > m_powerChange
The trace source fired when the transmission power changes.
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. ...
void DoReportDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
WifiRemoteStationState * m_state
Remote station state.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Class for representing data rates.
Definition: data-rate.h:88
Ptr< WifiPhy > GetPhy(void) const
Return the WifiPhy.
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.
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:726
void SetVhtSupported(bool enable)
Enable or disable VHT capability support.
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.
void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode)
This method is a pure virtual method that must be implemented by the sub-class.
tuple phy
Definition: third.py:86
void SetHtSupported(bool enable)
Enable or disable HT capability support.
uint32_t m_successThreshold
The minimum number of successful transmissions to try a new power or rate.
WifiRemoteStation * DoCreateStation(void) const
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...
void DoReportRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
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
void DoReportFinalDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
uint8_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
Mac48Address GetAddress(const WifiRemoteStation *station) const
Return the address of the station.
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.
uint32_t m_minPower
Minimal power level.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double GetTxPowerEnd(void) const
Return the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:546
bool m_initialized
For initializing variables.
WifiModeList m_operationalRateSet
This member is the list of WifiMode objects that comprise the OperationalRateSet parameter for this r...
uint32_t m_rateIndex
Current rate index used by the remote station.
PARF Rate control algorithm.
uint32_t m_nSupported
Number of supported rates by the remote station.
uint32_t m_nRetry
Number of transmission retries.
void SetHeSupported(bool enable)
Enable or disable HE capability support.
uint32_t GetLongRetryCount(const WifiRemoteStation *station) const
Return the long retry limit of the given station.
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...
static TypeId GetTypeId(void)
Register this type.
uint32_t m_nFail
Number of failed transmission attempts.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
uint32_t m_nSuccess
Number of successful transmission attempts.
bool IsLowLatency(void) const
uint32_t m_prevRateIndex
Rate index of the previous transmission.
uint32_t GetShortRetryCount(const WifiRemoteStation *station) const
Return the short retry limit of the given station.
bool m_usingRecoveryRate
If using recovery rate.
WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station)
bool m_usingRecoveryPower
If using recovery power.
WifiTxVector DoGetDataTxVector(WifiRemoteStation *station)
void DoReportFinalRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
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.
uint32_t m_attemptThreshold
The minimum number of transmission attempts to try a new power or rate.
double GetTxPowerStart(void) const
Return the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:533
uint8_t m_prevPowerLevel
Power level of the previous transmission.