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 "ns3/log.h"
22 #include "ns3/uinteger.h"
23 #include "ns3/data-rate.h"
24 #include "parf-wifi-manager.h"
25 #include "wifi-phy.h"
26 
27 #define Min(a,b) ((a < b) ? a : b)
28 
29 namespace ns3 {
30 
31 NS_LOG_COMPONENT_DEFINE ("ParfWifiManager");
32 
40 {
41  uint32_t m_nAttempt;
42  uint32_t m_nSuccess;
43  uint32_t m_nFail;
46  uint32_t m_nRetry;
47  uint8_t m_prevRateIndex;
48  uint8_t m_rateIndex;
49  uint8_t m_prevPowerLevel;
50  uint8_t m_powerLevel;
51  uint8_t m_nSupported;
53 };
54 
56 
57 TypeId
59 {
60  static TypeId tid = TypeId ("ns3::ParfWifiManager")
62  .SetGroupName ("Wifi")
63  .AddConstructor<ParfWifiManager> ()
64  .AddAttribute ("AttemptThreshold",
65  "The minimum number of transmission attempts to try a new power or rate.",
66  UintegerValue (15),
68  MakeUintegerChecker<uint32_t> ())
69  .AddAttribute ("SuccessThreshold",
70  "The minimum number of successful transmissions to try a new power or rate.",
71  UintegerValue (10),
73  MakeUintegerChecker<uint32_t> ())
74  .AddTraceSource ("PowerChange",
75  "The transmission power has change",
77  "ns3::WifiRemoteStationManager::PowerChangeTracedCallback")
78  .AddTraceSource ("RateChange",
79  "The transmission rate has change",
81  "ns3::WifiRemoteStationManager::RateChangeTracedCallback")
82  ;
83  return tid;
84 }
85 
87 {
88  NS_LOG_FUNCTION (this);
89 }
90 
92 {
93  NS_LOG_FUNCTION (this);
94 }
95 
96 void
98 {
99  NS_LOG_FUNCTION (this << phy);
100  m_minPower = 0;
101  m_maxPower = phy->GetNTxPower () - 1;
103 }
104 
107 {
108  NS_LOG_FUNCTION (this);
110 
111  station->m_nSuccess = 0;
112  station->m_nFail = 0;
113  station->m_usingRecoveryRate = false;
114  station->m_usingRecoveryPower = false;
115  station->m_initialized = false;
116  station->m_nRetry = 0;
117  station->m_nAttempt = 0;
118 
119  NS_LOG_DEBUG ("create station=" << station << ", timer=" << station->m_nAttempt
120  << ", rate=" << +station->m_rateIndex << ", power=" << +station->m_powerLevel);
121 
122  return station;
123 }
124 
125 void
127 {
128  if (!station->m_initialized)
129  {
130  station->m_nSupported = GetNSupported (station);
131  station->m_rateIndex = station->m_nSupported - 1;
132  station->m_prevRateIndex = station->m_nSupported - 1;
133  station->m_powerLevel = m_maxPower;
134  station->m_prevPowerLevel = m_maxPower;
135  WifiMode mode = GetSupported (station, station->m_rateIndex);
136  uint16_t channelWidth = GetChannelWidth (station);
137  DataRate rate = DataRate (mode.GetDataRate (channelWidth));
138  double power = GetPhy ()->GetPowerDbm (m_maxPower);
139  m_powerChange (power, power, station->m_state->m_address);
140  m_rateChange (rate, rate, station->m_state->m_address);
141  station->m_initialized = true;
142  }
143 }
144 
145 void
147 {
148  NS_LOG_FUNCTION (this << station);
149 }
150 
151 /*
152  * It is important to realize that "recovery" mode starts after failure of
153  * the first transmission after a rate increase and ends at the first successful
154  * transmission. Specifically, recovery mode spans retransmissions boundaries.
155  * Fundamentally, ARF handles each data transmission independently, whether it
156  * is the initial transmission of a packet or the retransmission of a packet.
157  * The fundamental reason for this is that there is a backoff between each data
158  * transmission, be it an initial transmission or a retransmission.
159  */
160 void
162 {
163  NS_LOG_FUNCTION (this << st);
165  CheckInit (station);
166  station->m_nAttempt++;
167  station->m_nFail++;
168  station->m_nRetry++;
169  station->m_nSuccess = 0;
170 
171  NS_LOG_DEBUG ("station=" << station << " data fail retry=" << station->m_nRetry << ", timer=" << station->m_nAttempt
172  << ", rate=" << +station->m_rateIndex << ", power=" << +station->m_powerLevel);
173  if (station->m_usingRecoveryRate)
174  {
175  NS_ASSERT (station->m_nRetry >= 1);
176  if (station->m_nRetry == 1)
177  {
178  //need recovery fallback
179  if (station->m_rateIndex != 0)
180  {
181  NS_LOG_DEBUG ("station=" << station << " dec rate");
182  station->m_rateIndex--;
183  station->m_usingRecoveryRate = false;
184  }
185  }
186  station->m_nAttempt = 0;
187  }
188  else if (station->m_usingRecoveryPower)
189  {
190  NS_ASSERT (station->m_nRetry >= 1);
191  if (station->m_nRetry == 1)
192  {
193  //need recovery fallback
194  if (station->m_powerLevel < m_maxPower)
195  {
196  NS_LOG_DEBUG ("station=" << station << " inc power");
197  station->m_powerLevel++;
198  station->m_usingRecoveryPower = false;
199  }
200  }
201  station->m_nAttempt = 0;
202  }
203  else
204  {
205  NS_ASSERT (station->m_nRetry >= 1);
206  if (((station->m_nRetry - 1) % 2) == 1)
207  {
208  //need normal fallback
209  if (station->m_powerLevel == m_maxPower)
210  {
211  if (station->m_rateIndex != 0)
212  {
213  NS_LOG_DEBUG ("station=" << station << " dec rate");
214  station->m_rateIndex--;
215  }
216  }
217  else
218  {
219  NS_LOG_DEBUG ("station=" << station << " inc power");
220  station->m_powerLevel++;
221  }
222  }
223  if (station->m_nRetry >= 2)
224  {
225  station->m_nAttempt = 0;
226  }
227  }
228 }
229 
230 void
232  double rxSnr, WifiMode txMode)
233 {
234  NS_LOG_FUNCTION (this << station << rxSnr << txMode);
235 }
236 
238  double ctsSnr, WifiMode ctsMode, double rtsSnr)
239 {
240  NS_LOG_FUNCTION (this << station << ctsSnr << ctsMode << rtsSnr);
241 }
242 
244  double ackSnr, WifiMode ackMode, double dataSnr)
245 {
246  NS_LOG_FUNCTION (this << st << ackSnr << ackMode << dataSnr);
248  CheckInit (station);
249  station->m_nAttempt++;
250  station->m_nSuccess++;
251  station->m_nFail = 0;
252  station->m_usingRecoveryRate = false;
253  station->m_usingRecoveryPower = false;
254  station->m_nRetry = 0;
255  NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_nSuccess << ", timer=" << station->m_nAttempt << ", rate=" << +station->m_rateIndex << ", power=" << +station->m_powerLevel);
256  if ((station->m_nSuccess == m_successThreshold
257  || station->m_nAttempt == m_attemptThreshold)
258  && (station->m_rateIndex < (station->m_state->m_operationalRateSet.size () - 1)))
259  {
260  NS_LOG_DEBUG ("station=" << station << " inc rate");
261  station->m_rateIndex++;
262  station->m_nAttempt = 0;
263  station->m_nSuccess = 0;
264  station->m_usingRecoveryRate = true;
265  }
266  else if (station->m_nSuccess == m_successThreshold || station->m_nAttempt == m_attemptThreshold)
267  {
268  //we are at the maximum rate, we decrease power
269  if (station->m_powerLevel != m_minPower)
270  {
271  NS_LOG_DEBUG ("station=" << station << " dec power");
272  station->m_powerLevel--;
273  }
274  station->m_nAttempt = 0;
275  station->m_nSuccess = 0;
276  station->m_usingRecoveryPower = true;
277  }
278 }
279 
280 void
282 {
283  NS_LOG_FUNCTION (this << station);
284 }
285 
286 void
288 {
289  NS_LOG_FUNCTION (this << station);
290 }
291 
294 {
295  NS_LOG_FUNCTION (this << st);
297  uint16_t channelWidth = GetChannelWidth (station);
298  if (channelWidth > 20 && channelWidth != 22)
299  {
300  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
301  channelWidth = 20;
302  }
303  CheckInit (station);
304  WifiMode mode = GetSupported (station, station->m_rateIndex);
305  DataRate rate = DataRate (mode.GetDataRate (channelWidth));
306  DataRate prevRate = DataRate (GetSupported (station, station->m_prevRateIndex).GetDataRate (channelWidth));
307  double power = GetPhy ()->GetPowerDbm (station->m_powerLevel);
308  double prevPower = GetPhy ()->GetPowerDbm (station->m_prevPowerLevel);
309  if (station->m_prevPowerLevel != station->m_powerLevel)
310  {
311  m_powerChange (prevPower, power, station->m_state->m_address);
312  station->m_prevPowerLevel = station->m_powerLevel;
313  }
314  if (station->m_prevRateIndex != station->m_rateIndex)
315  {
316  m_rateChange (prevRate, rate, station->m_state->m_address);
317  station->m_prevRateIndex = station->m_rateIndex;
318  }
319  return WifiTxVector (mode, station->m_powerLevel, GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
320 }
321 
324 {
325  NS_LOG_FUNCTION (this << st);
329  uint16_t channelWidth = GetChannelWidth (station);
330  if (channelWidth > 20 && channelWidth != 22)
331  {
332  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
333  channelWidth = 20;
334  }
335  WifiTxVector rtsTxVector;
336  WifiMode mode;
337  if (GetUseNonErpProtection () == false)
338  {
339  mode = GetSupported (station, 0);
340  }
341  else
342  {
343  mode = GetNonErpSupported (station, 0);
344  }
345  rtsTxVector = WifiTxVector (mode, GetDefaultTxPowerLevel (), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
346  return rtsTxVector;
347 }
348 
349 bool
351 {
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.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint8_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
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
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:202
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.
WifiMode GetSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether mode associated with the specified station at the specified index. ...
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
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.
phy
Definition: third.py:86
Class for representing data rates.
Definition: data-rate.h:88
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 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.
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.
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.
void DoReportFinalDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
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.
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:700
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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.
bool IsLowLatency(void) const
Mac48Address GetAddress(const WifiRemoteStation *station) const
Return the address of the station.
WifiMode GetNonErpSupported(const WifiRemoteStation *station, uint8_t i) const
Return whether non-ERP mode associated with the specified station at the specified index...
uint32_t m_nRetry
Number of transmission retries.
void SetHeSupported(bool enable)
Enable or disable HE capability support.
bool GetAggregation(const WifiRemoteStation *station) const
Return whether the given station supports A-MPDU.
uint8_t m_prevRateIndex
Rate index of the previous transmission.
Ptr< WifiPhy > GetPhy(void) const
Return the WifiPhy.
WifiRemoteStation * DoCreateStation(void) const
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.
bool GetUseNonErpProtection(void) const
Return whether the device supports protection of non-ERP stations.
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:270
uint32_t m_nSuccess
Number of successful transmission attempts.
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:915
hold per-remote-station state.
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:156
uint32_t m_attemptThreshold
The minimum number of transmission attempts to try a new power or rate.
uint16_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
uint8_t m_prevPowerLevel
Power level of the previous transmission.