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  CodeRateCallback codeRateCallback,
309  ConstellationSizeCallback constellationSizeCallback,
310  PhyRateCallback phyRateCallback,
311  DataRateCallback dataRateCallback,
312  NonHtReferenceRateCallback nonHtReferenceRateCallback,
313  AllowedCallback isAllowedCallback)
314 {
315  WifiModeFactory *factory = GetFactory ();
316  uint32_t uid = factory->AllocateUid (uniqueName);
317  WifiModeItem *item = factory->Get (uid);
318  item->uniqueUid = uniqueName;
319  item->modClass = modClass;
320 
321  NS_ASSERT (modClass >= WIFI_MOD_CLASS_HT);
322 
323  item->mcsValue = mcsValue;
324  item->GetCodeRateCallback = codeRateCallback;
325  item->GetConstellationSizeCallback = constellationSizeCallback;
326  item->GetPhyRateCallback = phyRateCallback;
327  item->GetDataRateCallback = dataRateCallback;
328  item->GetNonHtReferenceRateCallback = nonHtReferenceRateCallback;
329  item->IsAllowedCallback = isAllowedCallback;
330 
331  //fill unused items with dummy values
332  item->isMandatory = false;
333 
334  return WifiMode (uid);
335 }
336 
337 WifiMode
338 WifiModeFactory::Search (std::string name) const
339 {
340  WifiModeItemList::const_iterator i;
341  uint32_t j = 0;
342  for (i = m_itemList.begin (); i != m_itemList.end (); i++)
343  {
344  if (i->uniqueUid == name)
345  {
346  return WifiMode (j);
347  }
348  j++;
349  }
350 
351  //If we get here then a matching WifiMode was not found above. This
352  //is a fatal problem, but we try to be helpful by displaying the
353  //list of WifiModes that are supported.
354  NS_LOG_UNCOND ("Could not find match for WifiMode named \""
355  << name << "\". Valid options are:");
356  for (i = m_itemList.begin (); i != m_itemList.end (); i++)
357  {
358  NS_LOG_UNCOND (" " << i->uniqueUid);
359  }
360  //Empty fatal error to die. We've already unconditionally logged
361  //the helpful information.
362  NS_FATAL_ERROR ("");
363 
364  //This next line is unreachable because of the fatal error
365  //immediately above, and that is fortunate, because we have no idea
366  //what is in WifiMode (0), but we do know it is not what our caller
367  //has requested by name. It's here only because it's the safest
368  //thing that'll give valid code.
369  return WifiMode (0);
370 }
371 
372 uint32_t
373 WifiModeFactory::AllocateUid (std::string uniqueUid)
374 {
375  uint32_t j = 0;
376  for (WifiModeItemList::const_iterator i = m_itemList.begin ();
377  i != m_itemList.end (); i++)
378  {
379  if (i->uniqueUid == uniqueUid)
380  {
381  return j;
382  }
383  j++;
384  }
385  uint32_t uid = static_cast<uint32_t> (m_itemList.size ());
386  m_itemList.push_back (WifiModeItem ());
387  return uid;
388 }
389 
391 WifiModeFactory::Get (uint32_t uid)
392 {
393  NS_ASSERT (uid < m_itemList.size ());
394  return &m_itemList[uid];
395 }
396 
399 {
400  static bool isFirstTime = true;
401  static WifiModeFactory factory;
402  if (isFirstTime)
403  {
404  uint32_t uid = factory.AllocateUid ("Invalid-WifiMode");
405  WifiModeItem *item = factory.Get (uid);
406  item->uniqueUid = "Invalid-WifiMode";
408  item->isMandatory = false;
409  item->mcsValue = 0;
410  item->GetCodeRateCallback = MakeNullCallback<WifiCodeRate> ();
411  item->GetConstellationSizeCallback = MakeNullCallback<uint16_t> ();
412  item->GetPhyRateCallback = MakeNullCallback<uint64_t, const WifiTxVector&, uint16_t> ();
413  item->GetDataRateCallback = MakeNullCallback<uint64_t, const WifiTxVector&, uint16_t> ();
414  item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t> ();
415  item->IsAllowedCallback = MakeNullCallback<bool, const WifiTxVector&> ();
416  isFirstTime = false;
417  }
418  return &factory;
419 }
420 
421 } //namespace ns3
ns3::WifiModeFactory::WifiModeItem::GetPhyRateCallback
PhyRateCallback GetPhyRateCallback
Callback to calculate PHY rate in bps of this WifiModeItem.
Definition: wifi-mode.h:411
NS_ASSERT
#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
ns3::WifiModeFactory::Get
WifiModeItem * Get(uint32_t uid)
Return a WifiModeItem at the given UID index.
Definition: wifi-mode.cc:391
ns3::WifiMode::IsHigherCodeRate
bool IsHigherCodeRate(WifiMode mode) const
Definition: wifi-mode.cc:192
ns3::WifiModeFactory::WifiModeItem
This is the data associated to a unique WifiMode.
Definition: wifi-mode.h:404
ns3::WifiMode::IsMandatory
bool IsMandatory(void) const
Definition: wifi-mode.cc:148
ns3::Callback< WifiCodeRate >
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::WifiModeFactory::WifiModeItem::uniqueUid
std::string uniqueUid
unique UID
Definition: wifi-mode.h:405
ns3::WifiModeFactory::WifiModeItem::modClass
WifiModulationClass modClass
modulation class
Definition: wifi-mode.h:406
ns3::Callback::IsNull
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
ns3::WIFI_MOD_CLASS_HT
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
Definition: wifi-phy-common.h:130
ns3::WifiModeFactory::WifiModeItem::GetDataRateCallback
DataRateCallback GetDataRateCallback
Callback to calculate data rate in bps of this WifiModeItem.
Definition: wifi-mode.h:412
ns3::WifiMode::IsHigherDataRate
bool IsHigherDataRate(WifiMode mode) const
Definition: wifi-mode.cc:199
ns3::operator<
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:160
ns3::WifiTxVector::SetGuardInterval
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
Definition: wifi-tx-vector.cc:260
ns3::WifiMode::GetCodeRate
WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:126
ns3::WifiModeFactory::WifiModeItem::GetNonHtReferenceRateCallback
NonHtReferenceRateCallback GetNonHtReferenceRateCallback
Callback to calculate non-HT reference rate of this WifiModeItem.
Definition: wifi-mode.h:413
ns3::WifiMode::GetModulationClass
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:177
ns3::WifiTxVector::SetNss
void SetNss(uint8_t nss)
Sets the number of Nss.
Definition: wifi-tx-vector.cc:272
ns3::WIFI_CODE_RATE_UNDEFINED
const uint16_t WIFI_CODE_RATE_UNDEFINED
undefined coding rate
Definition: wifi-phy-common.h:57
ns3::WifiModeFactory::WifiModeItem::GetConstellationSizeCallback
ConstellationSizeCallback GetConstellationSizeCallback
Callback to retrieve constellation size of this WifiModeItem.
Definition: wifi-mode.h:410
ns3::WifiTxVector::SetMode
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
Definition: wifi-tx-vector.cc:226
ns3::WifiTxVector
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Definition: wifi-tx-vector.h:71
ns3::WIFI_MOD_CLASS_UNKNOWN
@ WIFI_MOD_CLASS_UNKNOWN
Modulation class unknown or unspecified.
Definition: wifi-phy-common.h:125
ns3::WIFI_MOD_CLASS_HR_DSSS
@ WIFI_MOD_CLASS_HR_DSSS
HR/DSSS (Clause 16)
Definition: wifi-phy-common.h:127
NS_FATAL_ERROR
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
ns3::WifiCodeRate
uint16_t WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
Definition: wifi-phy-common.h:45
ns3::WifiMode
represent a single transmission mode
Definition: wifi-mode.h:48
ns3::WifiModeFactory::Search
WifiMode Search(std::string name) const
Search and return WifiMode from a given name.
Definition: wifi-mode.cc:338
ATTRIBUTE_HELPER_CPP
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type
Definition: attribute-helper.h:412
ns3::WifiModeFactory::AllocateUid
uint32_t AllocateUid(std::string uniqueUid)
Allocate a WifiModeItem from a given uniqueUid.
Definition: wifi-mode.cc:373
wifi-tx-vector.h
ns3::WifiMode::GetNonHtReferenceRate
uint64_t GetNonHtReferenceRate(void) const
Definition: wifi-mode.cc:184
ns3::WifiModeFactory::CreateWifiMcs
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, NonHtReferenceRateCallback nonHtReferenceRateCallback, AllowedCallback isAllowedCallback)
Definition: wifi-mode.cc:305
ns3::WifiMode::GetUniqueName
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:140
ns3::WifiTxVector::SetChannelWidth
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
Definition: wifi-tx-vector.cc:254
ns3::WifiMode::WifiMode
WifiMode()
Create an invalid WifiMode.
Definition: wifi-mode.cc:238
ns3::operator==
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:142
wifi-mode.h
NS_ASSERT_MSG
#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
NS_LOG_UNCOND
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
Definition: log-macros-enabled.h:269
ns3::WifiMode::GetPhyRate
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:83
ns3::WifiModeFactory::m_itemList
WifiModeItemList m_itemList
item list
Definition: wifi-mode.h:446
ns3::WifiModeFactory::WifiModeFactory
WifiModeFactory()
Definition: wifi-mode.cc:255
ns3::WifiModeFactory::WifiModeItem::isMandatory
bool isMandatory
flag to indicate whether this mode is mandatory
Definition: wifi-mode.h:407
ns3::WifiModeFactory::WifiModeItem::IsAllowedCallback
AllowedCallback IsAllowedCallback
Callback to check whether a given combination of is allowed.
Definition: wifi-mode.h:414
ns3::WifiModeFactory::WifiModeItem::mcsValue
uint8_t mcsValue
MCS value.
Definition: wifi-mode.h:408
ns3::WifiMode::GetUid
uint32_t GetUid(void) const
Definition: wifi-mode.cc:171
ns3::operator!=
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
ns3::WifiMode::m_uid
uint32_t m_uid
UID.
Definition: wifi-mode.h:197
ns3::WifiModeFactory::GetFactory
static WifiModeFactory * GetFactory()
Return a WifiModeFactory.
Definition: wifi-mode.cc:398
ns3::WifiModeFactory::WifiModeItem::GetCodeRateCallback
CodeRateCallback GetCodeRateCallback
Callback to retrieve code rate of this WifiModeItem.
Definition: wifi-mode.h:409
ns3::WifiMode::GetDataRate
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:114
ns3::WifiModeFactory::CreateWifiMode
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
ns3::WifiModeFactory
create WifiMode class instances and keep track of them.
Definition: wifi-mode.h:273
ns3::operator<<
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:137
ns3::WifiModeFactory::WifiMode
friend class WifiMode
allow WifiMode class access
Definition: wifi-mode.h:387
ns3::WifiMode::IsAllowed
bool IsAllowed(uint16_t channelWidth, uint8_t nss) const
Definition: wifi-mode.cc:60
ns3::WIFI_MOD_CLASS_DSSS
@ WIFI_MOD_CLASS_DSSS
DSSS (Clause 15)
Definition: wifi-phy-common.h:126
ns3::WifiMode::GetConstellationSize
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:133
ns3::WifiModulationClass
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
Definition: wifi-phy-common.h:122
ns3::WifiMode::GetMcsValue
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:155
ns3::operator>>
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:160