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 {
62  WifiTxVector txVector;
63  txVector.SetMode (WifiMode (m_uid));
64  txVector.SetChannelWidth (channelWidth);
65  txVector.SetNss (nss);
66  return IsAllowed (txVector);
67 }
68 
69 bool
70 WifiMode::IsAllowed (const WifiTxVector& txVector) const
71 {
73  return item->IsAllowedCallback (txVector);
74 }
75 
76 uint64_t
77 WifiMode::GetPhyRate (uint16_t channelWidth) const
78 {
79  return GetPhyRate (channelWidth, 800, 1);
80 }
81 
82 uint64_t
83 WifiMode::GetPhyRate (uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
84 {
85  WifiTxVector txVector;
86  txVector.SetMode (WifiMode (m_uid));
87  txVector.SetChannelWidth (channelWidth);
88  txVector.SetGuardInterval (guardInterval);
89  txVector.SetNss (nss);
90  return GetPhyRate (txVector);
91 }
92 
93 uint64_t
94 WifiMode::GetPhyRate (const WifiTxVector& txVector, uint16_t staId) const
95 {
97  return item->GetPhyRateCallback (txVector, staId);
98 }
99 
100 uint64_t
101 WifiMode::GetDataRate (uint16_t channelWidth) const
102 {
103  return GetDataRate (channelWidth, 800, 1);
104 }
105 
106 uint64_t
107 WifiMode::GetDataRate (const WifiTxVector& txVector, uint16_t staId) const
108 {
110  return item->GetDataRateCallback (txVector, staId);
111 }
112 
113 uint64_t
114 WifiMode::GetDataRate (uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
115 {
116  NS_ASSERT (nss <= 8);
117  WifiTxVector txVector;
118  txVector.SetMode (WifiMode (m_uid));
119  txVector.SetChannelWidth (channelWidth);
120  txVector.SetGuardInterval (guardInterval);
121  txVector.SetNss (nss);
122  return GetDataRate (txVector);
123 }
124 
127 {
129  return item->GetCodeRateCallback ();
130 }
131 
132 uint16_t
134 {
136  return item->GetConstellationSizeCallback ();
137 }
138 
139 std::string
141 {
142  //needed for ostream printing of the invalid mode
144  return item->uniqueUid;
145 }
146 
147 bool
149 {
151  return item->isMandatory;
152 }
153 
154 uint8_t
156 {
158  if (item->modClass >= WIFI_MOD_CLASS_HT)
159  {
160  return item->mcsValue;
161  }
162  else
163  {
164  //We should not go here!
165  NS_ASSERT (false);
166  return 0;
167  }
168 }
169 
170 uint32_t
171 WifiMode::GetUid (void) const
172 {
173  return m_uid;
174 }
175 
178 {
180  return item->modClass;
181 }
182 
183 uint64_t
185 {
187  NS_ASSERT_MSG (!item->GetNonHtReferenceRateCallback.IsNull (), "Trying to get HT reference rate for a non-HT rate");
188  return item->GetNonHtReferenceRateCallback ();
189 }
190 
191 bool
193 {
194  NS_ASSERT_MSG (GetCodeRate () != WIFI_CODE_RATE_UNDEFINED, "Wifi Code Rate not defined");
195  return (GetCodeRate () > mode.GetCodeRate ());
196 }
197 
198 bool
200 {
201  // If current modulation class is DSSS and other is not, the other is always higher
204  {
205  return false;
206  }
207  // If other modulation class is DSSS and current is not, the current is always higher
210  {
211  return true;
212  }
213  // If current is not HR/DSSS while other is not, check constellation size of other against current
216  {
217  return (mode.GetConstellationSize () > GetConstellationSize ());
218  }
219  // This block is for current and other mode > HR/DSSS, if constellation size
220  // is the same, check the code rate (DSSS and HR/DSSS does not define code rate)
221  else if (GetConstellationSize () == mode.GetConstellationSize ()
224  {
225  return IsHigherCodeRate (mode);
226  }
227  // Otherwise, check constellation size of current against other,
228  // the code go here if:
229  // - both current and other mode is DSSS
230  // - current mode is HR/DSSS and other mode is not HR/DSSS
231  // - current and other mode > HR/DSSS and both constellation size is not equal
232  else
233  {
234  return (GetConstellationSize () > mode.GetConstellationSize ());
235  }
236 }
237 
239  : m_uid (0)
240 {
241 }
242 
243 WifiMode::WifiMode (uint32_t uid)
244  : m_uid (uid)
245 {
246 }
247 
248 WifiMode::WifiMode (std::string name)
249 {
250  *this = WifiModeFactory::GetFactory ()->Search (name);
251 }
252 
254 
256 {
257 }
258 
259 WifiMode
260 WifiModeFactory::CreateWifiMode (std::string uniqueName,
261  WifiModulationClass modClass,
262  bool isMandatory,
263  CodeRateCallback codeRateCallback,
264  ConstellationSizeCallback constellationSizeCallback,
265  PhyRateCallback phyRateCallback,
266  DataRateCallback dataRateCallback,
267  AllowedCallback isAllowedCallback)
268 {
269  WifiModeFactory *factory = GetFactory ();
270  uint32_t uid = factory->AllocateUid (uniqueName);
271  WifiModeItem *item = factory->Get (uid);
272  item->uniqueUid = uniqueName;
273  item->modClass = modClass;
274  //The modulation class for this WifiMode must be valid.
275  NS_ASSERT (modClass != WIFI_MOD_CLASS_UNKNOWN);
276 
277  //Check for compatibility between modulation class and coding
278  //rate. If modulation class is DSSS then coding rate must be
279  //undefined, and vice versa. I could have done this with an
280  //assertion, but it seems better to always give the error (i.e.,
281  //not only in non-optimised builds) and the cycles that extra test
282  //here costs are only suffered at simulation setup.
283  if ((codeRateCallback () == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS && modClass != WIFI_MOD_CLASS_HR_DSSS)
284  {
285  NS_FATAL_ERROR ("Error in creation of WifiMode named " << uniqueName << std::endl
286  << "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is WIFI_MOD_CLASS_DSSS or WIFI_MOD_CLASS_HR_DSSS");
287  }
288 
289  item->isMandatory = isMandatory;
290  item->GetCodeRateCallback = codeRateCallback;
291  item->GetConstellationSizeCallback = constellationSizeCallback;
292  item->GetPhyRateCallback = phyRateCallback;
293  item->GetDataRateCallback = dataRateCallback;
294  item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t> ();
295  item->IsAllowedCallback = isAllowedCallback;
296 
297  NS_ASSERT (modClass < WIFI_MOD_CLASS_HT);
298  //fill unused MCS item with a dummy value
299  item->mcsValue = 0;
300 
301  return WifiMode (uid);
302 }
303 
304 WifiMode
305 WifiModeFactory::CreateWifiMcs (std::string uniqueName,
306  uint8_t mcsValue,
307  WifiModulationClass modClass,
308  bool isMandatory,
309  CodeRateCallback codeRateCallback,
310  ConstellationSizeCallback constellationSizeCallback,
311  PhyRateCallback phyRateCallback,
312  DataRateCallback dataRateCallback,
313  NonHtReferenceRateCallback nonHtReferenceRateCallback,
314  AllowedCallback isAllowedCallback)
315 {
316  WifiModeFactory *factory = GetFactory ();
317  uint32_t uid = factory->AllocateUid (uniqueName);
318  WifiModeItem *item = factory->Get (uid);
319  item->uniqueUid = uniqueName;
320  item->modClass = modClass;
321 
322  NS_ASSERT (modClass >= WIFI_MOD_CLASS_HT);
323 
324  item->mcsValue = mcsValue;
325  item->isMandatory = isMandatory;
326  item->GetCodeRateCallback = codeRateCallback;
327  item->GetConstellationSizeCallback = constellationSizeCallback;
328  item->GetPhyRateCallback = phyRateCallback;
329  item->GetDataRateCallback = dataRateCallback;
330  item->GetNonHtReferenceRateCallback = nonHtReferenceRateCallback;
331  item->IsAllowedCallback = isAllowedCallback;
332 
333  return WifiMode (uid);
334 }
335 
336 WifiMode
337 WifiModeFactory::Search (std::string name) const
338 {
339  WifiModeItemList::const_iterator i;
340  uint32_t j = 0;
341  for (i = m_itemList.begin (); i != m_itemList.end (); i++)
342  {
343  if (i->uniqueUid == name)
344  {
345  return WifiMode (j);
346  }
347  j++;
348  }
349 
350  //If we get here then a matching WifiMode was not found above. This
351  //is a fatal problem, but we try to be helpful by displaying the
352  //list of WifiModes that are supported.
353  NS_LOG_UNCOND ("Could not find match for WifiMode named \""
354  << name << "\". Valid options are:");
355  for (i = m_itemList.begin (); i != m_itemList.end (); i++)
356  {
357  NS_LOG_UNCOND (" " << i->uniqueUid);
358  }
359  //Empty fatal error to die. We've already unconditionally logged
360  //the helpful information.
361  NS_FATAL_ERROR ("");
362 
363  //This next line is unreachable because of the fatal error
364  //immediately above, and that is fortunate, because we have no idea
365  //what is in WifiMode (0), but we do know it is not what our caller
366  //has requested by name. It's here only because it's the safest
367  //thing that'll give valid code.
368  return WifiMode (0);
369 }
370 
371 uint32_t
372 WifiModeFactory::AllocateUid (std::string uniqueUid)
373 {
374  uint32_t j = 0;
375  for (WifiModeItemList::const_iterator i = m_itemList.begin ();
376  i != m_itemList.end (); i++)
377  {
378  if (i->uniqueUid == uniqueUid)
379  {
380  return j;
381  }
382  j++;
383  }
384  uint32_t uid = static_cast<uint32_t> (m_itemList.size ());
385  m_itemList.push_back (WifiModeItem ());
386  return uid;
387 }
388 
390 WifiModeFactory::Get (uint32_t uid)
391 {
392  NS_ASSERT (uid < m_itemList.size ());
393  return &m_itemList[uid];
394 }
395 
398 {
399  static bool isFirstTime = true;
400  static WifiModeFactory factory;
401  if (isFirstTime)
402  {
403  uint32_t uid = factory.AllocateUid ("Invalid-WifiMode");
404  WifiModeItem *item = factory.Get (uid);
405  item->uniqueUid = "Invalid-WifiMode";
407  item->isMandatory = false;
408  item->mcsValue = 0;
409  item->GetCodeRateCallback = MakeNullCallback<WifiCodeRate> ();
410  item->GetConstellationSizeCallback = MakeNullCallback<uint16_t> ();
411  item->GetPhyRateCallback = MakeNullCallback<uint64_t, const WifiTxVector&, uint16_t> ();
412  item->GetDataRateCallback = MakeNullCallback<uint64_t, const WifiTxVector&, uint16_t> ();
413  item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t> ();
414  item->IsAllowedCallback = MakeNullCallback<bool, const WifiTxVector&> ();
415  isFirstTime = false;
416  }
417  return &factory;
418 }
419 
420 } //namespace ns3
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
create WifiMode class instances and keep track of them.
Definition: wifi-mode.h:273
WifiModeItem * Get(uint32_t uid)
Return a WifiModeItem at the given UID index.
Definition: wifi-mode.cc:390
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, NonHtReferenceRateCallback nonHtReferenceRateCallback, AllowedCallback isAllowedCallback)
Definition: wifi-mode.cc:305
uint32_t AllocateUid(std::string uniqueUid)
Allocate a WifiModeItem from a given uniqueUid.
Definition: wifi-mode.cc:372
static WifiModeFactory * GetFactory()
Return a WifiModeFactory.
Definition: wifi-mode.cc:397
WifiModeItemList m_itemList
item list
Definition: wifi-mode.h:448
WifiMode Search(std::string name) const
Search and return WifiMode from a given name.
Definition: wifi-mode.cc:337
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, AllowedCallback isAllowedCallback)
Definition: wifi-mode.cc:260
friend class WifiMode
allow WifiMode class access
Definition: wifi-mode.h:389
represent a single transmission mode
Definition: wifi-mode.h:48
WifiMode()
Create an invalid WifiMode.
Definition: wifi-mode.cc:238
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:133
uint64_t GetNonHtReferenceRate(void) const
Definition: wifi-mode.cc:184
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:155
bool IsHigherDataRate(WifiMode mode) const
Definition: wifi-mode.cc:199
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:177
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:83
uint32_t GetUid(void) const
Definition: wifi-mode.cc:171
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:140
WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:126
uint32_t m_uid
UID.
Definition: wifi-mode.h:197
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:114
bool IsHigherCodeRate(WifiMode mode) const
Definition: wifi-mode.cc:192
bool IsAllowed(uint16_t channelWidth, uint8_t nss) const
Definition: wifi-mode.cc:60
bool IsMandatory(void) const
Definition: wifi-mode.cc:148
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetNss(uint8_t nss)
Sets the number of Nss.
#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_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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
@ WIFI_MOD_CLASS_HR_DSSS
HR/DSSS (Clause 16)
@ WIFI_MOD_CLASS_UNKNOWN
Modulation class unknown or unspecified.
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_DSSS
DSSS (Clause 15)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
const uint16_t WIFI_CODE_RATE_UNDEFINED
undefined coding rate
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:158
ATTRIBUTE_HELPER_CPP(Length)
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:176
uint16_t WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
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:1612
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:162
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
This is the data associated to a unique WifiMode.
Definition: wifi-mode.h:406
WifiModulationClass modClass
modulation class
Definition: wifi-mode.h:408
AllowedCallback IsAllowedCallback
Callback to check whether a given combination of is allowed.
Definition: wifi-mode.h:416
std::string uniqueUid
unique UID
Definition: wifi-mode.h:407
bool isMandatory
flag to indicate whether this mode is mandatory
Definition: wifi-mode.h:409
PhyRateCallback GetPhyRateCallback
Callback to calculate PHY rate in bps of this WifiModeItem.
Definition: wifi-mode.h:413
DataRateCallback GetDataRateCallback
Callback to calculate data rate in bps of this WifiModeItem.
Definition: wifi-mode.h:414
NonHtReferenceRateCallback GetNonHtReferenceRateCallback
Callback to calculate non-HT reference rate of this WifiModeItem.
Definition: wifi-mode.h:415
ConstellationSizeCallback GetConstellationSizeCallback
Callback to retrieve constellation size of this WifiModeItem.
Definition: wifi-mode.h:412
CodeRateCallback GetCodeRateCallback
Callback to retrieve code rate of this WifiModeItem.
Definition: wifi-mode.h:411