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
28namespace ns3 {
29
30bool operator == (const WifiMode &a, const WifiMode &b)
31{
32 return a.GetUid () == b.GetUid ();
33}
34
35bool operator != (const WifiMode &a, const WifiMode &b)
36{
37 return a.GetUid () != b.GetUid ();
38}
39
40bool operator < (const WifiMode &a, const WifiMode &b)
41{
42 return a.GetUid () < b.GetUid ();
43}
44
45std::ostream & operator << (std::ostream & os, const WifiMode &mode)
46{
47 os << mode.GetUniqueName ();
48 return os;
49}
50
51std::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
59bool
60WifiMode::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
69bool
70WifiMode::IsAllowed (const WifiTxVector& txVector) const
71{
73 return item->IsAllowedCallback (txVector);
74}
75
76uint64_t
77WifiMode::GetPhyRate (uint16_t channelWidth) const
78{
79 return GetPhyRate (channelWidth, 800, 1);
80}
81
82uint64_t
83WifiMode::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
93uint64_t
94WifiMode::GetPhyRate (const WifiTxVector& txVector, uint16_t staId) const
95{
97 return item->GetPhyRateCallback (txVector, staId);
98}
99
100uint64_t
101WifiMode::GetDataRate (uint16_t channelWidth) const
102{
103 return GetDataRate (channelWidth, 800, 1);
104}
105
106uint64_t
107WifiMode::GetDataRate (const WifiTxVector& txVector, uint16_t staId) const
108{
110 return item->GetDataRateCallback (txVector, staId);
111}
112
113uint64_t
114WifiMode::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
132uint16_t
134{
136 return item->GetConstellationSizeCallback ();
137}
138
139std::string
141{
142 //needed for ostream printing of the invalid mode
144 return item->uniqueUid;
145}
146
147bool
149{
151 return item->isMandatory;
152}
153
154uint8_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
172{
173 return m_uid;
174}
175
178{
180 return item->modClass;
181}
182
183uint64_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
191bool
193{
194 NS_ASSERT_MSG (GetCodeRate () != WIFI_CODE_RATE_UNDEFINED, "Wifi Code Rate not defined");
195 return (GetCodeRate () > mode.GetCodeRate ());
196}
197
198bool
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
244 : m_uid (uid)
245{
246}
247
248WifiMode::WifiMode (std::string name)
249{
250 *this = WifiModeFactory::GetFactory ()->Search (name);
251}
252
254
256{
257}
258
260WifiModeFactory::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
305WifiModeFactory::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
337WifiModeFactory::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
372WifiModeFactory::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
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:162
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
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