A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-mode.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006,2007 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 * Sébastien Deronne <sebastien.deronne@gmail.com>
19 */
20
21#include "wifi-mode.h"
22
23#include "wifi-tx-vector.h"
24
25#include "ns3/he-ru.h"
26#include "ns3/log.h"
27
28#include <cmath>
29
30namespace ns3
31{
32
33bool
34operator==(const WifiMode& a, const WifiMode& b)
35{
36 return a.GetUid() == b.GetUid();
37}
38
39bool
40operator!=(const WifiMode& a, const WifiMode& b)
41{
42 return a.GetUid() != b.GetUid();
43}
44
45bool
46operator<(const WifiMode& a, const WifiMode& b)
47{
48 return a.GetUid() < b.GetUid();
49}
50
51std::ostream&
52operator<<(std::ostream& os, const WifiMode& mode)
53{
54 os << mode.GetUniqueName();
55 return os;
56}
57
58std::istream&
59operator>>(std::istream& is, WifiMode& mode)
60{
61 std::string str;
62 is >> str;
64 return is;
65}
66
67bool
68WifiMode::IsAllowed(uint16_t channelWidth, uint8_t nss) const
69{
70 WifiTxVector txVector;
71 txVector.SetMode(WifiMode(m_uid));
72 txVector.SetChannelWidth(channelWidth);
73 txVector.SetNss(nss);
74 return IsAllowed(txVector);
75}
76
77bool
78WifiMode::IsAllowed(const WifiTxVector& txVector) const
79{
81 return item->IsAllowedCallback(txVector);
82}
83
84uint64_t
85WifiMode::GetPhyRate(uint16_t channelWidth) const
86{
87 return GetPhyRate(channelWidth, 800, 1);
88}
89
90uint64_t
91WifiMode::GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
92{
93 WifiTxVector txVector;
94 txVector.SetMode(WifiMode(m_uid));
95 txVector.SetChannelWidth(channelWidth);
96 txVector.SetGuardInterval(guardInterval);
97 txVector.SetNss(nss);
98 return GetPhyRate(txVector);
99}
100
101uint64_t
102WifiMode::GetPhyRate(const WifiTxVector& txVector, uint16_t staId) const
103{
105 return item->GetPhyRateCallback(txVector, staId);
106}
107
108uint64_t
109WifiMode::GetDataRate(uint16_t channelWidth) const
110{
111 return GetDataRate(channelWidth, 800, 1);
112}
113
114uint64_t
115WifiMode::GetDataRate(const WifiTxVector& txVector, uint16_t staId) const
116{
118 return item->GetDataRateCallback(txVector, staId);
119}
120
121uint64_t
122WifiMode::GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
123{
124 NS_ASSERT(nss <= 8);
125 WifiTxVector txVector;
126 txVector.SetMode(WifiMode(m_uid));
127 txVector.SetChannelWidth(channelWidth);
128 txVector.SetGuardInterval(guardInterval);
129 txVector.SetNss(nss);
130 return GetDataRate(txVector);
131}
132
135{
137 return item->GetCodeRateCallback();
138}
139
140uint16_t
142{
144 return item->GetConstellationSizeCallback();
145}
146
147std::string
149{
150 // needed for ostream printing of the invalid mode
152 return item->uniqueUid;
153}
154
155bool
157{
159 return item->isMandatory;
160}
161
162uint8_t
164{
166 if (item->modClass >= WIFI_MOD_CLASS_HT)
167 {
168 return item->mcsValue;
169 }
170 else
171 {
172 // We should not go here!
173 NS_ASSERT(false);
174 return 0;
175 }
176}
177
180{
181 return m_uid;
182}
183
186{
188 return item->modClass;
189}
190
191uint64_t
193{
196 "Trying to get HT reference rate for a non-HT rate");
197 return item->GetNonHtReferenceRateCallback();
198}
199
200bool
202{
203 NS_ASSERT_MSG(GetCodeRate() != WIFI_CODE_RATE_UNDEFINED, "Wifi Code Rate not defined");
204 return (GetCodeRate() > mode.GetCodeRate());
205}
206
207bool
209{
210 // If current modulation class is DSSS and other is not, the other is always higher
213 {
214 return false;
215 }
216 // If other modulation class is DSSS and current is not, the current is always higher
219 {
220 return true;
221 }
222 // If current is not HR/DSSS while other is not, check constellation size of other against
223 // current
226 {
227 return (mode.GetConstellationSize() > GetConstellationSize());
228 }
229 // This block is for current and other mode > HR/DSSS, if constellation size
230 // is the same, check the code rate (DSSS and HR/DSSS does not define code rate)
231 else if (GetConstellationSize() == mode.GetConstellationSize() &&
234 {
235 return IsHigherCodeRate(mode);
236 }
237 // Otherwise, check constellation size of current against other,
238 // the code go here if:
239 // - both current and other mode is DSSS
240 // - current mode is HR/DSSS and other mode is not HR/DSSS
241 // - current and other mode > HR/DSSS and both constellation size is not equal
242 else
243 {
244 return (GetConstellationSize() > mode.GetConstellationSize());
245 }
246}
247
249 : m_uid(0)
250{
251}
252
254 : m_uid(uid)
255{
256}
257
258WifiMode::WifiMode(std::string name)
259{
260 *this = WifiModeFactory::GetFactory()->Search(name);
261}
262
264
266{
267}
268
270WifiModeFactory::CreateWifiMode(std::string uniqueName,
271 WifiModulationClass modClass,
272 bool isMandatory,
273 CodeRateCallback codeRateCallback,
274 ConstellationSizeCallback constellationSizeCallback,
275 PhyRateCallback phyRateCallback,
276 DataRateCallback dataRateCallback,
277 AllowedCallback isAllowedCallback)
278{
279 WifiModeFactory* factory = GetFactory();
280 uint32_t uid = factory->AllocateUid(uniqueName);
281 WifiModeItem* item = factory->Get(uid);
282 item->uniqueUid = uniqueName;
283 item->modClass = modClass;
284 // The modulation class for this WifiMode must be valid.
286
287 // Check for compatibility between modulation class and coding
288 // rate. If modulation class is DSSS then coding rate must be
289 // undefined, and vice versa. I could have done this with an
290 // assertion, but it seems better to always give the error (i.e.,
291 // not only in non-optimised builds) and the cycles that extra test
292 // here costs are only suffered at simulation setup.
293 if ((codeRateCallback() == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS &&
294 modClass != WIFI_MOD_CLASS_HR_DSSS)
295 {
296 NS_FATAL_ERROR("Error in creation of WifiMode named "
297 << uniqueName << std::endl
298 << "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is "
299 "WIFI_MOD_CLASS_DSSS or WIFI_MOD_CLASS_HR_DSSS");
300 }
301
302 item->isMandatory = isMandatory;
303 item->GetCodeRateCallback = codeRateCallback;
304 item->GetConstellationSizeCallback = constellationSizeCallback;
305 item->GetPhyRateCallback = phyRateCallback;
306 item->GetDataRateCallback = dataRateCallback;
307 item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t>();
308 item->IsAllowedCallback = isAllowedCallback;
309
310 NS_ASSERT(modClass < WIFI_MOD_CLASS_HT);
311 // fill unused MCS item with a dummy value
312 item->mcsValue = 0;
313
314 return WifiMode(uid);
315}
316
318WifiModeFactory::CreateWifiMcs(std::string uniqueName,
319 uint8_t mcsValue,
320 WifiModulationClass modClass,
321 bool isMandatory,
322 CodeRateCallback codeRateCallback,
323 ConstellationSizeCallback constellationSizeCallback,
324 PhyRateCallback phyRateCallback,
325 DataRateCallback dataRateCallback,
326 NonHtReferenceRateCallback nonHtReferenceRateCallback,
327 AllowedCallback isAllowedCallback)
328{
329 WifiModeFactory* factory = GetFactory();
330 uint32_t uid = factory->AllocateUid(uniqueName);
331 WifiModeItem* item = factory->Get(uid);
332 item->uniqueUid = uniqueName;
333 item->modClass = modClass;
334
335 NS_ASSERT(modClass >= WIFI_MOD_CLASS_HT);
336
337 item->mcsValue = mcsValue;
338 item->isMandatory = isMandatory;
339 item->GetCodeRateCallback = codeRateCallback;
340 item->GetConstellationSizeCallback = constellationSizeCallback;
341 item->GetPhyRateCallback = phyRateCallback;
342 item->GetDataRateCallback = dataRateCallback;
343 item->GetNonHtReferenceRateCallback = nonHtReferenceRateCallback;
344 item->IsAllowedCallback = isAllowedCallback;
345
346 return WifiMode(uid);
347}
348
350WifiModeFactory::Search(std::string name) const
351{
352 uint32_t j = 0;
353 for (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
354 {
355 if (i->uniqueUid == name)
356 {
357 return WifiMode(j);
358 }
359 j++;
360 }
361
362 // If we get here then a matching WifiMode was not found above. This
363 // is a fatal problem, but we try to be helpful by displaying the
364 // list of WifiModes that are supported.
365 NS_LOG_UNCOND("Could not find match for WifiMode named \"" << name << "\". Valid options are:");
366 for (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
367 {
368 NS_LOG_UNCOND(" " << i->uniqueUid);
369 }
370 // Empty fatal error to die. We've already unconditionally logged
371 // the helpful information.
372 NS_FATAL_ERROR("");
373
374 // This next line is unreachable because of the fatal error
375 // immediately above, and that is fortunate, because we have no idea
376 // what is in WifiMode (0), but we do know it is not what our caller
377 // has requested by name. It's here only because it's the safest
378 // thing that'll give valid code.
379 return WifiMode(0);
380}
381
383WifiModeFactory::AllocateUid(std::string uniqueUid)
384{
385 uint32_t j = 0;
386 for (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
387 {
388 if (i->uniqueUid == uniqueUid)
389 {
390 return j;
391 }
392 j++;
393 }
394 auto uid = static_cast<uint32_t>(m_itemList.size());
395 m_itemList.emplace_back();
396 return uid;
397}
398
401{
402 NS_ASSERT(uid < m_itemList.size());
403 return &m_itemList[uid];
404}
405
408{
409 static bool isFirstTime = true;
410 static WifiModeFactory factory;
411 if (isFirstTime)
412 {
413 uint32_t uid = factory.AllocateUid("Invalid-WifiMode");
414 WifiModeItem* item = factory.Get(uid);
415 item->uniqueUid = "Invalid-WifiMode";
417 item->isMandatory = false;
418 item->mcsValue = 0;
419 item->GetCodeRateCallback = MakeNullCallback<WifiCodeRate>();
420 item->GetConstellationSizeCallback = MakeNullCallback<uint16_t>();
421 item->GetPhyRateCallback = MakeNullCallback<uint64_t, const WifiTxVector&, uint16_t>();
422 item->GetDataRateCallback = MakeNullCallback<uint64_t, const WifiTxVector&, uint16_t>();
423 item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t>();
424 item->IsAllowedCallback = MakeNullCallback<bool, const WifiTxVector&>();
425 isFirstTime = false;
426 }
427 return &factory;
428}
429
430} // namespace ns3
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
create WifiMode class instances and keep track of them.
Definition: wifi-mode.h:275
WifiModeItem * Get(uint32_t uid)
Return a WifiModeItem at the given UID index.
Definition: wifi-mode.cc:400
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:318
uint32_t AllocateUid(std::string uniqueUid)
Allocate a WifiModeItem from a given uniqueUid.
Definition: wifi-mode.cc:383
static WifiModeFactory * GetFactory()
Return a WifiModeFactory.
Definition: wifi-mode.cc:407
WifiModeItemList m_itemList
item list
Definition: wifi-mode.h:459
WifiMode Search(std::string name) const
Search and return WifiMode from a given name.
Definition: wifi-mode.cc:350
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, AllowedCallback isAllowedCallback)
Definition: wifi-mode.cc:270
friend class WifiMode
allow WifiMode class access
Definition: wifi-mode.h:392
represent a single transmission mode
Definition: wifi-mode.h:51
WifiMode()
Create an invalid WifiMode.
Definition: wifi-mode.cc:248
uint32_t GetUid() const
Definition: wifi-mode.cc:179
std::string GetUniqueName() const
Definition: wifi-mode.cc:148
bool IsHigherDataRate(WifiMode mode) const
Definition: wifi-mode.cc:208
uint16_t GetConstellationSize() const
Definition: wifi-mode.cc:141
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:91
bool IsMandatory() const
Definition: wifi-mode.cc:156
uint64_t GetNonHtReferenceRate() const
Definition: wifi-mode.cc:192
WifiCodeRate GetCodeRate() const
Definition: wifi-mode.cc:134
uint32_t m_uid
UID.
Definition: wifi-mode.h:199
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
bool IsHigherCodeRate(WifiMode mode) const
Definition: wifi-mode.cc:201
bool IsAllowed(uint16_t channelWidth, uint8_t nss) const
Definition: wifi-mode.cc:68
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
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:66
#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:86
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#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.
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
Definition: callback.h:678
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:157
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:183
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
@ WIFI_CODE_RATE_UNDEFINED
undefined coding rate
This is the data associated to a unique WifiMode.
Definition: wifi-mode.h:409
WifiModulationClass modClass
modulation class
Definition: wifi-mode.h:411
AllowedCallback IsAllowedCallback
Callback to check whether a given combination of is allowed.
Definition: wifi-mode.h:427
std::string uniqueUid
unique UID
Definition: wifi-mode.h:410
bool isMandatory
flag to indicate whether this mode is mandatory
Definition: wifi-mode.h:412
PhyRateCallback GetPhyRateCallback
Callback to calculate PHY rate in bps of this WifiModeItem.
Definition: wifi-mode.h:420
DataRateCallback GetDataRateCallback
Callback to calculate data rate in bps of this WifiModeItem.
Definition: wifi-mode.h:422
NonHtReferenceRateCallback GetNonHtReferenceRateCallback
Callback to calculate non-HT reference rate of this WifiModeItem.
Definition: wifi-mode.h:424
ConstellationSizeCallback GetConstellationSizeCallback
Callback to retrieve constellation size of this WifiModeItem.
Definition: wifi-mode.h:417
CodeRateCallback GetCodeRateCallback
Callback to retrieve code rate of this WifiModeItem.
Definition: wifi-mode.h:415