A Discrete-Event Network Simulator
API
wifi-tx-vector.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 CTTC
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: Nicola Baldo <nbaldo@cttc.es>
18 * Ghada Badawy <gbadawy@gmail.com>
19 */
20
21#include "wifi-tx-vector.h"
22
23#include "wifi-phy-common.h"
24
25#include "ns3/abort.h"
26
27#include <algorithm>
28#include <iterator>
29
30namespace ns3
31{
32
34 : m_preamble(WIFI_PREAMBLE_LONG),
35 m_channelWidth(20),
36 m_guardInterval(800),
37 m_nTx(1),
38 m_nss(1),
39 m_ness(0),
40 m_aggregation(false),
41 m_stbc(false),
42 m_ldpc(false),
43 m_bssColor(0),
44 m_length(0),
45 m_modeInitialized(false),
46 m_inactiveSubchannels(),
47 m_ruAllocation()
48{
49}
50
52 uint8_t powerLevel,
53 WifiPreamble preamble,
54 uint16_t guardInterval,
55 uint8_t nTx,
56 uint8_t nss,
57 uint8_t ness,
58 uint16_t channelWidth,
59 bool aggregation,
60 bool stbc,
61 bool ldpc,
62 uint8_t bssColor,
63 uint16_t length)
64 : m_mode(mode),
65 m_txPowerLevel(powerLevel),
66 m_preamble(preamble),
67 m_channelWidth(channelWidth),
68 m_guardInterval(guardInterval),
69 m_nTx(nTx),
70 m_nss(nss),
71 m_ness(ness),
72 m_aggregation(aggregation),
73 m_stbc(stbc),
74 m_ldpc(ldpc),
75 m_bssColor(bssColor),
76 m_length(length),
77 m_modeInitialized(true),
78 m_inactiveSubchannels(),
79 m_ruAllocation()
80{
81}
82
84 : m_mode(txVector.m_mode),
85 m_txPowerLevel(txVector.m_txPowerLevel),
86 m_preamble(txVector.m_preamble),
87 m_channelWidth(txVector.m_channelWidth),
88 m_guardInterval(txVector.m_guardInterval),
89 m_nTx(txVector.m_nTx),
90 m_nss(txVector.m_nss),
91 m_ness(txVector.m_ness),
92 m_aggregation(txVector.m_aggregation),
93 m_stbc(txVector.m_stbc),
94 m_ldpc(txVector.m_ldpc),
95 m_bssColor(txVector.m_bssColor),
96 m_length(txVector.m_length),
97 m_modeInitialized(txVector.m_modeInitialized),
98 m_inactiveSubchannels(txVector.m_inactiveSubchannels),
99 m_sigBMcs(txVector.m_sigBMcs),
100 m_ruAllocation(txVector.m_ruAllocation)
101{
102 m_muUserInfos.clear();
103 if (!txVector.m_muUserInfos.empty()) // avoids crashing for loop
104 {
105 for (auto& info : txVector.m_muUserInfos)
106 {
107 m_muUserInfos.insert(std::make_pair(info.first, info.second));
108 }
109 }
110}
111
113{
114 m_muUserInfos.clear();
115}
116
117bool
119{
120 return m_modeInitialized;
121}
122
124WifiTxVector::GetMode(uint16_t staId) const
125{
127 {
128 NS_FATAL_ERROR("WifiTxVector mode must be set before using");
129 }
130 if (IsMu())
131 {
132 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
133 NS_ASSERT(m_muUserInfos.find(staId) != m_muUserInfos.end());
134 return m_muUserInfos.at(staId).mcs;
135 }
136 return m_mode;
137}
138
141{
142 NS_ABORT_MSG_IF(!m_modeInitialized, "WifiTxVector mode must be set before using");
143
144 if (IsMu())
145 {
146 NS_ASSERT(!m_muUserInfos.empty());
147 // all the modes belong to the same modulation class
148 return m_muUserInfos.begin()->second.mcs.GetModulationClass();
149 }
150 return m_mode.GetModulationClass();
151}
152
153uint8_t
155{
156 return m_txPowerLevel;
157}
158
161{
162 return m_preamble;
163}
164
165uint16_t
167{
168 return m_channelWidth;
169}
170
171uint16_t
173{
174 return m_guardInterval;
175}
176
177uint8_t
179{
180 return m_nTx;
181}
182
183uint8_t
184WifiTxVector::GetNss(uint16_t staId) const
185{
186 if (IsMu())
187 {
188 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
189 NS_ASSERT(m_muUserInfos.find(staId) != m_muUserInfos.end());
190 return m_muUserInfos.at(staId).nss;
191 }
192 return m_nss;
193}
194
195uint8_t
197{
198 uint8_t nss = 0;
199 if (IsMu())
200 {
201 for (const auto& info : m_muUserInfos)
202 {
203 nss = (nss < info.second.nss) ? info.second.nss : nss;
204 }
205 }
206 else
207 {
208 nss = m_nss;
209 }
210 return nss;
211}
212
213uint8_t
215{
216 return m_ness;
217}
218
219bool
221{
222 return m_aggregation;
223}
224
225bool
227{
228 return m_stbc;
229}
230
231bool
233{
234 return m_ldpc;
235}
236
237void
239{
240 m_mode = mode;
241 m_modeInitialized = true;
242}
243
244void
245WifiTxVector::SetMode(WifiMode mode, uint16_t staId)
246{
247 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
248 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
249 m_muUserInfos[staId].mcs = mode;
250 m_modeInitialized = true;
251}
252
253void
255{
256 m_txPowerLevel = powerlevel;
257}
258
259void
261{
262 m_preamble = preamble;
263}
264
265void
266WifiTxVector::SetChannelWidth(uint16_t channelWidth)
267{
268 m_channelWidth = channelWidth;
269}
270
271void
272WifiTxVector::SetGuardInterval(uint16_t guardInterval)
273{
274 m_guardInterval = guardInterval;
275}
276
277void
279{
280 m_nTx = nTx;
281}
282
283void
285{
286 m_nss = nss;
287}
288
289void
290WifiTxVector::SetNss(uint8_t nss, uint16_t staId)
291{
292 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
293 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
294 m_muUserInfos[staId].nss = nss;
295}
296
297void
299{
300 m_ness = ness;
301}
302
303void
305{
306 m_aggregation = aggregation;
307}
308
309void
311{
312 m_stbc = stbc;
313}
314
315void
317{
318 m_ldpc = ldpc;
319}
320
321void
323{
324 m_bssColor = color;
325}
326
327uint8_t
329{
330 return m_bssColor;
331}
332
333void
335{
336 m_length = length;
337}
338
339uint16_t
341{
342 return m_length;
343}
344
345void
347{
348 m_sigBMcs = mode;
349}
350
353{
354 return m_sigBMcs;
355}
356
357void
359{
360 if (IsDlMu() && !m_muUserInfos.empty())
361 {
362 NS_ASSERT(ruAlloc == DeriveRuAllocation());
363 }
364 m_ruAllocation = ruAlloc;
365}
366
367const RuAllocation&
369{
370 if (IsDlMu() && m_ruAllocation.empty())
371 {
373 }
374 return m_ruAllocation;
375}
376
377bool
379{
380 if (!GetModeInitialized())
381 {
382 return false;
383 }
384 std::string modeName = m_mode.GetUniqueName();
385 if (m_channelWidth == 20)
386 {
387 if (m_nss != 3 && m_nss != 6)
388 {
389 return (modeName != "VhtMcs9");
390 }
391 }
392 else if (m_channelWidth == 80)
393 {
394 if (m_nss == 3 || m_nss == 7)
395 {
396 return (modeName != "VhtMcs6");
397 }
398 else if (m_nss == 6)
399 {
400 return (modeName != "VhtMcs9");
401 }
402 }
403 else if (m_channelWidth == 160)
404 {
405 if (m_nss == 3)
406 {
407 return (modeName != "VhtMcs9");
408 }
409 }
410 return true;
411}
412
413bool
415{
416 return ns3::IsMu(m_preamble);
417}
418
419bool
421{
422 return ns3::IsDlMu(m_preamble);
423}
424
425bool
427{
428 return ns3::IsUlMu(m_preamble);
429}
430
432WifiTxVector::GetRu(uint16_t staId) const
433{
434 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
435 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
436 return m_muUserInfos.at(staId).ru;
437}
438
439void
441{
442 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
443 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
444 m_muUserInfos[staId].ru = ru;
445}
446
448WifiTxVector::GetHeMuUserInfo(uint16_t staId) const
449{
450 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
451 return m_muUserInfos.at(staId);
452}
453
454void
456{
457 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
458 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
460 "Only HE (or newer) modes authorized for MU");
461 m_muUserInfos[staId] = userInfo;
462 m_modeInitialized = true;
463 m_ruAllocation.clear();
464}
465
468{
469 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
470 return m_muUserInfos;
471}
472
475{
476 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
477 m_ruAllocation.clear();
478 return m_muUserInfos;
479}
480
481std::pair<std::size_t, std::size_t>
483{
484 // MU-MIMO is not handled for now, i.e. one station per RU
485 auto ruAllocation = GetRuAllocation();
486 NS_ASSERT_MSG(!ruAllocation.empty(), "RU allocation is not set");
487 if (ruAllocation.size() != m_channelWidth / 20)
488 {
489 ruAllocation = DeriveRuAllocation();
490 }
491 NS_ASSERT_MSG(ruAllocation.size() == m_channelWidth / 20,
492 "RU allocation is not consistent with packet bandwidth");
493
494 std::pair<std::size_t /* number of RUs in content channel 1 */,
495 std::size_t /* number of RUs in content channel 2 */>
496 chSize{0, 0};
497
498 switch (GetChannelWidth())
499 {
500 case 40:
501 chSize.second += HeRu::GetRuSpecs(ruAllocation[1]).size();
502 [[fallthrough]];
503 case 20:
504 chSize.first += HeRu::GetRuSpecs(ruAllocation[0]).size();
505 break;
506 default:
507 for (auto n = 0; n < m_channelWidth / 20;)
508 {
509 chSize.first += HeRu::GetRuSpecs(ruAllocation[n]).size();
510 chSize.second += HeRu::GetRuSpecs(ruAllocation[n + 1]).size();
511 if (ruAllocation[n] >= 208)
512 {
513 // 996 tone RU occupies 80 MHz
514 n += 4;
515 continue;
516 }
517 n += 2;
518 }
519 break;
520 }
521 return chSize;
522}
523
524void
525WifiTxVector::SetInactiveSubchannels(const std::vector<bool>& inactiveSubchannels)
526{
528 "Only HE (or later) authorized for preamble puncturing");
530 m_channelWidth < 80,
531 "Preamble puncturing only possible for transmission bandwidth of 80 MHz or larger");
532 NS_ABORT_MSG_IF(!inactiveSubchannels.empty() &&
533 inactiveSubchannels.size() != (m_channelWidth / 20),
534 "The size of the inactive subchannnels bitmap should be equal to the number of "
535 "20 MHz subchannels");
536 m_inactiveSubchannels = inactiveSubchannels;
537}
538
539const std::vector<bool>&
541{
543}
544
545std::ostream&
546operator<<(std::ostream& os, const WifiTxVector& v)
547{
548 if (!v.IsValid())
549 {
550 os << "TXVECTOR not valid";
551 return os;
552 }
553 os << "txpwrlvl: " << +v.GetTxPowerLevel() << " preamble: " << v.GetPreambleType()
554 << " channel width: " << v.GetChannelWidth() << " GI: " << v.GetGuardInterval()
555 << " NTx: " << +v.GetNTx() << " Ness: " << +v.GetNess()
556 << " MPDU aggregation: " << v.IsAggregation() << " STBC: " << v.IsStbc()
557 << " FEC coding: " << (v.IsLdpc() ? "LDPC" : "BCC");
559 {
560 os << " BSS color: " << +v.GetBssColor();
561 }
562 if (v.IsUlMu())
563 {
564 os << " Length: " << v.GetLength();
565 }
566 if (v.IsMu())
567 {
569 os << " num User Infos: " << userInfoMap.size();
570 for (auto& ui : userInfoMap)
571 {
572 os << ", {STA-ID: " << ui.first << ", " << ui.second.ru << ", MCS: " << ui.second.mcs
573 << ", Nss: " << +ui.second.nss << "}";
574 }
575 }
576 else
577 {
578 os << " mode: " << v.GetMode() << " Nss: " << +v.GetNss();
579 }
580 const auto& puncturedSubchannels = v.GetInactiveSubchannels();
581 if (!puncturedSubchannels.empty())
582 {
583 os << " Punctured subchannels: ";
584 std::copy(puncturedSubchannels.cbegin(),
585 puncturedSubchannels.cend(),
586 std::ostream_iterator<bool>(os, ", "));
587 }
588 return os;
589}
590
591bool
593{
594 return ru == other.ru && mcs.GetMcsValue() == other.mcs.GetMcsValue() && nss == other.nss;
595}
596
597bool
599{
600 return !(*this == other);
601}
602
605{
606 ContentChannelAllocation channelAlloc{{}};
607
608 if (m_channelWidth > 20)
609 {
610 channelAlloc.emplace_back();
611 }
612
613 for (const auto& [staId, userInfo] : m_muUserInfos)
614 {
615 auto ruType = userInfo.ru.GetRuType();
616 auto ruIdx = userInfo.ru.GetIndex();
617
618 if ((ruType == HeRu::RU_484_TONE) || (ruType == HeRu::RU_996_TONE))
619 {
620 channelAlloc[0].push_back(staId);
621 channelAlloc[1].push_back(staId);
622 continue;
623 }
624
625 size_t numRus{1};
626 if (ruType < HeRu::RU_242_TONE)
627 {
628 numRus = HeRu::m_heRuSubcarrierGroups.at({20, ruType}).size();
629 }
630
631 if (((ruIdx - 1) / numRus) % 2 == 0)
632 {
633 channelAlloc[0].push_back(staId);
634 }
635 else
636 {
637 channelAlloc[1].push_back(staId);
638 }
639 }
640
641 return channelAlloc;
642}
643
646{
647 std::all_of(m_muUserInfos.cbegin(), m_muUserInfos.cend(), [&](const auto& userInfo) {
648 return userInfo.second.ru.GetRuType() == m_muUserInfos.cbegin()->second.ru.GetRuType();
649 });
651 std::vector<HeRu::RuType> ruTypes{};
652 ruTypes.resize(ruAllocations.size());
653 for (auto it = m_muUserInfos.begin(); it != m_muUserInfos.end(); ++it)
654 {
655 const auto ruType = it->second.ru.GetRuType();
656 const auto ruBw = HeRu::GetBandwidth(ruType);
657 const auto isPrimary80MHz = it->second.ru.GetPrimary80MHz();
658 const auto rusPerSubchannel = HeRu::GetRusOfType(ruBw > 20 ? ruBw : 20, ruType);
659 auto ruIndex = it->second.ru.GetIndex();
660 if ((m_channelWidth >= 80) && (ruIndex > 19))
661 {
662 // take into account the center 26-tone RU in the primary 80 MHz
663 ruIndex--;
664 }
665 if ((!isPrimary80MHz) && (ruIndex > 19))
666 {
667 // take into account the center 26-tone RU in the secondary 80 MHz
668 ruIndex--;
669 }
670 if (!isPrimary80MHz && (ruType != HeRu::RU_2x996_TONE))
671 {
673 // adjust RU index for the secondary 80 MHz: in that case index is restarting at 1,
674 // hence we need to add an offset corresponding to the number of RUs of the same type in
675 // the primary 80 MHz
676 ruIndex += HeRu::GetRusOfType(80, ruType).size();
677 }
678 const auto index =
679 (ruBw < 20) ? ((ruIndex - 1) / rusPerSubchannel.size()) : ((ruIndex - 1) * (ruBw / 20));
680 const auto numSubchannelsForRu = (ruBw < 20) ? 1 : (ruBw / 20);
681 NS_ABORT_IF(index >= (m_channelWidth / 20));
682 auto ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, false);
683 if (ruAllocations.at(index) != HeRu::EMPTY_242_TONE_RU)
684 {
685 if (ruType == ruTypes.at(index))
686 {
687 continue;
688 }
689 if (ruType == HeRu::RU_26_TONE)
690 {
691 ruAlloc = HeRu::GetEqualizedRuAllocation(ruTypes.at(index), true);
692 }
693 else if (ruTypes.at(index) == HeRu::RU_26_TONE)
694 {
695 ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, true);
696 }
697 else
698 {
699 NS_ASSERT_MSG(false, "unsupported RU combination");
700 }
701 }
702 for (auto i = 0; i < numSubchannelsForRu; ++i)
703 {
704 ruTypes.at(index + i) = ruType;
705 ruAllocations.at(index + i) = ruAlloc;
706 }
707 }
708 return ruAllocations;
709}
710
711} // namespace ns3
RU Specification.
Definition: he-ru.h:66
static std::vector< RuSpec > GetRuSpecs(uint8_t ruAllocation)
Get the RU specs based on RU_ALLOCATION.
Definition: he-ru.cc:373
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:760
static constexpr uint8_t EMPTY_242_TONE_RU
Empty 242-tone RU identifier.
Definition: he-ru.h:287
static std::vector< HeRu::RuSpec > GetRusOfType(uint16_t bw, HeRu::RuType ruType)
Get the set of distinct RUs of the given type (number of tones) available in a HE PPDU of the given b...
Definition: he-ru.cc:505
static const SubcarrierGroups m_heRuSubcarrierGroups
Subcarrier groups for all RUs (with indices being applicable to primary 80 MHz channel)
Definition: he-ru.h:267
static uint8_t GetEqualizedRuAllocation(RuType ruType, bool isOdd)
Get the RU_ALLOCATION value for equal size RUs.
Definition: he-ru.cc:401
@ RU_26_TONE
Definition: he-ru.h:42
@ RU_484_TONE
Definition: he-ru.h:46
@ RU_996_TONE
Definition: he-ru.h:47
@ RU_242_TONE
Definition: he-ru.h:45
@ RU_2x996_TONE
Definition: he-ru.h:48
represent a single transmission mode
Definition: wifi-mode.h:50
std::string GetUniqueName() const
Definition: wifi-mode.cc:148
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
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...
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 m_aggregation
Flag whether the PSDU contains A-MPDU.
const RuAllocation & GetRuAllocation() const
Get RU Allocation of SIG-B.
uint16_t GetGuardInterval() const
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
bool IsValid() const
The standard disallows certain combinations of WifiMode, number of spatial streams,...
void SetLdpc(bool ldpc)
Sets if LDPC FEC coding is being used.
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
uint8_t GetBssColor() const
Get the BSS color.
bool GetModeInitialized() const
std::vector< bool > m_inactiveSubchannels
Bitmap of inactive subchannels used for preamble puncturing.
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
uint8_t GetNTx() const
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.
RuAllocation m_ruAllocation
RU allocations that are going to be carried in SIG-B common field per Table 27-1 IEEE.
void SetInactiveSubchannels(const std::vector< bool > &inactiveSubchannels)
Set the 20 MHz subchannels that are punctured.
bool IsStbc() const
Check if STBC is used or not.
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
WifiPreamble GetPreambleType() const
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.
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...
uint8_t m_txPowerLevel
The TXPWR_LEVEL parameter in Table 15-4.
bool m_ldpc
LDPC FEC coding if true, BCC otherwise.
uint16_t GetLength() const
Get the LENGTH field of the L-SIG.
uint16_t m_guardInterval
guard interval duration in nanoseconds
bool IsDlMu() const
Return true if this TX vector is used for a downlink multi-user transmission.
bool m_stbc
STBC used or not.
uint8_t m_nss
number of spatial streams
void SetRuAllocation(const RuAllocation &ruAlloc)
Set RU Allocation of SIG-B common field.
const HeMuUserInfoMap & GetHeMuUserInfoMap() const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
void SetRu(HeRu::RuSpec ru, uint16_t staId)
Set the RU specification for the STA-ID.
RuAllocation DeriveRuAllocation() const
Derive the RU allocation from the TXVECTOR for which its RU allocation has not been set yet.
ContentChannelAllocation GetContentChannelAllocation() const
Get the HE SIG-B content channel STA ID allocation IEEE 802.11ax-2021 27.3.11.8.2 HE-SIG-B content ch...
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
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.
uint8_t GetNssMax() const
bool IsUlMu() const
Return true if this TX vector is used for an uplink multi-user transmission.
void SetSigBMode(const WifiMode &mode)
Set the MCS used for SIG-B.
bool IsMu() const
Return true if this TX vector is used for a multi-user transmission.
uint16_t m_length
LENGTH field of the L-SIG.
uint8_t m_bssColor
BSS color.
std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel() const
Get the number of RUs per HE-SIG-B content channel.
WifiMode m_sigBMcs
MCS_SIG_B per Table 27-1 IEEE 802.11ax-2021.
void SetBssColor(uint8_t color)
Set the BSS color.
bool IsLdpc() const
Check if LDPC FEC coding is used or not.
void SetNTx(uint8_t nTx)
Sets the number of TX antennas.
uint8_t GetTxPowerLevel() const
bool IsAggregation() const
Checks whether the PSDU contains A-MPDU.
uint16_t GetChannelWidth() const
WifiPreamble m_preamble
preamble
bool m_modeInitialized
Internal initialization flag.
uint8_t GetNess() const
uint8_t m_ness
number of spatial streams in beamforming
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
WifiMode GetSigBMode() const
Get MCS used for SIG-B.
void SetNss(uint8_t nss)
Sets the number of Nss.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
const std::vector< bool > & GetInactiveSubchannels() const
Get the 20 MHz subchannels that are punctured.
#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 NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
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:129
std::vector< std::vector< uint16_t > > ContentChannelAllocation
HE SIG-B Content Channels STA ID Allocation.
bool IsMu(WifiPreamble preamble)
Return true if a preamble corresponds to a multi-user transmission.
std::vector< uint8_t > RuAllocation
8 bit RU_ALLOCATION per 20 MHz
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: