A Discrete-Event Network Simulator
API
ideal-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) 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ideal-wifi-manager.h"
22 #include "wifi-phy.h"
23 #include "ns3/assert.h"
24 #include "ns3/double.h"
25 #include "ns3/log.h"
26 #include <cmath>
27 
28 namespace ns3 {
29 
37 {
39  double m_lastSnrCached;
40  double m_nss;
42 };
43 
45 
46 NS_LOG_COMPONENT_DEFINE ("IdealWifiManager");
47 
48 TypeId
50 {
51  static TypeId tid = TypeId ("ns3::IdealWifiManager")
53  .SetGroupName ("Wifi")
54  .AddConstructor<IdealWifiManager> ()
55  .AddAttribute ("BerThreshold",
56  "The maximum Bit Error Rate acceptable at any transmission mode",
57  DoubleValue (1e-5),
59  MakeDoubleChecker<double> ())
60  .AddTraceSource ("Rate",
61  "Traced value for rate changes (b/s)",
63  "ns3::TracedValueCallback::Uint64")
64  ;
65  return tid;
66 }
67 
69  : m_currentRate (0)
70 {
71 }
72 
74 {
75 }
76 
77 void
79 {
80  NS_LOG_FUNCTION (this << phy);
82 }
83 
84 uint32_t
86 {
89  if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS ||
91  {
92  return 22;
93  }
94  else
95  {
96  return 20;
97  }
98 }
99 
100 void
102 {
103  NS_LOG_FUNCTION (this);
104  WifiMode mode;
105  WifiTxVector txVector;
106  uint8_t nss = 1;
107  uint32_t nModes = GetPhy ()->GetNModes ();
108  txVector.SetShortGuardInterval (GetPhy ()->GetGuardInterval ());
109  for (uint32_t i = 0; i < nModes; i++)
110  {
111  mode = GetPhy ()->GetMode (i);
112  txVector.SetChannelWidth (GetChannelWidthForMode (mode));
113  txVector.SetNss (nss);
114  txVector.SetMode (mode);
115  NS_LOG_DEBUG ("Initialize, adding mode = " << mode.GetUniqueName () <<
116  " channel width " << txVector.GetChannelWidth () <<
117  " nss " << (uint16_t) nss <<
118  " short GI " << GetPhy ()->GetGuardInterval ());
119  AddSnrThreshold (txVector, GetPhy ()->CalculateSnr (txVector, m_ber));
120  }
121  // Add all Ht and Vht MCSes
122  txVector.SetChannelWidth (GetPhy ()->GetChannelWidth ());
123  if (HasVhtSupported () == true || HasHtSupported () == true )
124  {
125  nModes = GetPhy ()->GetNMcs ();
126  for (uint32_t i = 0; i < nModes; i++)
127  {
128  mode = GetPhy ()->GetMcs (i);
129  if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
130  {
131  //derive NSS from the Mcs index
132  nss = (mode.GetMcsValue () / 8) + 1;
133  }
134  else
135  {
137  }
138  NS_LOG_DEBUG ("Initialize, adding mode = " << mode.GetUniqueName () <<
139  " channel width " << GetPhy ()->GetChannelWidth () <<
140  " nss " << (uint16_t) nss <<
141  " short GI " << GetPhy ()->GetGuardInterval ());
142  NS_LOG_DEBUG ("In SetupPhy, adding mode = " << mode.GetUniqueName ());
143  txVector.SetNss (nss);
144  txVector.SetMode (mode);
145  AddSnrThreshold (txVector, GetPhy ()->CalculateSnr (txVector, m_ber));
146  }
147  }
148 }
149 
150 double
152 {
153  NS_LOG_FUNCTION (this << txVector.GetMode().GetUniqueName ());
154  for (Thresholds::const_iterator i = m_thresholds.begin (); i != m_thresholds.end (); i++)
155  {
156  NS_LOG_DEBUG ("Checking " << i->second.GetMode ().GetUniqueName () <<
157  " nss " << (uint16_t) i->second.GetNss () <<
158  " width " << i->second.GetChannelWidth ());
159  NS_LOG_DEBUG ("against TxVector " << txVector.GetMode ().GetUniqueName () <<
160  " nss " << (uint16_t) txVector.GetNss () <<
161  " width " << txVector.GetChannelWidth ());
162  if (txVector.GetMode () == i->second.GetMode () &&
163  txVector.GetNss () == i->second.GetNss () &&
164  txVector.IsShortGuardInterval () == i->second.IsShortGuardInterval () &&
165  txVector.GetChannelWidth () == i->second.GetChannelWidth ())
166  {
167  return i->first;
168  }
169  }
170  NS_ASSERT (false);
171  return 0.0;
172 }
173 
174 void
176 {
177  NS_LOG_FUNCTION (this << txVector.GetMode ().GetUniqueName () << snr);
178  m_thresholds.push_back (std::make_pair (snr, txVector));
179 }
180 
183 {
184  NS_LOG_FUNCTION (this);
186  station->m_lastSnrObserved = 0.0;
187  station->m_lastSnrCached = 0.0;
188  station->m_lastMode = GetDefaultMode ();
189  station->m_nss = 1;
190  return station;
191 }
192 
193 
194 void
196  double rxSnr, WifiMode txMode)
197 {
198 }
199 
200 void
202 {
203 }
204 
205 void
207 {
208 }
209 
210 void
212  double ctsSnr, WifiMode ctsMode, double rtsSnr)
213 {
214  NS_LOG_FUNCTION (this << st << ctsSnr << ctsMode.GetUniqueName () << rtsSnr);
216  station->m_lastSnrObserved = rtsSnr;
217 }
218 
219 void
221  double ackSnr, WifiMode ackMode, double dataSnr)
222 {
223  NS_LOG_FUNCTION (this << st << ackSnr << ackMode.GetUniqueName () << dataSnr);
225  if (dataSnr == 0)
226  {
227  NS_LOG_WARN ("DataSnr reported to be zero; not saving this report.");
228  return;
229  }
230  station->m_lastSnrObserved = dataSnr;
231 }
232 
233 void
234 IdealWifiManager::DoReportAmpduTxStatus (WifiRemoteStation *st, uint32_t nSuccessfulMpdus, uint32_t nFailedMpdus, double rxSnr, double dataSnr)
235 {
236  NS_LOG_FUNCTION (this << st << nSuccessfulMpdus << nFailedMpdus << rxSnr << dataSnr);
238  if (dataSnr == 0)
239  {
240  NS_LOG_WARN ("DataSnr reported to be zero; not saving this report.");
241  return;
242  }
243  station->m_lastSnrObserved = dataSnr;
244 }
245 
246 
247 void
249 {
250 }
251 
252 void
254 {
255 }
256 
259 {
260  NS_LOG_FUNCTION (this << st);
262  //We search within the Supported rate set the mode with the
263  //highest snr threshold possible which is smaller than m_lastSnr
264  //to ensure correct packet delivery.
265  double maxThreshold = 0.0;
266  WifiMode maxMode = GetDefaultMode ();
267  std::vector<WifiTxVector> candidateTxVectors;
268  WifiTxVector txVector;
269  WifiMode mode;
270  uint8_t nss = 1;
271  txVector.SetChannelWidth (GetPhy ()->GetChannelWidth ());
272  txVector.SetShortGuardInterval (GetPhy ()->GetGuardInterval ());
273  if (station->m_lastSnrObserved == station->m_lastSnrCached)
274  {
275  // SNR has not changed, so skip the search and use the last
276  // mode selected
277  maxMode = station->m_lastMode;
278  nss = station->m_nss;
279  NS_LOG_DEBUG ("Using cached mode = " << maxMode.GetUniqueName () <<
280  " last snr observed " << station->m_lastSnrObserved <<
281  " cached " << station->m_lastSnrCached);
282  }
283  else
284  {
285  if (HasVhtSupported () == true || HasHtSupported () == true)
286  {
287  for (uint32_t i = 0; i < GetNMcsSupported (station); i++)
288  {
289  mode = GetMcsSupported (station, i);
290  txVector.SetMode (mode);
291  if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
292  {
293  //derive NSS from the Mcs index
294  nss = (mode.GetMcsValue () / 8) + 1;
295  }
296  else
297  {
299  }
300  txVector.SetNss (nss);
301  if (WifiPhy::IsValidTxVector (txVector) == false)
302  {
303  NS_LOG_DEBUG ("Skipping mode " << mode.GetUniqueName () <<
304  " nss " << nss << " width " <<
305  txVector.GetChannelWidth());
306  continue;
307  }
308  double threshold = GetSnrThreshold (txVector);
309  // If the node and peer are both VHT capable, only search VHT modes
311  {
312  continue;
313  }
314  // If the node and peer are not both VHT capable, only search HT modes
315  if (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT && (!HasVhtSupported () || !GetVhtSupported (st)))
316  {
317  continue;
318  }
319  NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () <<
320  " threshold " << threshold << " maxThreshold " <<
321  maxThreshold << " last snr observed " <<
322  station->m_lastSnrObserved << " cached " <<
323  station->m_lastSnrCached);
324  if (threshold > maxThreshold && threshold < station->m_lastSnrObserved)
325  {
326  NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
327  " threshold " << threshold <<
328  " last snr observed " <<
329  station->m_lastSnrObserved);
330  maxThreshold = threshold;
331  maxMode = mode;
332  }
333  }
334  }
335  else
336  {
337  // Non-HT selection
338  nss = 1;
339  for (uint32_t i = 0; i < GetNSupported (station); i++)
340  {
341  mode = GetSupported (station, i);
342  txVector.SetMode (mode);
343  txVector.SetNss (nss);
344  txVector.SetChannelWidth (GetChannelWidthForMode (mode));
345  double threshold = GetSnrThreshold (txVector);
346  NS_LOG_DEBUG ("mode = " << mode.GetUniqueName () <<
347  " threshold " << threshold <<
348  " last snr observed " <<
349  station->m_lastSnrObserved);
350  if (threshold > maxThreshold && threshold < station->m_lastSnrObserved)
351  {
352  NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
353  " threshold " << threshold <<
354  " last snr observed " <<
355  station->m_lastSnrObserved);
356  maxThreshold = threshold;
357  maxMode = mode;
358  }
359  }
360  }
361  NS_LOG_DEBUG ("Updating cached values for station to " << maxMode.GetUniqueName () << " snr " << station->m_lastSnrObserved);
362  station->m_lastSnrCached = station->m_lastSnrObserved;
363  station->m_lastMode = maxMode;
364  station->m_nss = nss;
365  }
366  uint32_t channelWidth = GetChannelWidth (station);
367  NS_LOG_DEBUG ("Found maxMode: " << maxMode << " channelWidth: " << channelWidth);
368  if (m_currentRate != maxMode.GetDataRate (channelWidth, GetPhy ()->GetGuardInterval (), nss))
369  {
370  NS_LOG_DEBUG ("New datarate: " << maxMode.GetDataRate (channelWidth, GetPhy ()->GetGuardInterval (), nss));
371  m_currentRate = maxMode.GetDataRate (channelWidth, GetPhy ()->GetGuardInterval (), nss);
372  }
373  return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, nss, 0, channelWidth, GetAggregation (station), false);
374 }
375 
378 {
379  NS_LOG_FUNCTION (this << st);
381  //We search within the Basic rate set the mode with the highest
382  //snr threshold possible which is smaller than m_lastSnr to
383  //ensure correct packet delivery.
384  double maxThreshold = 0.0;
385  WifiTxVector txVector;
386  WifiMode mode;
387  uint8_t nss = 1;
388  WifiMode maxMode = GetDefaultMode ();
389  //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
390  // RTS is sent in a non-HT frame; RTS with (V)HT is not yet supported
391  txVector.SetShortGuardInterval (GetPhy ()->GetGuardInterval ());
392  for (uint32_t i = 0; i < GetNBasicModes (); i++)
393  {
394  mode = GetBasicMode (i);
395  txVector.SetMode (mode);
396  txVector.SetNss (nss);
397  txVector.SetChannelWidth (GetChannelWidthForMode (mode));
398  double threshold = GetSnrThreshold (txVector);
399  if (threshold > maxThreshold && threshold < station->m_lastSnrObserved)
400  {
401  maxThreshold = threshold;
402  maxMode = mode;
403  }
404  }
405  return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, nss, 0, GetChannelWidthForMode (maxMode), GetAggregation (station), false);
406 }
407 
408 bool
410 {
411  return true;
412 }
413 
414 } //namespace ns3
virtual void DoReportFinalDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
uint32_t GetNSupported(const WifiRemoteStation *station) const
Return the number of modes supported by the given station.
void SetShortGuardInterval(bool guardinterval)
Sets if short gurad interval is being used.
virtual bool IsLowLatency(void) const
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual bool GetGuardInterval(void) const
Return whether guard interval is being used.
Definition: wifi-phy.cc:579
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:44
virtual void DoReportFinalRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
virtual void SetupPhy(Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
enum WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:379
#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
bool IsShortGuardInterval(void) const
virtual 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.
virtual WifiTxVector DoGetDataTxVector(WifiRemoteStation *station)
virtual uint8_t GetNMcs(void) const
The WifiPhy::GetNMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of t...
Definition: wifi-phy.cc:2862
WifiMode GetMcsSupported(const WifiRemoteStation *station, uint32_t i) const
Return the WifiMode supported by the specified station at the specified index.
hold per-remote-station state for Ideal Wifi manager.
VHT PHY (Clause 22)
Definition: wifi-mode.h:64
HR/DSSS PHY (Clause 18)
Definition: wifi-mode.h:52
virtual void SetupPhy(Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
bool GetAggregation(const WifiRemoteStation *station) const
Return whether the given station supports A-MPDU.
virtual void DoInitialize(void)
Initialize() implementation.
WifiMode GetSupported(const WifiRemoteStation *station, uint32_t i) const
Return whether mode associated with the specified station at the specified index. ...
void SetChannelWidth(uint32_t channelWidth)
Sets the selected channelWidth (in MHz)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
virtual void DoReportRxOk(WifiRemoteStation *station, double rxSnr, WifiMode txMode)
This method is a pure virtual method that must be implemented by the sub-class.
Ptr< WifiPhy > GetPhy(void) const
Return the WifiPhy.
double GetSnrThreshold(WifiTxVector txVector) const
Return the minimum SNR needed to successfully transmit data with this WifiTxVector at the specified B...
static TypeId GetTypeId(void)
tuple phy
Definition: third.py:86
double m_ber
The maximum Bit Error Rate acceptable at any transmission mode.
WifiMode GetBasicMode(uint32_t i) const
Return a basic mode from the set of basic modes.
uint32_t GetChannelWidth(void) const
HT PHY (Clause 20)
Definition: wifi-mode.h:62
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:357
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:342
Thresholds m_thresholds
List of WifiTxVector and the minimum SNR pair.
double m_nss
SNR most recently used to select a rate.
double m_lastSnrObserved
SNR of most recently reported packet sent to the remote station.
virtual uint32_t GetNModes(void) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:2850
hold a list of per-remote-station state.
void SetNss(uint8_t nss)
Sets the number of Nss refer to IEEE 802.11n Table 20-28 for explanation and range.
virtual 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.
virtual WifiRemoteStation * DoCreateStation(void) const
virtual WifiMode GetMcs(uint8_t mcs) const
The WifiPhy::GetMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of tr...
Definition: wifi-phy.cc:2868
virtual uint32_t GetChannelWidth(void) const
Definition: wifi-phy.cc:1157
TracedValue< uint64_t > m_currentRate
Trace rate changes.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static bool IsValidTxVector(WifiTxVector txVector)
The standard disallows certain combinations of WifiMode, number of spatial streams, and channel widths.
Definition: wifi-phy.cc:2788
bool HasVhtSupported(void) const
Return whether the device has VHT capability support enabled.
uint64_t GetDataRate(uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
Definition: wifi-mode.cc:109
double m_lastSnrCached
SNR most recently used to select a rate.
bool HasHtSupported(void) const
Return whether the device has HT capability support enabled.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
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
virtual WifiTxVector DoGetRtsTxVector(WifiRemoteStation *station)
uint8_t GetNss(void) const
uint32_t GetNBasicModes(void) const
Return the number of basic modes we support.
uint32_t GetLongRetryCount(const WifiRemoteStation *station) const
Return the long retry limit of the given station.
virtual void DoReportAmpduTxStatus(WifiRemoteStation *station, uint32_t nSuccessfulMpdus, uint32_t nFailedMpdus, double rxSnr, double dataSnr)
Typically called per A-MPDU, either when a Block ACK was successfully received or when a BlockAckTime...
uint32_t GetNMcsSupported(const WifiRemoteStation *station) const
Return the number of MCS supported by the given station.
WifiMode GetDefaultMode(void) const
Return the default transmission mode.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
uint32_t GetChannelWidthForMode(WifiMode mode) const
Convenience function for selecting a channel width for legacy mode.
bool GetVhtSupported(const WifiRemoteStation *station) const
Return whether the given station is VHT capable.
virtual uint8_t GetSupportedTxSpatialStreams(void) const
Definition: wifi-phy.cc:1194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Ideal rate control algorithmThis class implements an 'ideal' rate control algorithm similar to RBAR i...
uint32_t GetChannelWidth(const WifiRemoteStation *station) const
Return the channel width supported by the station.
WifiMode m_lastMode
Mode most recently used to the remote station.
uint32_t GetShortRetryCount(const WifiRemoteStation *station) const
Return the short retry limit of the given station.
virtual void DoReportDataFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
WifiMode GetMode(void) const
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
a unique identifier for an interface.
Definition: type-id.h:58
virtual void DoReportRtsFailed(WifiRemoteStation *station)
This method is a pure virtual method that must be implemented by the sub-class.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
hold per-remote-station state.
DSSS PHY (Clause 15)
Definition: wifi-mode.h:50
void AddSnrThreshold(WifiTxVector txVector, double snr)
Adds a pair of WifiTxVector and the minimum SNR for that given vector to the list.
virtual WifiMode GetMode(uint32_t mode) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:2856