A Discrete-Event Network Simulator
API
wifi-mode.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006,2007 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  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  * Sébastien Deronne <sebastien.deronne@gmail.com>
20  */
21 
22 #include <cmath>
23 #include "ns3/log.h"
24 #include "wifi-mode.h"
25 #include "wifi-tx-vector.h"
26 #include "ns3/he-ru.h"
27 
28 namespace ns3 {
29 
30 bool operator == (const WifiMode &a, const WifiMode &b)
31 {
32  return a.GetUid () == b.GetUid ();
33 }
34 
35 bool operator != (const WifiMode &a, const WifiMode &b)
36 {
37  return a.GetUid () != b.GetUid ();
38 }
39 
40 bool operator < (const WifiMode &a, const WifiMode &b)
41 {
42  return a.GetUid () < b.GetUid ();
43 }
44 
45 std::ostream & operator << (std::ostream & os, const WifiMode &mode)
46 {
47  os << mode.GetUniqueName ();
48  return os;
49 }
50 
51 std::istream & operator >> (std::istream &is, WifiMode &mode)
52 {
53  std::string str;
54  is >> str;
55  mode = WifiModeFactory::GetFactory ()->Search (str);
56  return is;
57 }
58 
59 bool
60 WifiMode::IsAllowed (uint16_t channelWidth, uint8_t nss) const
61 {
63  return item->IsModeAllowedCallback (channelWidth, nss);
64 }
65 
66 uint64_t
67 WifiMode::GetPhyRate (uint16_t channelWidth) const
68 {
69  return GetPhyRate (channelWidth, 800, 1);
70 }
71 
72 uint64_t
73 WifiMode::GetPhyRate (uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
74 {
76  return item->GetPhyRateCallback (channelWidth, guardInterval, nss);
77 }
78 
79 uint64_t
80 WifiMode::GetPhyRate (const WifiTxVector& txVector, uint16_t staId) const
81 {
83  return item->GetPhyRateFromTxVectorCallback (txVector, staId);
84 }
85 
86 uint64_t
87 WifiMode::GetDataRate (uint16_t channelWidth) const
88 {
89  return GetDataRate (channelWidth, 800, 1);
90 }
91 
92 uint64_t
93 WifiMode::GetDataRate (const WifiTxVector& txVector, uint16_t staId) const
94 {
96  return item->GetDataRateFromTxVectorCallback (txVector, staId);
97 }
98 
99 uint64_t
100 WifiMode::GetDataRate (uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
101 {
102  NS_ASSERT (nss <= 8);
104  return item->GetDataRateCallback (channelWidth, guardInterval, nss);
105 }
106 
109 {
111  return item->GetCodeRateCallback ();
112 }
113 
114 uint16_t
116 {
118  return item->GetConstellationSizeCallback ();
119 }
120 
121 std::string
123 {
124  //needed for ostream printing of the invalid mode
126  return item->uniqueUid;
127 }
128 
129 bool
131 {
133  return item->isMandatory;
134 }
135 
136 uint8_t
138 {
140  if (item->modClass >= WIFI_MOD_CLASS_HT)
141  {
142  return item->mcsValue;
143  }
144  else
145  {
146  //We should not go here!
147  NS_ASSERT (false);
148  return 0;
149  }
150 }
151 
152 uint32_t
153 WifiMode::GetUid (void) const
154 {
155  return m_uid;
156 }
157 
160 {
162  return item->modClass;
163 }
164 
165 uint64_t
167 {
169  NS_ASSERT_MSG (!item->GetNonHtReferenceRateCallback.IsNull (), "Trying to get HT reference rate for a non-HT rate");
170  return item->GetNonHtReferenceRateCallback ();
171 }
172 
173 bool
175 {
176  NS_ASSERT_MSG (GetCodeRate () != WIFI_CODE_RATE_UNDEFINED, "Wifi Code Rate not defined");
177  return (GetCodeRate () > mode.GetCodeRate ());
178 }
179 
180 bool
182 {
183  // If current modulation class is DSSS and other is not, the other is always higher
186  {
187  return false;
188  }
189  // If other modulation class is DSSS and current is not, the current is always higher
192  {
193  return true;
194  }
195  // If current is not HR/DSSS while other is not, check constellation size of other against current
198  {
199  return (mode.GetConstellationSize () > GetConstellationSize ());
200  }
201  // This block is for current and other mode > HR/DSSS, if constellation size
202  // is the same, check the code rate (DSSS and HR/DSSS does not define code rate)
203  else if (GetConstellationSize () == mode.GetConstellationSize ()
206  {
207  return IsHigherCodeRate (mode);
208  }
209  // Otherwise, check constellation size of current against other,
210  // the code go here if:
211  // - both current and other mode is DSSS
212  // - current mode is HR/DSSS and other mode is not HR/DSSS
213  // - current and other mode > HR/DSSS and both constellation size is not equal
214  else
215  {
216  return (GetConstellationSize () > mode.GetConstellationSize ());
217  }
218 }
219 
221  : m_uid (0)
222 {
223 }
224 
225 WifiMode::WifiMode (uint32_t uid)
226  : m_uid (uid)
227 {
228 }
229 
230 WifiMode::WifiMode (std::string name)
231 {
232  *this = WifiModeFactory::GetFactory ()->Search (name);
233 }
234 
236 
238 {
239 }
240 
241 WifiMode
242 WifiModeFactory::CreateWifiMode (std::string uniqueName,
243  WifiModulationClass modClass,
244  bool isMandatory,
245  CodeRateCallback codeRateCallback,
246  ConstellationSizeCallback constellationSizeCallback,
247  PhyRateCallback phyRateCallback,
248  PhyRateFromTxVectorCallback phyRateFromTxVectorCallback,
249  DataRateCallback dataRateCallback,
250  DataRateFromTxVectorCallback dataRateFromTxVectorCallback,
251  ModeAllowedCallback isModeAllowedCallback)
252 {
253  WifiModeFactory *factory = GetFactory ();
254  uint32_t uid = factory->AllocateUid (uniqueName);
255  WifiModeItem *item = factory->Get (uid);
256  item->uniqueUid = uniqueName;
257  item->modClass = modClass;
258  //The modulation class for this WifiMode must be valid.
259  NS_ASSERT (modClass != WIFI_MOD_CLASS_UNKNOWN);
260 
261  //Check for compatibility between modulation class and coding
262  //rate. If modulation class is DSSS then coding rate must be
263  //undefined, and vice versa. I could have done this with an
264  //assertion, but it seems better to always give the error (i.e.,
265  //not only in non-optimised builds) and the cycles that extra test
266  //here costs are only suffered at simulation setup.
267  if ((codeRateCallback () == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS && modClass != WIFI_MOD_CLASS_HR_DSSS)
268  {
269  NS_FATAL_ERROR ("Error in creation of WifiMode named " << uniqueName << std::endl
270  << "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is WIFI_MOD_CLASS_DSSS or WIFI_MOD_CLASS_HR_DSSS");
271  }
272 
273  item->isMandatory = isMandatory;
274  item->GetCodeRateCallback = codeRateCallback;
275  item->GetConstellationSizeCallback = constellationSizeCallback;
276  item->GetPhyRateCallback = phyRateCallback;
277  item->GetPhyRateFromTxVectorCallback = phyRateFromTxVectorCallback;
278  item->GetDataRateCallback = dataRateCallback;
279  item->GetDataRateFromTxVectorCallback = dataRateFromTxVectorCallback;
280  item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t> ();
281  item->IsModeAllowedCallback = isModeAllowedCallback;
282 
283  NS_ASSERT (modClass < WIFI_MOD_CLASS_HT);
284  //fill unused MCS item with a dummy value
285  item->mcsValue = 0;
286 
287  return WifiMode (uid);
288 }
289 
290 WifiMode
291 WifiModeFactory::CreateWifiMcs (std::string uniqueName,
292  uint8_t mcsValue,
293  WifiModulationClass modClass,
294  CodeRateCallback codeRateCallback,
295  ConstellationSizeCallback constellationSizeCallback,
296  PhyRateCallback phyRateCallback,
297  PhyRateFromTxVectorCallback phyRateFromTxVectorCallback,
298  DataRateCallback dataRateCallback,
299  DataRateFromTxVectorCallback dataRateFromTxVectorCallback,
300  NonHtReferenceRateCallback nonHtReferenceRateCallback,
301  ModeAllowedCallback isModeAllowedCallback)
302 {
303  WifiModeFactory *factory = GetFactory ();
304  uint32_t uid = factory->AllocateUid (uniqueName);
305  WifiModeItem *item = factory->Get (uid);
306  item->uniqueUid = uniqueName;
307  item->modClass = modClass;
308 
309  NS_ASSERT (modClass >= WIFI_MOD_CLASS_HT);
310 
311  item->mcsValue = mcsValue;
312  item->GetCodeRateCallback = codeRateCallback;
313  item->GetConstellationSizeCallback = constellationSizeCallback;
314  item->GetPhyRateCallback = phyRateCallback;
315  item->GetPhyRateFromTxVectorCallback = phyRateFromTxVectorCallback;
316  item->GetDataRateCallback = dataRateCallback;
317  item->GetDataRateFromTxVectorCallback = dataRateFromTxVectorCallback;
318  item->GetNonHtReferenceRateCallback = nonHtReferenceRateCallback;
319  item->IsModeAllowedCallback = isModeAllowedCallback;
320 
321  //fill unused items with dummy values
322  item->isMandatory = false;
323 
324  return WifiMode (uid);
325 }
326 
327 WifiMode
328 WifiModeFactory::Search (std::string name) const
329 {
330  WifiModeItemList::const_iterator i;
331  uint32_t j = 0;
332  for (i = m_itemList.begin (); i != m_itemList.end (); i++)
333  {
334  if (i->uniqueUid == name)
335  {
336  return WifiMode (j);
337  }
338  j++;
339  }
340 
341  //If we get here then a matching WifiMode was not found above. This
342  //is a fatal problem, but we try to be helpful by displaying the
343  //list of WifiModes that are supported.
344  NS_LOG_UNCOND ("Could not find match for WifiMode named \""
345  << name << "\". Valid options are:");
346  for (i = m_itemList.begin (); i != m_itemList.end (); i++)
347  {
348  NS_LOG_UNCOND (" " << i->uniqueUid);
349  }
350  //Empty fatal error to die. We've already unconditionally logged
351  //the helpful information.
352  NS_FATAL_ERROR ("");
353 
354  //This next line is unreachable because of the fatal error
355  //immediately above, and that is fortunate, because we have no idea
356  //what is in WifiMode (0), but we do know it is not what our caller
357  //has requested by name. It's here only because it's the safest
358  //thing that'll give valid code.
359  return WifiMode (0);
360 }
361 
362 uint32_t
363 WifiModeFactory::AllocateUid (std::string uniqueUid)
364 {
365  uint32_t j = 0;
366  for (WifiModeItemList::const_iterator i = m_itemList.begin ();
367  i != m_itemList.end (); i++)
368  {
369  if (i->uniqueUid == uniqueUid)
370  {
371  return j;
372  }
373  j++;
374  }
375  uint32_t uid = static_cast<uint32_t> (m_itemList.size ());
376  m_itemList.push_back (WifiModeItem ());
377  return uid;
378 }
379 
381 WifiModeFactory::Get (uint32_t uid)
382 {
383  NS_ASSERT (uid < m_itemList.size ());
384  return &m_itemList[uid];
385 }
386 
389 {
390  static bool isFirstTime = true;
391  static WifiModeFactory factory;
392  if (isFirstTime)
393  {
394  uint32_t uid = factory.AllocateUid ("Invalid-WifiMode");
395  WifiModeItem *item = factory.Get (uid);
396  item->uniqueUid = "Invalid-WifiMode";
398  item->isMandatory = false;
399  item->mcsValue = 0;
400  item->GetCodeRateCallback = MakeNullCallback<WifiCodeRate> ();
401  item->GetConstellationSizeCallback = MakeNullCallback<uint16_t> ();
402  item->GetPhyRateCallback = MakeNullCallback<uint64_t, uint16_t, uint16_t, uint8_t> ();
403  item->GetPhyRateFromTxVectorCallback = MakeNullCallback<uint64_t, const WifiTxVector&, uint16_t> ();
404  item->GetDataRateCallback = MakeNullCallback<uint64_t, uint16_t, uint16_t, uint8_t> ();
405  item->GetDataRateFromTxVectorCallback = MakeNullCallback<uint64_t, const WifiTxVector&, uint16_t> ();
406  item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t> ();
407  item->IsModeAllowedCallback = MakeNullCallback<bool, uint16_t, uint8_t> ();
408  isFirstTime = false;
409  }
410  return &factory;
411 }
412 
413 } //namespace ns3
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802...
WifiMode()
Create an invalid WifiMode.
Definition: wifi-mode.cc:220
CodeRateCallback GetCodeRateCallback
Callback to retrieve code rate of this WifiModeItem.
Definition: wifi-mode.h:439
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type
bool IsAllowed(uint16_t channelWidth, uint8_t nss) const
Definition: wifi-mode.cc:60
DataRateFromTxVectorCallback GetDataRateFromTxVectorCallback
Callback to calculate data rate in bps of this WifiModeItem using a TXVECTOR as input.
Definition: wifi-mode.h:444
#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_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:160
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:47
Modulation class unknown or unspecified.
uint32_t GetUid(void) const
Definition: wifi-mode.cc:153
bool IsMandatory(void) const
Definition: wifi-mode.cc:130
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:160
HR/DSSS (Clause 16)
WifiMode Search(std::string name) const
Search and return WifiMode from a given name.
Definition: wifi-mode.cc:328
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:137
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, PhyRateFromTxVectorCallback phyRateFromTxVectorCallback, DataRateCallback dataRateCallback, DataRateFromTxVectorCallback dataRateFromTxVectorCallback, NonHtReferenceRateCallback nonHtReferenceRateCallback, ModeAllowedCallback isModeAllowedCallback)
Definition: wifi-mode.cc:291
PhyRateCallback GetPhyRateCallback
Callback to calculate PHY rate in bps of this WifiModeItem.
Definition: wifi-mode.h:441
uint32_t m_uid
UID.
Definition: wifi-mode.h:191
NonHtReferenceRateCallback GetNonHtReferenceRateCallback
Callback to calculate non-HT reference rate of this WifiModeItem.
Definition: wifi-mode.h:445
WifiModeItemList m_itemList
item list
Definition: wifi-mode.h:478
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:159
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:122
WifiModulationClass modClass
modulation class
Definition: wifi-mode.h:436
uint16_t WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
PhyRateFromTxVectorCallback GetPhyRateFromTxVectorCallback
Callback to calculate PHY rate in bps of this WifiModeItem using a TXVECTOR as input.
Definition: wifi-mode.h:442
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, PhyRateFromTxVectorCallback phyRateFromTxVectorCallback, DataRateCallback dataRateCallback, DataRateFromTxVectorCallback dataRateFromTxVectorCallback, ModeAllowedCallback isModeAllowedCallback)
Definition: wifi-mode.cc:242
bool operator!=(Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > a, Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > b)
Inequality test.
Definition: callback.h:1606
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsHigherCodeRate(WifiMode mode) const
Definition: wifi-mode.cc:174
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
friend class WifiMode
allow WifiMode class access
Definition: wifi-mode.h:417
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:115
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
uint64_t GetNonHtReferenceRate(void) const
Definition: wifi-mode.cc:166
create WifiMode class instances and keep track of them.
Definition: wifi-mode.h:266
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:142
const uint16_t WIFI_CODE_RATE_UNDEFINED
undefined coding rate
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:73
static WifiModeFactory * GetFactory()
Return a WifiModeFactory.
Definition: wifi-mode.cc:388
ModeAllowedCallback IsModeAllowedCallback
Callback to check whether the combination of <MCS, channel width (MHz), NSS> is allowed.
Definition: wifi-mode.h:446
uint32_t AllocateUid(std::string uniqueUid)
Allocate a WifiModeItem from a given uniqueUid.
Definition: wifi-mode.cc:363
WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:108
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
WifiModeItem * Get(uint32_t uid)
Return a WifiModeItem at the given UID index.
Definition: wifi-mode.cc:381
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:137
bool isMandatory
flag to indicate whether this mode is mandatory
Definition: wifi-mode.h:437
bool IsHigherDataRate(WifiMode mode) const
Definition: wifi-mode.cc:181
ConstellationSizeCallback GetConstellationSizeCallback
Callback to retrieve constellation size of this WifiModeItem.
Definition: wifi-mode.h:440
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:100
This is the data associated to a unique WifiMode.
Definition: wifi-mode.h:433
std::string uniqueUid
unique UID
Definition: wifi-mode.h:435
DataRateCallback GetDataRateCallback
Callback to calculate data rate in bps of this WifiModeItem.
Definition: wifi-mode.h:443