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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 * Sébastien Deronne <sebastien.deronne@gmail.com>
8 */
9
10#include "wifi-mode.h"
11
12#include "wifi-tx-vector.h"
13
14#include "ns3/log.h"
15
16#include <cmath>
17
18namespace ns3
19{
20
21bool
22operator==(const WifiMode& a, const WifiMode& b)
23{
24 return a.GetUid() == b.GetUid();
25}
26
27bool
28operator!=(const WifiMode& a, const WifiMode& b)
29{
30 return a.GetUid() != b.GetUid();
31}
32
33bool
34operator<(const WifiMode& a, const WifiMode& b)
35{
36 return a.GetUid() < b.GetUid();
37}
38
39std::ostream&
40operator<<(std::ostream& os, const WifiMode& mode)
41{
42 os << mode.GetUniqueName();
43 return os;
44}
45
46std::istream&
47operator>>(std::istream& is, WifiMode& mode)
48{
49 std::string str;
50 is >> str;
52 return is;
53}
54
55bool
56WifiMode::IsAllowed(MHz_u channelWidth, uint8_t nss) const
57{
58 WifiTxVector txVector;
59 txVector.SetMode(WifiMode(m_uid));
60 txVector.SetChannelWidth(channelWidth);
61 txVector.SetNss(nss);
62 return IsAllowed(txVector);
63}
64
65bool
66WifiMode::IsAllowed(const WifiTxVector& txVector) const
67{
69 return item->IsAllowedCallback(txVector);
70}
71
72uint64_t
73WifiMode::GetPhyRate(MHz_u channelWidth) const
74{
75 return GetPhyRate(channelWidth, NanoSeconds(800), 1);
76}
77
78uint64_t
79WifiMode::GetPhyRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
80{
81 WifiTxVector txVector;
82 txVector.SetMode(WifiMode(m_uid));
83 txVector.SetChannelWidth(channelWidth);
84 txVector.SetGuardInterval(guardInterval);
85 txVector.SetNss(nss);
86 return GetPhyRate(txVector);
87}
88
89uint64_t
90WifiMode::GetPhyRate(const WifiTxVector& txVector, uint16_t staId) const
91{
93 return item->GetPhyRateCallback(txVector, staId);
94}
95
96uint64_t
97WifiMode::GetDataRate(MHz_u channelWidth) const
98{
99 return GetDataRate(channelWidth, NanoSeconds(800), 1);
100}
101
102uint64_t
103WifiMode::GetDataRate(const WifiTxVector& txVector, uint16_t staId) const
104{
106 return item->GetDataRateCallback(txVector, staId);
107}
108
109uint64_t
110WifiMode::GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
111{
112 NS_ASSERT(nss <= 8);
113 WifiTxVector txVector;
114 txVector.SetMode(WifiMode(m_uid));
115 txVector.SetChannelWidth(channelWidth);
116 txVector.SetGuardInterval(guardInterval);
117 txVector.SetNss(nss);
118 return GetDataRate(txVector);
119}
120
127
128uint16_t
134
135const std::string&
137{
138 // needed for ostream printing of the invalid mode
140 return item->uniqueUid;
141}
142
143bool
149
150uint8_t
152{
154 if (item->modClass >= WIFI_MOD_CLASS_HT)
155 {
156 return item->mcsValue;
157 }
158 else
159 {
160 // We should not go here!
161 NS_ASSERT(false);
162 return 0;
163 }
164}
165
168{
169 return m_uid;
170}
171
178
179uint64_t
181{
184 "Trying to get HT reference rate for a non-HT rate");
185 return item->GetNonHtReferenceRateCallback();
186}
187
188bool
190{
191 NS_ASSERT_MSG(GetCodeRate() != WIFI_CODE_RATE_UNDEFINED, "Wifi Code Rate not defined");
192 return (GetCodeRate() > mode.GetCodeRate());
193}
194
195bool
197{
198 // If current modulation class is DSSS and other is not, the other is always higher
201 {
202 return false;
203 }
204 // If other modulation class is DSSS and current is not, the current is always higher
207 {
208 return true;
209 }
210 // If current is not HR/DSSS while other is not, check constellation size of other against
211 // current
214 {
215 return (mode.GetConstellationSize() > GetConstellationSize());
216 }
217 // This block is for current and other mode > HR/DSSS, if constellation size
218 // is the same, check the code rate (DSSS and HR/DSSS does not define code rate)
219 else if (GetConstellationSize() == mode.GetConstellationSize() &&
222 {
223 return IsHigherCodeRate(mode);
224 }
225 // Otherwise, check constellation size of current against other,
226 // the code go here if:
227 // - both current and other mode is DSSS
228 // - current mode is HR/DSSS and other mode is not HR/DSSS
229 // - current and other mode > HR/DSSS and both constellation size is not equal
230 else
231 {
232 return (GetConstellationSize() > mode.GetConstellationSize());
233 }
234}
235
237 : m_uid(0)
238{
239}
240
242 : m_uid(uid)
243{
244}
245
246WifiMode::WifiMode(std::string name)
247{
248 *this = WifiModeFactory::GetFactory()->Search(name);
249}
250
252
256
258WifiModeFactory::CreateWifiMode(std::string uniqueName,
259 WifiModulationClass modClass,
260 bool isMandatory,
261 CodeRateCallback codeRateCallback,
262 ConstellationSizeCallback constellationSizeCallback,
263 PhyRateCallback phyRateCallback,
264 DataRateCallback dataRateCallback,
265 AllowedCallback isAllowedCallback)
266{
267 WifiModeFactory* factory = GetFactory();
268 uint32_t uid = factory->AllocateUid(uniqueName);
269 WifiModeItem* item = factory->Get(uid);
270 item->uniqueUid = uniqueName;
271 item->modClass = modClass;
272 // The modulation class for this WifiMode must be valid.
274
275 // Check for compatibility between modulation class and coding
276 // rate. If modulation class is DSSS then coding rate must be
277 // undefined, and vice versa. I could have done this with an
278 // assertion, but it seems better to always give the error (i.e.,
279 // not only in non-optimised builds) and the cycles that extra test
280 // here costs are only suffered at simulation setup.
281 if ((codeRateCallback() == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS &&
282 modClass != WIFI_MOD_CLASS_HR_DSSS)
283 {
284 NS_FATAL_ERROR("Error in creation of WifiMode named "
285 << uniqueName << std::endl
286 << "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is "
287 "WIFI_MOD_CLASS_DSSS or WIFI_MOD_CLASS_HR_DSSS");
288 }
289
290 item->isMandatory = isMandatory;
291 item->GetCodeRateCallback = codeRateCallback;
292 item->GetConstellationSizeCallback = constellationSizeCallback;
293 item->GetPhyRateCallback = phyRateCallback;
294 item->GetDataRateCallback = dataRateCallback;
296 item->IsAllowedCallback = isAllowedCallback;
297
298 NS_ASSERT(modClass < WIFI_MOD_CLASS_HT);
299 // fill unused MCS item with a dummy value
300 item->mcsValue = 0;
301
302 return WifiMode(uid);
303}
304
306WifiModeFactory::CreateWifiMcs(std::string uniqueName,
307 uint8_t mcsValue,
308 WifiModulationClass modClass,
309 bool isMandatory,
310 CodeRateCallback codeRateCallback,
311 ConstellationSizeCallback constellationSizeCallback,
312 PhyRateCallback phyRateCallback,
313 DataRateCallback dataRateCallback,
314 NonHtReferenceRateCallback nonHtReferenceRateCallback,
315 AllowedCallback isAllowedCallback)
316{
317 WifiModeFactory* factory = GetFactory();
318 uint32_t uid = factory->AllocateUid(uniqueName);
319 WifiModeItem* item = factory->Get(uid);
320 item->uniqueUid = uniqueName;
321 item->modClass = modClass;
322
323 NS_ASSERT(modClass >= WIFI_MOD_CLASS_HT);
324
325 item->mcsValue = mcsValue;
326 item->isMandatory = isMandatory;
327 item->GetCodeRateCallback = codeRateCallback;
328 item->GetConstellationSizeCallback = constellationSizeCallback;
329 item->GetPhyRateCallback = phyRateCallback;
330 item->GetDataRateCallback = dataRateCallback;
331 item->GetNonHtReferenceRateCallback = nonHtReferenceRateCallback;
332 item->IsAllowedCallback = isAllowedCallback;
333
334 return WifiMode(uid);
335}
336
338WifiModeFactory::Search(std::string name) const
339{
340 uint32_t j = 0;
341 for (auto 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 \"" << name << "\". Valid options are:");
354 for (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
355 {
356 NS_LOG_UNCOND(" " << i->uniqueUid);
357 }
358 // Empty fatal error to die. We've already unconditionally logged
359 // the helpful information.
360 NS_FATAL_ERROR("");
361
362 // This next line is unreachable because of the fatal error
363 // immediately above, and that is fortunate, because we have no idea
364 // what is in WifiMode (0), but we do know it is not what our caller
365 // has requested by name. It's here only because it's the safest
366 // thing that'll give valid code.
367 return WifiMode(0);
368}
369
371WifiModeFactory::AllocateUid(std::string uniqueUid)
372{
373 uint32_t j = 0;
374 for (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
375 {
376 if (i->uniqueUid == uniqueUid)
377 {
378 return j;
379 }
380 j++;
381 }
382 auto uid = static_cast<uint32_t>(m_itemList.size());
383 m_itemList.emplace_back();
384 return uid;
385}
386
389{
390 NS_ASSERT(uid < m_itemList.size());
391 return &m_itemList[uid];
392}
393
396{
397 static bool isFirstTime = true;
398 static WifiModeFactory factory;
399 if (isFirstTime)
400 {
401 uint32_t uid = factory.AllocateUid("Invalid-WifiMode");
402 WifiModeItem* item = factory.Get(uid);
403 item->uniqueUid = "Invalid-WifiMode";
405 item->isMandatory = false;
406 item->mcsValue = 0;
413 isFirstTime = false;
414 }
415 return &factory;
416}
417
418} // namespace ns3
bool IsNull() const
Check for null implementation.
Definition callback.h:555
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
create WifiMode class instances and keep track of them.
Definition wifi-mode.h:264
WifiModeItem * Get(uint32_t uid)
Return a WifiModeItem at the given UID index.
Definition wifi-mode.cc:388
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:306
uint32_t AllocateUid(std::string uniqueUid)
Allocate a WifiModeItem from a given uniqueUid.
Definition wifi-mode.cc:371
static WifiModeFactory * GetFactory()
Return a WifiModeFactory.
Definition wifi-mode.cc:395
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:338
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, AllowedCallback isAllowedCallback)
Definition wifi-mode.cc:258
friend class WifiMode
allow WifiMode class access
Definition wifi-mode.h:381
represent a single transmission mode
Definition wifi-mode.h:40
WifiMode()
Create an invalid WifiMode.
Definition wifi-mode.cc:236
uint32_t GetUid() const
Definition wifi-mode.cc:167
const std::string & GetUniqueName() const
Definition wifi-mode.cc:136
bool IsHigherDataRate(WifiMode mode) const
Definition wifi-mode.cc:196
uint16_t GetConstellationSize() const
Definition wifi-mode.cc:129
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:173
uint64_t GetPhyRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:79
bool IsMandatory() const
Definition wifi-mode.cc:144
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:110
uint64_t GetNonHtReferenceRate() const
Definition wifi-mode.cc:180
WifiCodeRate GetCodeRate() const
Definition wifi-mode.cc:122
uint32_t m_uid
UID.
Definition wifi-mode.h:188
bool IsHigherCodeRate(WifiMode mode) const
Definition wifi-mode.cc:189
bool IsAllowed(MHz_u channelWidth, uint8_t nss) const
Definition wifi-mode.cc:56
uint8_t GetMcsValue() const
Definition wifi-mode.cc:151
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetGuardInterval(Time guardInterval)
Sets the guard interval duration (in nanoseconds)
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
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:55
#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:75
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
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:658
bool operator==(const EventId &a, const EventId &b)
Definition event-id.h:155
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:168
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:398
WifiModulationClass modClass
modulation class
Definition wifi-mode.h:400
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:399
bool isMandatory
flag to indicate whether this mode is mandatory
Definition wifi-mode.h:401
PhyRateCallback GetPhyRateCallback
Callback to calculate PHY rate in bps of this WifiModeItem.
Definition wifi-mode.h:409
DataRateCallback GetDataRateCallback
Callback to calculate data rate in bps of this WifiModeItem.
Definition wifi-mode.h:411
NonHtReferenceRateCallback GetNonHtReferenceRateCallback
Callback to calculate non-HT reference rate of this WifiModeItem.
Definition wifi-mode.h:413
ConstellationSizeCallback GetConstellationSizeCallback
Callback to retrieve constellation size of this WifiModeItem.
Definition wifi-mode.h:406
CodeRateCallback GetCodeRateCallback
Callback to retrieve code rate of this WifiModeItem.
Definition wifi-mode.h:404