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 std::ostream & operator << (std::ostream & os, const WifiMode &mode)
41 {
42  os << mode.GetUniqueName ();
43  return os;
44 }
45 
46 std::istream & operator >> (std::istream &is, WifiMode &mode)
47 {
48  std::string str;
49  is >> str;
50  mode = WifiModeFactory::GetFactory ()->Search (str);
51  return is;
52 }
53 
54 bool
55 WifiMode::IsAllowed (uint16_t channelWidth, uint8_t nss) const
56 {
58  return item->IsModeAllowedCallback (channelWidth, nss);
59 }
60 
61 uint64_t
62 WifiMode::GetPhyRate (uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
63 {
65  return item->GetPhyRateCallback (channelWidth, guardInterval, nss);
66 }
67 
68 uint64_t
69 WifiMode::GetPhyRate (const WifiTxVector& txVector) const
70 {
71  return GetPhyRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), txVector.GetNss ());
72 }
73 
74 uint64_t
75 WifiMode::GetDataRate (uint16_t channelWidth) const
76 {
77  return GetDataRate (channelWidth, 800, 1);
78 }
79 
80 uint64_t
81 WifiMode::GetDataRate (const WifiTxVector& txVector, uint16_t staId) const
82 {
84  return item->GetDataRateFromTxVectorCallback (txVector, staId);
85 }
86 
87 uint64_t
88 WifiMode::GetDataRate (uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
89 {
90  NS_ASSERT (nss <= 8);
92  return item->GetDataRateCallback (channelWidth, guardInterval, nss);
93 }
94 
97 {
99  return item->GetCodeRateCallback ();
100 }
101 
102 uint16_t
104 {
106  return item->GetConstellationSizeCallback ();
107 }
108 
109 std::string
111 {
112  //needed for ostream printing of the invalid mode
114  return item->uniqueUid;
115 }
116 
117 bool
119 {
121  return item->isMandatory;
122 }
123 
124 uint8_t
126 {
128  if (item->modClass >= WIFI_MOD_CLASS_HT)
129  {
130  return item->mcsValue;
131  }
132  else
133  {
134  //We should not go here!
135  NS_ASSERT (false);
136  return 0;
137  }
138 }
139 
140 uint32_t
141 WifiMode::GetUid (void) const
142 {
143  return m_uid;
144 }
145 
148 {
150  return item->modClass;
151 }
152 
153 uint64_t
155 {
157  NS_ASSERT_MSG (!item->GetNonHtReferenceRateCallback.IsNull (), "Trying to get HT reference rate for a non-HT rate");
158  return item->GetNonHtReferenceRateCallback ();
159 }
160 
161 bool
163 {
164  NS_ASSERT_MSG (GetCodeRate () != WIFI_CODE_RATE_UNDEFINED, "Wifi Code Rate not defined");
165  return (GetCodeRate () > mode.GetCodeRate ());
166 }
167 
168 bool
170 {
171  // If current modulation class is DSSS and other is not, the other is always higher
174  {
175  return false;
176  }
177  // If other modulation class is DSSS and current is not, the current is always higher
180  {
181  return true;
182  }
183  // If current is not HR/DSSS while other is not, check constellation size of other against current
186  {
187  return (mode.GetConstellationSize () > GetConstellationSize ());
188  }
189  // This block is for current and other mode > HR/DSSS, if constellation size
190  // is the same, check the code rate (DSSS and HR/DSSS does not define code rate)
191  else if (GetConstellationSize () == mode.GetConstellationSize ()
194  {
195  return IsHigherCodeRate (mode);
196  }
197  // Otherwise, check constellation size of current against other,
198  // the code go here if:
199  // - both current and other mode is DSSS
200  // - current mode is HR/DSSS and other mode is not HR/DSSS
201  // - current and other mode > HR/DSSS and both constellation size is not equal
202  else
203  {
204  return (GetConstellationSize () > mode.GetConstellationSize ());
205  }
206 }
207 
209  : m_uid (0)
210 {
211 }
212 
213 WifiMode::WifiMode (uint32_t uid)
214  : m_uid (uid)
215 {
216 }
217 
218 WifiMode::WifiMode (std::string name)
219 {
220  *this = WifiModeFactory::GetFactory ()->Search (name);
221 }
222 
224 
226 {
227 }
228 
229 WifiMode
230 WifiModeFactory::CreateWifiMode (std::string uniqueName,
231  WifiModulationClass modClass,
232  bool isMandatory,
233  CodeRateCallback codeRateCallback,
234  ConstellationSizeCallback constellationSizeCallback,
235  PhyRateCallback phyRateCallback,
236  DataRateCallback dataRateCallback,
237  DataRateFromTxVectorCallback dataRateFromTxVectorCallback,
238  ModeAllowedCallback isModeAllowedCallback)
239 {
240  WifiModeFactory *factory = GetFactory ();
241  uint32_t uid = factory->AllocateUid (uniqueName);
242  WifiModeItem *item = factory->Get (uid);
243  item->uniqueUid = uniqueName;
244  item->modClass = modClass;
245  //The modulation class for this WifiMode must be valid.
246  NS_ASSERT (modClass != WIFI_MOD_CLASS_UNKNOWN);
247 
248  //Check for compatibility between modulation class and coding
249  //rate. If modulation class is DSSS then coding rate must be
250  //undefined, and vice versa. I could have done this with an
251  //assertion, but it seems better to always give the error (i.e.,
252  //not only in non-optimised builds) and the cycles that extra test
253  //here costs are only suffered at simulation setup.
254  if ((codeRateCallback () == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS && modClass != WIFI_MOD_CLASS_HR_DSSS)
255  {
256  NS_FATAL_ERROR ("Error in creation of WifiMode named " << uniqueName << std::endl
257  << "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is WIFI_MOD_CLASS_DSSS or WIFI_MOD_CLASS_HR_DSSS");
258  }
259 
260  item->isMandatory = isMandatory;
261  item->GetCodeRateCallback = codeRateCallback;
262  item->GetConstellationSizeCallback = constellationSizeCallback;
263  item->GetPhyRateCallback = phyRateCallback;
264  item->GetDataRateCallback = dataRateCallback;
265  item->GetDataRateFromTxVectorCallback = dataRateFromTxVectorCallback;
266  item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t> ();
267  item->IsModeAllowedCallback = isModeAllowedCallback;
268 
269  NS_ASSERT (modClass < WIFI_MOD_CLASS_HT);
270  //fill unused MCS item with a dummy value
271  item->mcsValue = 0;
272 
273  return WifiMode (uid);
274 }
275 
276 WifiMode
277 WifiModeFactory::CreateWifiMcs (std::string uniqueName,
278  uint8_t mcsValue,
279  WifiModulationClass modClass,
280  CodeRateCallback codeRateCallback,
281  ConstellationSizeCallback constellationSizeCallback,
282  PhyRateCallback phyRateCallback,
283  DataRateCallback dataRateCallback,
284  DataRateFromTxVectorCallback dataRateFromTxVectorCallback,
285  NonHtReferenceRateCallback nonHtReferenceRateCallback,
286  ModeAllowedCallback isModeAllowedCallback)
287 {
288  WifiModeFactory *factory = GetFactory ();
289  uint32_t uid = factory->AllocateUid (uniqueName);
290  WifiModeItem *item = factory->Get (uid);
291  item->uniqueUid = uniqueName;
292  item->modClass = modClass;
293 
294  NS_ASSERT (modClass >= WIFI_MOD_CLASS_HT);
295 
296  item->mcsValue = mcsValue;
297  item->GetCodeRateCallback = codeRateCallback;
298  item->GetConstellationSizeCallback = constellationSizeCallback;
299  item->GetPhyRateCallback = phyRateCallback;
300  item->GetDataRateCallback = dataRateCallback;
301  item->GetDataRateFromTxVectorCallback = dataRateFromTxVectorCallback;
302  item->GetNonHtReferenceRateCallback = nonHtReferenceRateCallback;
303  item->IsModeAllowedCallback = isModeAllowedCallback;
304 
305  //fill unused items with dummy values
306  item->isMandatory = false;
307 
308  return WifiMode (uid);
309 }
310 
311 WifiMode
312 WifiModeFactory::Search (std::string name) const
313 {
314  WifiModeItemList::const_iterator i;
315  uint32_t j = 0;
316  for (i = m_itemList.begin (); i != m_itemList.end (); i++)
317  {
318  if (i->uniqueUid == name)
319  {
320  return WifiMode (j);
321  }
322  j++;
323  }
324 
325  //If we get here then a matching WifiMode was not found above. This
326  //is a fatal problem, but we try to be helpful by displaying the
327  //list of WifiModes that are supported.
328  NS_LOG_UNCOND ("Could not find match for WifiMode named \""
329  << name << "\". Valid options are:");
330  for (i = m_itemList.begin (); i != m_itemList.end (); i++)
331  {
332  NS_LOG_UNCOND (" " << i->uniqueUid);
333  }
334  //Empty fatal error to die. We've already unconditionally logged
335  //the helpful information.
336  NS_FATAL_ERROR ("");
337 
338  //This next line is unreachable because of the fatal error
339  //immediately above, and that is fortunate, because we have no idea
340  //what is in WifiMode (0), but we do know it is not what our caller
341  //has requested by name. It's here only because it's the safest
342  //thing that'll give valid code.
343  return WifiMode (0);
344 }
345 
346 uint32_t
347 WifiModeFactory::AllocateUid (std::string uniqueUid)
348 {
349  uint32_t j = 0;
350  for (WifiModeItemList::const_iterator i = m_itemList.begin ();
351  i != m_itemList.end (); i++)
352  {
353  if (i->uniqueUid == uniqueUid)
354  {
355  return j;
356  }
357  j++;
358  }
359  uint32_t uid = static_cast<uint32_t> (m_itemList.size ());
360  m_itemList.push_back (WifiModeItem ());
361  return uid;
362 }
363 
365 WifiModeFactory::Get (uint32_t uid)
366 {
367  NS_ASSERT (uid < m_itemList.size ());
368  return &m_itemList[uid];
369 }
370 
373 {
374  static bool isFirstTime = true;
375  static WifiModeFactory factory;
376  if (isFirstTime)
377  {
378  uint32_t uid = factory.AllocateUid ("Invalid-WifiMode");
379  WifiModeItem *item = factory.Get (uid);
380  item->uniqueUid = "Invalid-WifiMode";
382  item->isMandatory = false;
383  item->mcsValue = 0;
384  item->GetCodeRateCallback = MakeNullCallback<WifiCodeRate> ();
385  item->GetConstellationSizeCallback = MakeNullCallback<uint16_t> ();
386  item->GetPhyRateCallback = MakeNullCallback<uint64_t, uint16_t, uint16_t, uint8_t> ();
387  item->GetDataRateCallback = MakeNullCallback<uint64_t, uint16_t, uint16_t, uint8_t> ();
388  item->GetDataRateFromTxVectorCallback = MakeNullCallback<uint64_t, const WifiTxVector&, uint16_t> ();
389  item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t> ();
390  item->IsModeAllowedCallback = MakeNullCallback<bool, uint16_t, uint8_t> ();
391  isFirstTime = false;
392  }
393  return &factory;
394 }
395 
396 } //namespace ns3
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802...
std::istream & operator>>(std::istream &is, Angles &a)
initialize a struct Angles from input
Definition: angles.cc:48
WifiMode()
Create an invalid WifiMode.
Definition: wifi-mode.cc:208
CodeRateCallback GetCodeRateCallback
Callback to retrieve code rate of this WifiModeItem.
Definition: wifi-mode.h:424
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiCodeRate
This enumeration defines the various convolutional coding rates used for the OFDM transmission modes ...
Definition: wifi-mode.h:43
#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:55
DataRateFromTxVectorCallback GetDataRateFromTxVectorCallback
Callback to calculate data rate in bps of this WifiModeItem using a TXVECTOR as input.
Definition: wifi-mode.h:428
#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
uint16_t GetGuardInterval(void) const
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:68
Modulation class unknown or unspecified.
uint32_t GetUid(void) const
Definition: wifi-mode.cc:141
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, DataRateFromTxVectorCallback dataRateFromTxVectorCallback, ModeAllowedCallback isModeAllowedCallback)
Definition: wifi-mode.cc:230
bool IsMandatory(void) const
Definition: wifi-mode.cc:118
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:312
PhyRateCallback GetPhyRateCallback
Callback to calculate PHY rate in bps of this WifiModeItem.
Definition: wifi-mode.h:426
uint32_t m_uid
UID.
Definition: wifi-mode.h:205
NonHtReferenceRateCallback GetNonHtReferenceRateCallback
Callback to calculate non-HT reference rate of this WifiModeItem.
Definition: wifi-mode.h:429
WifiModeItemList m_itemList
item list
Definition: wifi-mode.h:462
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:147
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:110
WifiModulationClass modClass
modulation class
Definition: wifi-mode.h:421
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsHigherCodeRate(WifiMode mode) const
Definition: wifi-mode.cc:162
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
friend class WifiMode
allow WifiMode class access
Definition: wifi-mode.h:402
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:103
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, DataRateFromTxVectorCallback dataRateFromTxVectorCallback, NonHtReferenceRateCallback nonHtReferenceRateCallback, ModeAllowedCallback isModeAllowedCallback)
Definition: wifi-mode.cc:277
#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:154
No explicit coding (e.g., DSSS rates)
Definition: wifi-mode.h:46
create WifiMode class instances and keep track of them.
Definition: wifi-mode.h:267
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:142
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:62
static WifiModeFactory * GetFactory()
Return a WifiModeFactory.
Definition: wifi-mode.cc:372
ModeAllowedCallback IsModeAllowedCallback
Callback to check whether the combination of <MCS, channel width (MHz), NSS> is allowed.
Definition: wifi-mode.h:430
uint32_t AllocateUid(std::string uniqueUid)
Allocate a WifiModeItem from a given uniqueUid.
Definition: wifi-mode.cc:347
uint16_t GetChannelWidth(void) const
WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:96
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:365
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:125
bool isMandatory
flag to indicate whether this mode is mandatory
Definition: wifi-mode.h:422
bool IsHigherDataRate(WifiMode mode) const
Definition: wifi-mode.cc:169
ConstellationSizeCallback GetConstellationSizeCallback
Callback to retrieve constellation size of this WifiModeItem.
Definition: wifi-mode.h:425
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:88
This is the data associated to a unique WifiMode.
Definition: wifi-mode.h:418
std::string uniqueUid
unique UID
Definition: wifi-mode.h:420
DataRateCallback GetDataRateCallback
Callback to calculate data rate in bps of this WifiModeItem.
Definition: wifi-mode.h:427