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 NS_ASSERT_MSG(false, "GetMcsValue() cannot be called for non-HT modulations");
161 return 0;
162 }
163}
164
167{
168 return m_uid;
169}
170
177
178uint64_t
180{
183 "Trying to get HT reference rate for a non-HT rate");
184 return item->GetNonHtReferenceRateCallback();
185}
186
187bool
189{
190 NS_ASSERT_MSG(GetCodeRate() != WIFI_CODE_RATE_UNDEFINED, "Wifi Code Rate not defined");
191 return (GetCodeRate() > mode.GetCodeRate());
192}
193
194bool
196{
197 // If current modulation class is DSSS and other is not, the other is always higher
200 {
201 return false;
202 }
203 // If other modulation class is DSSS and current is not, the current is always higher
206 {
207 return true;
208 }
209 // If current is not HR/DSSS while other is not, check constellation size of other against
210 // current
213 {
214 return (mode.GetConstellationSize() > GetConstellationSize());
215 }
216 // This block is for current and other mode > HR/DSSS, if constellation size
217 // is the same, check the code rate (DSSS and HR/DSSS does not define code rate)
218 else if (GetConstellationSize() == mode.GetConstellationSize() &&
221 {
222 return IsHigherCodeRate(mode);
223 }
224 // Otherwise, check constellation size of current against other,
225 // the code go here if:
226 // - both current and other mode is DSSS
227 // - current mode is HR/DSSS and other mode is not HR/DSSS
228 // - current and other mode > HR/DSSS and both constellation size is not equal
229 else
230 {
231 return (GetConstellationSize() > mode.GetConstellationSize());
232 }
233}
234
236 : m_uid(0)
237{
238}
239
241 : m_uid(uid)
242{
243}
244
245WifiMode::WifiMode(std::string name)
246{
247 *this = WifiModeFactory::GetFactory()->Search(name);
248}
249
251
255
257WifiModeFactory::CreateWifiMode(std::string uniqueName,
258 WifiModulationClass modClass,
259 bool isMandatory,
260 CodeRateCallback codeRateCallback,
261 ConstellationSizeCallback constellationSizeCallback,
262 PhyRateCallback phyRateCallback,
263 DataRateCallback dataRateCallback,
264 AllowedCallback isAllowedCallback)
265{
266 WifiModeFactory* factory = GetFactory();
267 uint32_t uid = factory->AllocateUid(uniqueName);
268 WifiModeItem* item = factory->Get(uid);
269 item->uniqueUid = uniqueName;
270 item->modClass = modClass;
271 // The modulation class for this WifiMode must be valid.
273
274 // Check for compatibility between modulation class and coding
275 // rate. If modulation class is DSSS then coding rate must be
276 // undefined, and vice versa. I could have done this with an
277 // assertion, but it seems better to always give the error (i.e.,
278 // not only in non-optimised builds) and the cycles that extra test
279 // here costs are only suffered at simulation setup.
280 if ((codeRateCallback() == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS &&
281 modClass != WIFI_MOD_CLASS_HR_DSSS)
282 {
283 NS_FATAL_ERROR("Error in creation of WifiMode named "
284 << uniqueName << std::endl
285 << "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is "
286 "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;
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 uint32_t j = 0;
340 for (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
341 {
342 if (i->uniqueUid == name)
343 {
344 return WifiMode(j);
345 }
346 j++;
347 }
348
349 // If we get here then a matching WifiMode was not found above. This
350 // is a fatal problem, but we try to be helpful by displaying the
351 // list of WifiModes that are supported.
352 NS_LOG_UNCOND("Could not find match for WifiMode named \"" << name << "\". Valid options are:");
353 for (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
354 {
355 NS_LOG_UNCOND(" " << i->uniqueUid);
356 }
357 // Empty fatal error to die. We've already unconditionally logged
358 // the helpful information.
359 NS_FATAL_ERROR("");
360
361 // This next line is unreachable because of the fatal error
362 // immediately above, and that is fortunate, because we have no idea
363 // what is in WifiMode (0), but we do know it is not what our caller
364 // has requested by name. It's here only because it's the safest
365 // thing that'll give valid code.
366 return WifiMode(0);
367}
368
370WifiModeFactory::AllocateUid(std::string uniqueUid)
371{
372 uint32_t j = 0;
373 for (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
374 {
375 if (i->uniqueUid == uniqueUid)
376 {
377 return j;
378 }
379 j++;
380 }
381 auto uid = static_cast<uint32_t>(m_itemList.size());
382 m_itemList.emplace_back();
383 return uid;
384}
385
388{
389 NS_ASSERT(uid < m_itemList.size());
390 return &m_itemList[uid];
391}
392
395{
396 static bool isFirstTime = true;
397 static WifiModeFactory factory;
398 if (isFirstTime)
399 {
400 uint32_t uid = factory.AllocateUid("Invalid-WifiMode");
401 WifiModeItem* item = factory.Get(uid);
402 item->uniqueUid = "Invalid-WifiMode";
404 item->isMandatory = false;
405 item->mcsValue = 0;
412 isFirstTime = false;
413 }
414 return &factory;
415}
416
417} // 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:267
WifiModeItem * Get(uint32_t uid)
Return a WifiModeItem at the given UID index.
Definition wifi-mode.cc:387
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:370
static WifiModeFactory * GetFactory()
Return a WifiModeFactory.
Definition wifi-mode.cc:394
WifiModeItemList m_itemList
item list
Definition wifi-mode.h:451
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:257
friend class WifiMode
allow WifiMode class access
Definition wifi-mode.h:384
represent a single transmission mode
Definition wifi-mode.h:40
WifiMode()
Create an invalid WifiMode.
Definition wifi-mode.cc:235
uint32_t GetUid() const
Definition wifi-mode.cc:166
const std::string & GetUniqueName() const
Definition wifi-mode.cc:136
bool IsHigherDataRate(WifiMode mode) const
Definition wifi-mode.cc:195
uint16_t GetConstellationSize() const
Definition wifi-mode.cc:129
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:172
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:179
WifiCodeRate GetCodeRate() const
Definition wifi-mode.cc:122
uint32_t m_uid
UID.
Definition wifi-mode.h:191
bool IsHigherCodeRate(WifiMode mode) const
Definition wifi-mode.cc:188
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:401
WifiModulationClass modClass
modulation class
Definition wifi-mode.h:403
AllowedCallback IsAllowedCallback
Callback to check whether a given combination of is allowed.
Definition wifi-mode.h:419
std::string uniqueUid
unique UID
Definition wifi-mode.h:402
bool isMandatory
flag to indicate whether this mode is mandatory
Definition wifi-mode.h:404
PhyRateCallback GetPhyRateCallback
Callback to calculate PHY rate in bps of this WifiModeItem.
Definition wifi-mode.h:412
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:416
ConstellationSizeCallback GetConstellationSizeCallback
Callback to retrieve constellation size of this WifiModeItem.
Definition wifi-mode.h:409
CodeRateCallback GetCodeRateCallback
Callback to retrieve code rate of this WifiModeItem.
Definition wifi-mode.h:407