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  uint8_t m_prevRateIndex;
47  uint8_t m_rateIndex;
48  uint8_t m_prevPowerLevel;
49  uint8_t m_powerLevel;
50  uint8_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  NS_LOG_FUNCTION (this << phy);
99  m_minPower = phy->GetTxPowerStart ();
100  m_maxPower = phy->GetTxPowerEnd ();
102 }
103 
106 {
107  NS_LOG_FUNCTION (this);
109 
110  station->m_nSuccess = 0;
111  station->m_nFail = 0;
112  station->m_usingRecoveryRate = false;
113  station->m_usingRecoveryPower = false;
114  station->m_initialized = false;
115  station->m_nRetry = 0;
116  station->m_nAttempt = 0;
117 
118  NS_LOG_DEBUG ("create station=" << station << ", timer=" << station->m_nAttempt
119  << ", rate=" << +station->m_rateIndex << ", power=" << +station->m_powerLevel);
120 
121  return station;
122 }
123 
124 void
126 {
127  if (!station->m_initialized)
128  {
129  station->m_nSupported = GetNSupported (station);
130  station->m_rateIndex = station->m_nSupported - 1;
131  station->m_prevRateIndex = station->m_nSupported - 1;
132  station->m_powerLevel = m_maxPower;
133  station->m_prevPowerLevel = m_maxPower;
134  WifiMode mode = GetSupported (station, station->m_rateIndex);
135  uint8_t channelWidth = GetChannelWidth (station);
136  DataRate rate = DataRate (mode.GetDataRate (channelWidth));
137  double power = GetPhy ()->GetPowerDbm (m_maxPower);
138  m_powerChange (power, power, station->m_state->m_address);
139  m_rateChange (rate, rate, station->m_state->m_address);
140  station->m_initialized = true;
141  }
142 }
143 
144 void
146 {
147  NS_LOG_FUNCTION (this << station);
148 }
149 
150 /*
151  * It is important to realize that "recovery" mode starts after failure of
152  * the first transmission after a rate increase and ends at the first successful
153  * transmission. Specifically, recovery mode spans retransmissions boundaries.
154  * Fundamentally, ARF handles each data transmission independently, whether it
155  * is the initial transmission of a packet or the retransmission of a packet.
156  * The fundamental reason for this is that there is a backoff between each data
157  * transmission, be it an initial transmission or a retransmission.
158  */
159 void
161 {
162  NS_LOG_FUNCTION (this << st);
164  CheckInit (station);
165  station->m_nAttempt++;
166  station->m_nFail++;
167  station->m_nRetry++;
168  station->m_nSuccess = 0;
169 
170  NS_LOG_DEBUG ("station=" << station << " data fail retry=" << station->m_nRetry << ", timer=" << station->m_nAttempt
171  << ", rate=" << +station->m_rateIndex << ", power=" << +station->m_powerLevel);
172  if (station->m_usingRecoveryRate)
173  {
174  NS_ASSERT (station->m_nRetry >= 1);
175  if (station->m_nRetry == 1)
176  {
177  //need recovery fallback
178  if (station->m_rateIndex != 0)
179  {
180  NS_LOG_DEBUG ("station=" << station << " dec rate");
181  station->m_rateIndex--;
182  station->m_usingRecoveryRate = false;
183  }
184  }
185  station->m_nAttempt = 0;
186  }
187  else if (station->m_usingRecoveryPower)
188  {
189  NS_ASSERT (station->m_nRetry >= 1);
190  if (station->m_nRetry == 1)
191  {
192  //need recovery fallback
193  if (station->m_powerLevel < m_maxPower)
194  {
195  NS_LOG_DEBUG ("station=" << station << " inc power");
196  station->m_powerLevel++;
197  station->m_usingRecoveryPower = false;
198  }
199  }
200  station->m_nAttempt = 0;
201  }
202  else
203  {
204  NS_ASSERT (station->m_nRetry >= 1);
205  if (((station->m_nRetry - 1) % 2) == 1)
206  {
207  //need normal fallback
208  if (station->m_powerLevel == m_maxPower)
209  {
210  if (station->m_rateIndex != 0)
211  {
212  NS_LOG_DEBUG ("station=" << station << " dec rate");
213  station->m_rateIndex--;
214  }
215  }
216  else
217  {
218  NS_LOG_DEBUG ("station=" << station << " inc power");
219  station->m_powerLevel++;
220  }
221  }
222  if (station->m_nRetry >= 2)
223  {
224  station->m_nAttempt = 0;
225  }
226  }
227 }
228 
229 void
231  double rxSnr, WifiMode txMode)
232 {
233  NS_LOG_FUNCTION (this << station << rxSnr << txMode);
234 }
235 
237  double ctsSnr, WifiMode ctsMode, double rtsSnr)
238 {
239  NS_LOG_FUNCTION (this << station << ctsSnr << ctsMode << rtsSnr);
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=" << +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  uint8_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, GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
319 }
320 
323 {
324  NS_LOG_FUNCTION (this << st);
328  uint8_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 (), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
345  return rtsTxVector;
346 }
347 
348 bool
350 {
351  return true;
352 }
353 
354 void
356 {
357  //HT is not supported by this algorithm.
358  if (enable)
359  {
360  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HT rates");
361  }
362 }
363 
364 void
366 {
367  //VHT is not supported by this algorithm.
368  if (enable)
369  {
370  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support VHT rates");
371  }
372 }
373 
374 void
376 {
377  //HE is not supported by this algorithm.
378  if (enable)
379  {
380  NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates");
381  }
382 }
383 
384 } //namespace ns3
uint8_t m_powerLevel
Current power level used by the remote 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.
uint8_t m_maxPower
Maximal power level.
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
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.
uint8_t m_nSupported
Number of supported rates by the remote station.
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.
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:716
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
uint8_t m_rateIndex
Current rate index used by the remote station.
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.
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:530
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...
PARF Rate control algorithm.
uint8_t m_minPower
Minimal power level.
uint32_t m_nRetry
Number of transmission retries.
void SetHeSupported(bool enable)
Enable or disable HE capability support.
WifiMode GetSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether mode associated with the specified station at the specified index. ...
uint8_t m_prevRateIndex
Rate index of the previous transmission.
WifiMode GetNonErpSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether non-ERP mode associated with the specified station at the specified index...
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.
uint8_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
bool IsLowLatency(void) const
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:517
uint8_t m_prevPowerLevel
Power level of the previous transmission.