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/he-ru.h"
15#include "ns3/log.h"
16
17#include <cmath>
18
19namespace ns3
20{
21
22bool
23operator==(const WifiMode& a, const WifiMode& b)
24{
25 return a.GetUid() == b.GetUid();
26}
27
28bool
29operator!=(const WifiMode& a, const WifiMode& b)
30{
31 return a.GetUid() != b.GetUid();
32}
33
34bool
35operator<(const WifiMode& a, const WifiMode& b)
36{
37 return a.GetUid() < b.GetUid();
38}
39
40std::ostream&
41operator<<(std::ostream& os, const WifiMode& mode)
42{
43 os << mode.GetUniqueName();
44 return os;
45}
46
47std::istream&
48operator>>(std::istream& is, WifiMode& mode)
49{
50 std::string str;
51 is >> str;
53 return is;
54}
55
56bool
57WifiMode::IsAllowed(MHz_u channelWidth, uint8_t nss) const
58{
59 WifiTxVector txVector;
60 txVector.SetMode(WifiMode(m_uid));
61 txVector.SetChannelWidth(channelWidth);
62 txVector.SetNss(nss);
63 return IsAllowed(txVector);
64}
65
66bool
67WifiMode::IsAllowed(const WifiTxVector& txVector) const
68{
70 return item->IsAllowedCallback(txVector);
71}
72
73uint64_t
74WifiMode::GetPhyRate(MHz_u channelWidth) const
75{
76 return GetPhyRate(channelWidth, NanoSeconds(800), 1);
77}
78
79uint64_t
80WifiMode::GetPhyRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
81{
82 WifiTxVector txVector;
83 txVector.SetMode(WifiMode(m_uid));
84 txVector.SetChannelWidth(channelWidth);
85 txVector.SetGuardInterval(guardInterval);
86 txVector.SetNss(nss);
87 return GetPhyRate(txVector);
88}
89
90uint64_t
91WifiMode::GetPhyRate(const WifiTxVector& txVector, uint16_t staId) const
92{
94 return item->GetPhyRateCallback(txVector, staId);
95}
96
97uint64_t
98WifiMode::GetDataRate(MHz_u channelWidth) const
99{
100 return GetDataRate(channelWidth, NanoSeconds(800), 1);
101}
102
103uint64_t
104WifiMode::GetDataRate(const WifiTxVector& txVector, uint16_t staId) const
105{
107 return item->GetDataRateCallback(txVector, staId);
108}
109
110uint64_t
111WifiMode::GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
112{
113 NS_ASSERT(nss <= 8);
114 WifiTxVector txVector;
115 txVector.SetMode(WifiMode(m_uid));
116 txVector.SetChannelWidth(channelWidth);
117 txVector.SetGuardInterval(guardInterval);
118 txVector.SetNss(nss);
119 return GetDataRate(txVector);
120}
121
128
129uint16_t
135
136const std::string&
138{
139 // needed for ostream printing of the invalid mode
141 return item->uniqueUid;
142}
143
144bool
150
151uint8_t
153{
155 if (item->modClass >= WIFI_MOD_CLASS_HT)
156 {
157 return item->mcsValue;
158 }
159 else
160 {
161 // We should not go here!
162 NS_ASSERT(false);
163 return 0;
164 }
165}
166
169{
170 return m_uid;
171}
172
179
180uint64_t
182{
185 "Trying to get HT reference rate for a non-HT rate");
186 return item->GetNonHtReferenceRateCallback();
187}
188
189bool
191{
192 NS_ASSERT_MSG(GetCodeRate() != WIFI_CODE_RATE_UNDEFINED, "Wifi Code Rate not defined");
193 return (GetCodeRate() > mode.GetCodeRate());
194}
195
196bool
198{
199 // If current modulation class is DSSS and other is not, the other is always higher
202 {
203 return false;
204 }
205 // If other modulation class is DSSS and current is not, the current is always higher
208 {
209 return true;
210 }
211 // If current is not HR/DSSS while other is not, check constellation size of other against
212 // current
215 {
216 return (mode.GetConstellationSize() > GetConstellationSize());
217 }
218 // This block is for current and other mode > HR/DSSS, if constellation size
219 // is the same, check the code rate (DSSS and HR/DSSS does not define code rate)
220 else if (GetConstellationSize() == mode.GetConstellationSize() &&
223 {
224 return IsHigherCodeRate(mode);
225 }
226 // Otherwise, check constellation size of current against other,
227 // the code go here if:
228 // - both current and other mode is DSSS
229 // - current mode is HR/DSSS and other mode is not HR/DSSS
230 // - current and other mode > HR/DSSS and both constellation size is not equal
231 else
232 {
233 return (GetConstellationSize() > mode.GetConstellationSize());
234 }
235}
236
238 : m_uid(0)
239{
240}
241
243 : m_uid(uid)
244{
245}
246
247WifiMode::WifiMode(std::string name)
248{
249 *this = WifiModeFactory::GetFactory()->Search(name);
250}
251
253
257
259WifiModeFactory::CreateWifiMode(std::string uniqueName,
260 WifiModulationClass modClass,
261 bool isMandatory,
262 CodeRateCallback codeRateCallback,
263 ConstellationSizeCallback constellationSizeCallback,
264 PhyRateCallback phyRateCallback,
265 DataRateCallback dataRateCallback,
266 AllowedCallback isAllowedCallback)
267{
268 WifiModeFactory* factory = GetFactory();
269 uint32_t uid = factory->AllocateUid(uniqueName);
270 WifiModeItem* item = factory->Get(uid);
271 item->uniqueUid = uniqueName;
272 item->modClass = modClass;
273 // The modulation class for this WifiMode must be valid.
275
276 // Check for compatibility between modulation class and coding
277 // rate. If modulation class is DSSS then coding rate must be
278 // undefined, and vice versa. I could have done this with an
279 // assertion, but it seems better to always give the error (i.e.,
280 // not only in non-optimised builds) and the cycles that extra test
281 // here costs are only suffered at simulation setup.
282 if ((codeRateCallback() == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS &&
283 modClass != WIFI_MOD_CLASS_HR_DSSS)
284 {
285 NS_FATAL_ERROR("Error in creation of WifiMode named "
286 << uniqueName << std::endl
287 << "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is "
288 "WIFI_MOD_CLASS_DSSS or WIFI_MOD_CLASS_HR_DSSS");
289 }
290
291 item->isMandatory = isMandatory;
292 item->GetCodeRateCallback = codeRateCallback;
293 item->GetConstellationSizeCallback = constellationSizeCallback;
294 item->GetPhyRateCallback = phyRateCallback;
295 item->GetDataRateCallback = dataRateCallback;
297 item->IsAllowedCallback = isAllowedCallback;
298
299 NS_ASSERT(modClass < WIFI_MOD_CLASS_HT);
300 // fill unused MCS item with a dummy value
301 item->mcsValue = 0;
302
303 return WifiMode(uid);
304}
305
307WifiModeFactory::CreateWifiMcs(std::string uniqueName,
308 uint8_t mcsValue,
309 WifiModulationClass modClass,
310 bool isMandatory,
311 CodeRateCallback codeRateCallback,
312 ConstellationSizeCallback constellationSizeCallback,
313 PhyRateCallback phyRateCallback,
314 DataRateCallback dataRateCallback,
315 NonHtReferenceRateCallback nonHtReferenceRateCallback,
316 AllowedCallback isAllowedCallback)
317{
318 WifiModeFactory* factory = GetFactory();
319 uint32_t uid = factory->AllocateUid(uniqueName);
320 WifiModeItem* item = factory->Get(uid);
321 item->uniqueUid = uniqueName;
322 item->modClass = modClass;
323
324 NS_ASSERT(modClass >= WIFI_MOD_CLASS_HT);
325
326 item->mcsValue = mcsValue;
327 item->isMandatory = isMandatory;
328 item->GetCodeRateCallback = codeRateCallback;
329 item->GetConstellationSizeCallback = constellationSizeCallback;
330 item->GetPhyRateCallback = phyRateCallback;
331 item->GetDataRateCallback = dataRateCallback;
332 item->GetNonHtReferenceRateCallback = nonHtReferenceRateCallback;
333 item->IsAllowedCallback = isAllowedCallback;
334
335 return WifiMode(uid);
336}
337
339WifiModeFactory::Search(std::string name) const
340{
341 uint32_t j = 0;
342 for (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
343 {
344 if (i->uniqueUid == name)
345 {
346 return WifiMode(j);
347 }
348 j++;
349 }
350
351 // If we get here then a matching WifiMode was not found above. This
352 // is a fatal problem, but we try to be helpful by displaying the
353 // list of WifiModes that are supported.
354 NS_LOG_UNCOND("Could not find match for WifiMode named \"" << name << "\". Valid options are:");
355 for (auto 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 (auto i = m_itemList.begin(); i != m_itemList.end(); i++)
376 {
377 if (i->uniqueUid == uniqueUid)
378 {
379 return j;
380 }
381 j++;
382 }
383 auto uid = static_cast<uint32_t>(m_itemList.size());
384 m_itemList.emplace_back();
385 return uid;
386}
387
390{
391 NS_ASSERT(uid < m_itemList.size());
392 return &m_itemList[uid];
393}
394
397{
398 static bool isFirstTime = true;
399 static WifiModeFactory factory;
400 if (isFirstTime)
401 {
402 uint32_t uid = factory.AllocateUid("Invalid-WifiMode");
403 WifiModeItem* item = factory.Get(uid);
404 item->uniqueUid = "Invalid-WifiMode";
406 item->isMandatory = false;
407 item->mcsValue = 0;
414 isFirstTime = false;
415 }
416 return &factory;
417}
418
419} // 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:389
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:307
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:396
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:339
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, AllowedCallback isAllowedCallback)
Definition wifi-mode.cc:259
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:237
uint32_t GetUid() const
Definition wifi-mode.cc:168
const std::string & GetUniqueName() const
Definition wifi-mode.cc:137
bool IsHigherDataRate(WifiMode mode) const
Definition wifi-mode.cc:197
uint16_t GetConstellationSize() const
Definition wifi-mode.cc:130
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:174
uint64_t GetPhyRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:80
bool IsMandatory() const
Definition wifi-mode.cc:145
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:111
uint64_t GetNonHtReferenceRate() const
Definition wifi-mode.cc:181
WifiCodeRate GetCodeRate() const
Definition wifi-mode.cc:123
uint32_t m_uid
UID.
Definition wifi-mode.h:188
bool IsHigherCodeRate(WifiMode mode) const
Definition wifi-mode.cc:190
bool IsAllowed(MHz_u channelWidth, uint8_t nss) const
Definition wifi-mode.cc:57
uint8_t GetMcsValue() const
Definition wifi-mode.cc:152
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:1344
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