A Discrete-Event Network Simulator
API
wifi-tx-vector.cc
Go to the documentation of this file.
1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2010 CTTC
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: Nicola Baldo <nbaldo@cttc.es>
19 * Ghada Badawy <gbadawy@gmail.com>
20 */
21
22#include "wifi-tx-vector.h"
23#include "wifi-phy-common.h"
24#include "ns3/abort.h"
25
26namespace ns3 {
27
29 : m_preamble (WIFI_PREAMBLE_LONG),
30 m_channelWidth (20),
31 m_guardInterval (800),
32 m_nTx (1),
33 m_nss (1),
34 m_ness (0),
35 m_aggregation (false),
36 m_stbc (false),
37 m_ldpc (false),
38 m_bssColor (0),
39 m_length (0),
40 m_modeInitialized (false)
41{
42}
43
45 uint8_t powerLevel,
46 WifiPreamble preamble,
47 uint16_t guardInterval,
48 uint8_t nTx,
49 uint8_t nss,
50 uint8_t ness,
51 uint16_t channelWidth,
52 bool aggregation,
53 bool stbc,
54 bool ldpc,
55 uint8_t bssColor,
56 uint16_t length)
57 : m_mode (mode),
58 m_txPowerLevel (powerLevel),
59 m_preamble (preamble),
60 m_channelWidth (channelWidth),
61 m_guardInterval (guardInterval),
62 m_nTx (nTx),
63 m_nss (nss),
64 m_ness (ness),
65 m_aggregation (aggregation),
66 m_stbc (stbc),
67 m_ldpc (ldpc),
68 m_bssColor (bssColor),
69 m_length (length),
70 m_modeInitialized (true)
71{
72}
73
75 : m_mode (txVector.m_mode),
76 m_txPowerLevel (txVector.m_txPowerLevel),
77 m_preamble (txVector.m_preamble),
78 m_channelWidth (txVector.m_channelWidth),
79 m_guardInterval (txVector.m_guardInterval),
80 m_nTx (txVector.m_nTx),
81 m_nss (txVector.m_nss),
82 m_ness (txVector.m_ness),
83 m_aggregation (txVector.m_aggregation),
84 m_stbc (txVector.m_stbc),
85 m_ldpc (txVector.m_ldpc),
86 m_bssColor (txVector.m_bssColor),
87 m_length (txVector.m_length),
88 m_modeInitialized (txVector.m_modeInitialized)
89{
90 m_muUserInfos.clear ();
91 if (!txVector.m_muUserInfos.empty ()) //avoids crashing for loop
92 {
93 for (auto & info : txVector.m_muUserInfos)
94 {
95 m_muUserInfos.insert (std::make_pair (info.first, info.second));
96 }
97 }
98}
99
101{
102 m_muUserInfos.clear ();
103}
104
105bool
107{
108 return m_modeInitialized;
109}
110
112WifiTxVector::GetMode (uint16_t staId) const
113{
115 {
116 NS_FATAL_ERROR ("WifiTxVector mode must be set before using");
117 }
118 if (IsMu ())
119 {
120 NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
121 NS_ASSERT (m_muUserInfos.find (staId) != m_muUserInfos.end ());
122 return m_muUserInfos.at (staId).mcs;
123 }
124 return m_mode;
125}
126
129{
130 NS_ABORT_MSG_IF (!m_modeInitialized, "WifiTxVector mode must be set before using");
131
132 if (IsMu ())
133 {
134 NS_ASSERT (!m_muUserInfos.empty ());
135 // all the modes belong to the same modulation class
136 return m_muUserInfos.begin ()->second.mcs.GetModulationClass ();
137 }
138 return m_mode.GetModulationClass ();
139}
140
141uint8_t
143{
144 return m_txPowerLevel;
145}
146
149{
150 return m_preamble;
151}
152
153uint16_t
155{
156 return m_channelWidth;
157}
158
159uint16_t
161{
162 return m_guardInterval;
163}
164
165uint8_t
167{
168 return m_nTx;
169}
170
171uint8_t
172WifiTxVector::GetNss (uint16_t staId) const
173{
174 if (IsMu ())
175 {
176 NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
177 NS_ASSERT (m_muUserInfos.find (staId) != m_muUserInfos.end ());
178 return m_muUserInfos.at (staId).nss;
179 }
180 return m_nss;
181}
182
183uint8_t
185{
186 uint8_t nss = 0;
187 if (IsMu ())
188 {
189 for (const auto & info : m_muUserInfos)
190 {
191 nss = (nss < info.second.nss) ? info.second.nss : nss;
192 }
193 }
194 else
195 {
196 nss = m_nss;
197 }
198 return nss;
199}
200
201uint8_t
203{
204 return m_ness;
205}
206
207bool
209{
210 return m_aggregation;
211}
212
213bool
215{
216 return m_stbc;
217}
218
219bool
221{
222 return m_ldpc;
223}
224
225void
227{
228 m_mode = mode;
229 m_modeInitialized = true;
230}
231
232void
233WifiTxVector::SetMode (WifiMode mode, uint16_t staId)
234{
235 NS_ABORT_MSG_IF (!IsMu (), "Not a MU transmission");
236 NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for MU");
237 m_muUserInfos[staId].mcs = mode;
238 m_modeInitialized = true;
239}
240
241void
243{
244 m_txPowerLevel = powerlevel;
245}
246
247void
249{
250 m_preamble = preamble;
251}
252
253void
254WifiTxVector::SetChannelWidth (uint16_t channelWidth)
255{
256 m_channelWidth = channelWidth;
257}
258
259void
260WifiTxVector::SetGuardInterval (uint16_t guardInterval)
261{
262 m_guardInterval = guardInterval;
263}
264
265void
267{
268 m_nTx = nTx;
269}
270
271void
273{
274 m_nss = nss;
275}
276
277void
278WifiTxVector::SetNss (uint8_t nss, uint16_t staId)
279{
280 NS_ABORT_MSG_IF (!IsMu (), "Not a MU transmission");
281 NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for MU");
282 m_muUserInfos[staId].nss = nss;
283}
284
285void
287{
288 m_ness = ness;
289}
290
291void
293{
294 m_aggregation = aggregation;
295}
296
297void
299{
300 m_stbc = stbc;
301}
302
303void
305{
306 m_ldpc = ldpc;
307}
308
309void
311{
312 m_bssColor = color;
313}
314
315uint8_t
317{
318 return m_bssColor;
319}
320
321void
322WifiTxVector::SetLength (uint16_t length)
323{
324 m_length = length;
325}
326
327uint16_t
329{
330 return m_length;
331}
332
333bool
335{
336 if (!GetModeInitialized ())
337 {
338 return false;
339 }
340 std::string modeName = m_mode.GetUniqueName ();
341 if (m_channelWidth == 20)
342 {
343 if (m_nss != 3 && m_nss != 6)
344 {
345 return (modeName != "VhtMcs9");
346 }
347 }
348 else if (m_channelWidth == 80)
349 {
350 if (m_nss == 3 || m_nss == 7)
351 {
352 return (modeName != "VhtMcs6");
353 }
354 else if (m_nss == 6)
355 {
356 return (modeName != "VhtMcs9");
357 }
358 }
359 else if (m_channelWidth == 160)
360 {
361 if (m_nss == 3)
362 {
363 return (modeName != "VhtMcs9");
364 }
365 }
366 return true;
367}
368
369bool
371{
372 return ns3::IsMu (m_preamble);
373}
374
375bool
377{
378 return ns3::IsDlMu (m_preamble);
379}
380
381bool
383{
384 return ns3::IsUlMu (m_preamble);
385}
386
388WifiTxVector::GetRu (uint16_t staId) const
389{
390 NS_ABORT_MSG_IF (!IsMu (), "RU only available for MU");
391 NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for MU");
392 return m_muUserInfos.at (staId).ru;
393}
394
395void
397{
398 NS_ABORT_MSG_IF (!IsMu (), "RU only available for MU");
399 NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for MU");
400 m_muUserInfos[staId].ru = ru;
401}
402
404WifiTxVector::GetHeMuUserInfo (uint16_t staId) const
405{
406 NS_ABORT_MSG_IF (!IsMu (), "HE MU user info only available for MU");
407 return m_muUserInfos.at (staId);
408}
409
410void
412{
413 NS_ABORT_MSG_IF (!IsMu (), "HE MU user info only available for MU");
414 NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for MU");
415 NS_ABORT_MSG_IF (userInfo.mcs.GetModulationClass () < WIFI_MOD_CLASS_HE, "Only HE (or newer) modes authorized for MU");
416 m_muUserInfos[staId] = userInfo;
417 m_modeInitialized = true;
418}
419
422{
423 NS_ABORT_MSG_IF (!IsMu (), "HE MU user info map only available for MU");
424 return m_muUserInfos;
425}
426
429{
430 NS_ABORT_MSG_IF (!IsMu (), "HE MU user info map only available for MU");
431 return m_muUserInfos;
432}
433
434std::pair<std::size_t, std::size_t>
436{
437 //MU-MIMO is not handled for now, i.e. one station per RU
438
439 if (m_channelWidth == 20)
440 {
441 return std::make_pair (m_muUserInfos.size (), 0); //all RUs are in HE-SIG-B content channel 1
442 }
443
444 HeRu::SubcarrierGroup toneRangesContentChannel1, toneRangesContentChannel2;
445 // See section 27.3.10.8.3 of IEEE 802.11ax draft 4.0 for tone ranges per HE-SIG-B content channel
446 switch (m_channelWidth)
447 {
448 case 40:
449 toneRangesContentChannel1.push_back (std::make_pair (-244, -3));
450 toneRangesContentChannel2.push_back (std::make_pair (3, 244));
451 break;
452 case 80:
453 toneRangesContentChannel1.push_back (std::make_pair (-500, -259));
454 toneRangesContentChannel2.push_back (std::make_pair (-258, -17));
455 toneRangesContentChannel1.push_back (std::make_pair (-16, -4)); //first part of center carrier (in HE-SIG-B content channel 1)
456 toneRangesContentChannel1.push_back (std::make_pair (4, 16)); //second part of center carrier (in HE-SIG-B content channel 1)
457 toneRangesContentChannel1.push_back (std::make_pair (17, 258));
458 toneRangesContentChannel2.push_back (std::make_pair (259, 500));
459 break;
460 case 160:
461 toneRangesContentChannel1.push_back (std::make_pair (-1012, -771));
462 toneRangesContentChannel2.push_back (std::make_pair (-770, -529));
463 toneRangesContentChannel1.push_back (std::make_pair (-528, -516)); //first part of center carrier of lower 80 MHz band (in HE-SIG-B content channel 1)
464 toneRangesContentChannel1.push_back (std::make_pair (-508, -496)); //second part of center carrier of lower 80 MHz band (in HE-SIG-B content channel 1)
465 toneRangesContentChannel1.push_back (std::make_pair (-495, -254));
466 toneRangesContentChannel2.push_back (std::make_pair (-253, -12));
467 toneRangesContentChannel1.push_back (std::make_pair (12, 253));
468 toneRangesContentChannel2.push_back (std::make_pair (254, 495));
469 toneRangesContentChannel2.push_back (std::make_pair (496, 508)); //first part of center carrier of upper 80 MHz band (in HE-SIG-B content channel 2)
470 toneRangesContentChannel2.push_back (std::make_pair (516, 528)); //second part of center carrier of upper 80 MHz band (in HE-SIG-B content channel 2)
471 toneRangesContentChannel1.push_back (std::make_pair (529, 770));
472 toneRangesContentChannel2.push_back (std::make_pair (771, 1012));
473 break;
474 default:
475 NS_ABORT_MSG ("Unknown channel width: " << m_channelWidth);
476 }
477
478 std::size_t numRusContentChannel1 = 0;
479 std::size_t numRusContentChannel2 = 0;
480 for (auto & userInfo : m_muUserInfos)
481 {
482 HeRu::RuSpec ru = userInfo.second.ru;
483 if (!ru.IsPhyIndexSet ())
484 {
485 // this method can be called when calculating the TX duration of a frame
486 // and at that time the RU PHY index may have not been set yet
488 }
489 if (HeRu::DoesOverlap (m_channelWidth, ru, toneRangesContentChannel1))
490 {
491 numRusContentChannel1++;
492 }
493 if (HeRu::DoesOverlap (m_channelWidth, ru, toneRangesContentChannel2))
494 {
495 numRusContentChannel2++;
496 }
497 }
498 return std::make_pair (numRusContentChannel1, numRusContentChannel2);
499}
500
501std::ostream & operator << ( std::ostream &os, const WifiTxVector &v)
502{
503 if (!v.IsValid ())
504 {
505 os << "TXVECTOR not valid";
506 return os;
507 }
508 os << "txpwrlvl: " << +v.GetTxPowerLevel ()
509 << " preamble: " << v.GetPreambleType ()
510 << " channel width: " << v.GetChannelWidth ()
511 << " GI: " << v.GetGuardInterval ()
512 << " NTx: " << +v.GetNTx ()
513 << " Ness: " << +v.GetNess ()
514 << " MPDU aggregation: " << v.IsAggregation ()
515 << " STBC: " << v.IsStbc ()
516 << " FEC coding: " << (v.IsLdpc () ? "LDPC" : "BCC");
518 {
519 os << " BSS color: " << +v.GetBssColor ();
520 }
521 if (v.IsUlMu ())
522 {
523 os << " Length: " << v.GetLength ();
524 }
525 if (v.IsMu ())
526 {
528 os << " num User Infos: " << userInfoMap.size ();
529 for (auto & ui : userInfoMap)
530 {
531 os << ", {STA-ID: " << ui.first
532 << ", " << ui.second.ru
533 << ", MCS: " << ui.second.mcs
534 << ", Nss: " << +ui.second.nss << "}";
535 }
536 }
537 else
538 {
539 os << " mode: " << v.GetMode ()
540 << " Nss: " << +v.GetNss ();
541 }
542 return os;
543}
544
545bool
547{
548 return ru == other.ru
549 && mcs.GetMcsValue () == other.mcs.GetMcsValue ()
550 && nss == other.nss;
551}
552
553bool
555{
556 return !(*this == other);
557}
558
559} //namespace ns3
RU Specification.
Definition: he-ru.h:68
bool IsPhyIndexSet(void) const
Return true if the RU PHY index has been set, false otherwise.
Definition: he-ru.cc:206
void SetPhyIndex(uint16_t bw, uint8_t p20Index)
Set the RU PHY index.
Definition: he-ru.cc:188
static bool DoesOverlap(uint16_t bw, RuSpec ru, const std::vector< RuSpec > &v)
Check whether the given RU overlaps with the given set of RUs.
Definition: he-ru.cc:352
std::vector< SubcarrierRange > SubcarrierGroup
a vector of subcarrier ranges defining a subcarrier group
Definition: he-ru.h:56
represent a single transmission mode
Definition: wifi-mode.h:48
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:155
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:177
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:140
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint8_t GetBssColor(void) const
Get the BSS color.
uint16_t m_channelWidth
channel width in MHz
void SetStbc(bool stbc)
Sets if STBC is being used.
void SetNess(uint8_t ness)
Sets the Ness number.
bool IsDlMu(void) const
Return true if this TX vector is used for a downlink multi-user transmission.
bool m_aggregation
Flag whether the PSDU contains A-MPDU.
uint8_t GetNTx(void) const
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void SetLdpc(bool ldpc)
Sets if LDPC FEC coding is being used.
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
WifiMode m_mode
The DATARATE parameter in Table 15-4.
std::map< uint16_t, HeMuUserInfo > HeMuUserInfoMap
map of HE MU specific user info paramters indexed by STA-ID
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
uint8_t GetTxPowerLevel(void) const
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
uint8_t GetNess(void) const
uint16_t GetLength(void) const
Get the LENGTH field of the L-SIG.
HeMuUserInfo GetHeMuUserInfo(uint16_t staId) const
Get the HE MU user-specific transmission information for the given STA-ID.
uint8_t m_nTx
number of TX antennas
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
WifiPreamble GetPreambleType(void) const
HeRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
HeMuUserInfoMap m_muUserInfos
HE MU specific per-user information indexed by station ID (STA-ID) corresponding to the 11 LSBs of th...
bool GetModeInitialized(void) const
uint8_t m_txPowerLevel
The TXPWR_LEVEL parameter in Table 15-4.
bool m_ldpc
LDPC FEC coding if true, BCC otherwise.
uint16_t m_guardInterval
guard interval duration in nanoseconds
bool m_stbc
STBC used or not.
uint8_t m_nss
number of spatial streams
void SetRu(HeRu::RuSpec ru, uint16_t staId)
Set the RU specification for the STA-ID.
bool IsValid(void) const
The standard disallows certain combinations of WifiMode, number of spatial streams,...
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
void SetLength(uint16_t length)
Set the LENGTH field of the L-SIG.
bool IsAggregation(void) const
Checks whether the PSDU contains A-MPDU.
const HeMuUserInfoMap & GetHeMuUserInfoMap(void) const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(void) const
Get the number of RUs per HE-SIG-B content channel.
uint16_t m_length
LENGTH field of the L-SIG.
uint8_t m_bssColor
BSS color.
bool IsMu(void) const
Return true if this TX vector is used for a multi-user transmission.
void SetBssColor(uint8_t color)
Set the BSS color.
void SetNTx(uint8_t nTx)
Sets the number of TX antennas.
uint16_t GetChannelWidth(void) const
bool IsLdpc(void) const
Check if LDPC FEC coding is used or not.
WifiPreamble m_preamble
preamble
bool IsStbc(void) const
Check if STBC is used or not.
bool m_modeInitialized
Internal initialization flag.
uint8_t m_ness
number of spatial streams in beamforming
uint16_t GetGuardInterval(void) const
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
uint8_t GetNssMax(void) const
void SetNss(uint8_t nss)
Sets the number of Nss.
bool IsUlMu(void) const
Return true if this TX vector is used for an uplink multi-user transmission.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
WifiModulationClass GetModulationClass(void) const
Get the modulation class specified by this TXVECTOR.
#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_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
@ WIFI_PREAMBLE_LONG
@ WIFI_PREAMBLE_HE_SU
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
bool IsMu(WifiPreamble preamble)
Return true if a preamble corresponds to a multi-user transmission.
bool IsDlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a downlink multi-user transmission.
bool IsUlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a uplink multi-user transmission.
HE MU specific user transmission parameters.
HeRu::RuSpec ru
RU specification.
uint8_t nss
number of spatial streams
bool operator!=(const HeMuUserInfo &other) const
Compare this user info to the given user info.
bool operator==(const HeMuUserInfo &other) const
Compare this user info to the given user info.
WifiMode mcs
MCS.
Declaration of the following enums: