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#include "ns3/eht-phy.h"
27
28#include <algorithm>
29#include <iterator>
30
31namespace ns3
32{
33
35 : m_txPowerLevel(1),
36 m_preamble(WIFI_PREAMBLE_LONG),
37 m_channelWidth(20),
38 m_guardInterval(800),
39 m_nTx(1),
40 m_nss(1),
41 m_ness(0),
42 m_aggregation(false),
43 m_stbc(false),
44 m_ldpc(false),
45 m_bssColor(0),
46 m_length(0),
47 m_triggerResponding(false),
48 m_modeInitialized(false),
49 m_inactiveSubchannels(),
50 m_ruAllocation(),
51 m_ehtPpduType(1) // SU transmission by default
52{
53}
54
56 uint8_t powerLevel,
57 WifiPreamble preamble,
58 uint16_t guardInterval,
59 uint8_t nTx,
60 uint8_t nss,
61 uint8_t ness,
62 uint16_t channelWidth,
63 bool aggregation,
64 bool stbc,
65 bool ldpc,
66 uint8_t bssColor,
67 uint16_t length,
68 bool triggerResponding)
69 : m_mode(mode),
70 m_txPowerLevel(powerLevel),
71 m_preamble(preamble),
72 m_channelWidth(channelWidth),
73 m_guardInterval(guardInterval),
74 m_nTx(nTx),
75 m_nss(nss),
76 m_ness(ness),
77 m_aggregation(aggregation),
78 m_stbc(stbc),
79 m_ldpc(ldpc),
80 m_bssColor(bssColor),
81 m_length(length),
82 m_triggerResponding(triggerResponding),
83 m_modeInitialized(true),
84 m_inactiveSubchannels(),
85 m_ruAllocation(),
86 m_ehtPpduType(1) // SU transmission by default
87{
88}
89
91 : m_mode(txVector.m_mode),
92 m_txPowerLevel(txVector.m_txPowerLevel),
93 m_preamble(txVector.m_preamble),
94 m_channelWidth(txVector.m_channelWidth),
95 m_guardInterval(txVector.m_guardInterval),
96 m_nTx(txVector.m_nTx),
97 m_nss(txVector.m_nss),
98 m_ness(txVector.m_ness),
99 m_aggregation(txVector.m_aggregation),
100 m_stbc(txVector.m_stbc),
101 m_ldpc(txVector.m_ldpc),
102 m_bssColor(txVector.m_bssColor),
103 m_length(txVector.m_length),
104 m_triggerResponding(txVector.m_triggerResponding),
105 m_modeInitialized(txVector.m_modeInitialized),
106 m_inactiveSubchannels(txVector.m_inactiveSubchannels),
107 m_sigBMcs(txVector.m_sigBMcs),
108 m_ruAllocation(txVector.m_ruAllocation),
109 m_ehtPpduType(txVector.m_ehtPpduType)
110{
111 m_muUserInfos.clear();
112 if (!txVector.m_muUserInfos.empty()) // avoids crashing for loop
113 {
114 for (auto& info : txVector.m_muUserInfos)
115 {
116 m_muUserInfos.insert(std::make_pair(info.first, info.second));
117 }
118 }
119}
120
122{
123 m_muUserInfos.clear();
124}
125
126bool
128{
129 return m_modeInitialized;
130}
131
133WifiTxVector::GetMode(uint16_t staId) const
134{
136 {
137 NS_FATAL_ERROR("WifiTxVector mode must be set before using");
138 }
139 if (!IsMu())
140 {
141 return m_mode;
142 }
143 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
144 const auto userInfoIt = m_muUserInfos.find(staId);
145 NS_ASSERT(userInfoIt != m_muUserInfos.cend());
147 {
149 return EhtPhy::GetEhtMcs(userInfoIt->second.mcs);
151 return HePhy::GetHeMcs(userInfoIt->second.mcs);
152 default:
153 NS_ABORT_MSG("Unsupported modulation class: " << GetModulationClassForPreamble(m_preamble));
154 }
155 return WifiMode(); // invalid WifiMode
156}
157
160{
161 NS_ABORT_MSG_IF(!m_modeInitialized, "WifiTxVector mode must be set before using");
162
163 if (IsMu())
164 {
165 NS_ASSERT(!m_muUserInfos.empty());
166 // all the modes belong to the same modulation class
168 }
169 return m_mode.GetModulationClass();
170}
171
172uint8_t
174{
175 return m_txPowerLevel;
176}
177
180{
181 return m_preamble;
182}
183
184uint16_t
186{
187 return m_channelWidth;
188}
189
190uint16_t
192{
193 return m_guardInterval;
194}
195
196uint8_t
198{
199 return m_nTx;
200}
201
202uint8_t
203WifiTxVector::GetNss(uint16_t staId) const
204{
205 if (IsMu())
206 {
207 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
208 NS_ASSERT(m_muUserInfos.find(staId) != m_muUserInfos.end());
209 return m_muUserInfos.at(staId).nss;
210 }
211 return m_nss;
212}
213
214uint8_t
216{
217 uint8_t nss = 0;
218 if (IsMu())
219 {
220 for (const auto& info : m_muUserInfos)
221 {
222 nss = (nss < info.second.nss) ? info.second.nss : nss;
223 }
224 }
225 else
226 {
227 nss = m_nss;
228 }
229 return nss;
230}
231
232uint8_t
234{
235 return m_ness;
236}
237
238bool
240{
241 return m_aggregation;
242}
243
244bool
246{
247 return m_stbc;
248}
249
250bool
252{
253 return m_ldpc;
254}
255
256bool
258{
259 return ((m_channelWidth >= 40) && !IsMu() &&
261}
262
263void
265{
266 m_mode = mode;
267 m_modeInitialized = true;
268}
269
270void
271WifiTxVector::SetMode(WifiMode mode, uint16_t staId)
272{
273 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
274 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
275 m_muUserInfos[staId].mcs = mode.GetMcsValue();
276 m_modeInitialized = true;
277}
278
279void
281{
282 m_txPowerLevel = powerlevel;
283}
284
285void
287{
288 m_preamble = preamble;
289}
290
291void
292WifiTxVector::SetChannelWidth(uint16_t channelWidth)
293{
294 m_channelWidth = channelWidth;
295}
296
297void
298WifiTxVector::SetGuardInterval(uint16_t guardInterval)
299{
300 m_guardInterval = guardInterval;
301}
302
303void
305{
306 m_nTx = nTx;
307}
308
309void
311{
312 m_nss = nss;
313}
314
315void
316WifiTxVector::SetNss(uint8_t nss, uint16_t staId)
317{
318 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
319 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
320 m_muUserInfos[staId].nss = nss;
321}
322
323void
325{
326 m_ness = ness;
327}
328
329void
331{
332 m_aggregation = aggregation;
333}
334
335void
337{
338 m_stbc = stbc;
339}
340
341void
343{
344 m_ldpc = ldpc;
345}
346
347void
349{
350 m_bssColor = color;
351}
352
353uint8_t
355{
356 return m_bssColor;
357}
358
359void
361{
362 m_length = length;
363}
364
365uint16_t
367{
368 return m_length;
369}
370
371bool
373{
374 return m_triggerResponding;
375}
376
377void
379{
380 m_triggerResponding = triggerResponding;
381}
382
383void
385{
386 m_sigBMcs = mode;
387}
388
391{
392 return m_sigBMcs;
393}
394
395void
397{
398 if (ns3::IsDlMu(m_preamble) && !m_muUserInfos.empty())
399 {
400 NS_ASSERT(ruAlloc == DeriveRuAllocation());
401 }
402 m_ruAllocation = ruAlloc;
403}
404
405const RuAllocation&
407{
408 if (ns3::IsDlMu(m_preamble) && m_ruAllocation.empty())
409 {
411 }
412 return m_ruAllocation;
413}
414
415void
417{
420}
421
422uint8_t
424{
425 return m_ehtPpduType;
426}
427
428bool
430{
431 if (!GetModeInitialized())
432 {
433 return false;
434 }
435 std::string modeName = m_mode.GetUniqueName();
436 if (m_channelWidth == 20)
437 {
438 if (m_nss != 3 && m_nss != 6)
439 {
440 return (modeName != "VhtMcs9");
441 }
442 }
443 else if (m_channelWidth == 80)
444 {
445 if (m_nss == 3 || m_nss == 7)
446 {
447 return (modeName != "VhtMcs6");
448 }
449 else if (m_nss == 6)
450 {
451 return (modeName != "VhtMcs9");
452 }
453 }
454 else if (m_channelWidth == 160)
455 {
456 if (m_nss == 3)
457 {
458 return (modeName != "VhtMcs9");
459 }
460 }
461 return true;
462}
463
464bool
466{
467 return IsDlMu() || IsUlMu();
468}
469
470bool
472{
473 return ns3::IsDlMu(m_preamble) && !(IsEht(m_preamble) && m_ehtPpduType == 1);
474}
475
476bool
478{
479 return ns3::IsUlMu(m_preamble);
480}
481
483WifiTxVector::GetRu(uint16_t staId) const
484{
485 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
486 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
487 return m_muUserInfos.at(staId).ru;
488}
489
490void
492{
493 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
494 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
495 m_muUserInfos[staId].ru = ru;
496}
497
499WifiTxVector::GetHeMuUserInfo(uint16_t staId) const
500{
501 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
502 return m_muUserInfos.at(staId);
503}
504
505void
507{
508 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
509 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
510 m_muUserInfos[staId] = userInfo;
511 m_modeInitialized = true;
512 m_ruAllocation.clear();
513}
514
517{
518 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
519 return m_muUserInfos;
520}
521
524{
525 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
526 m_ruAllocation.clear();
527 return m_muUserInfos;
528}
529
530std::pair<std::size_t, std::size_t>
532{
534 {
535 return {1, 0};
536 }
537
538 // MU-MIMO is not handled for now, i.e. one station per RU
539 auto ruAllocation = GetRuAllocation();
540 NS_ASSERT_MSG(!ruAllocation.empty(), "RU allocation is not set");
541 if (ruAllocation.size() != m_channelWidth / 20)
542 {
543 ruAllocation = DeriveRuAllocation();
544 }
545 NS_ASSERT_MSG(ruAllocation.size() == m_channelWidth / 20,
546 "RU allocation is not consistent with packet bandwidth");
547
548 std::pair<std::size_t /* number of RUs in content channel 1 */,
549 std::size_t /* number of RUs in content channel 2 */>
550 chSize{0, 0};
551
552 switch (GetChannelWidth())
553 {
554 case 40:
555 chSize.second += HeRu::GetRuSpecs(ruAllocation[1]).size();
556 [[fallthrough]];
557 case 20:
558 chSize.first += HeRu::GetRuSpecs(ruAllocation[0]).size();
559 break;
560 default:
561 for (auto n = 0; n < m_channelWidth / 20;)
562 {
563 chSize.first += HeRu::GetRuSpecs(ruAllocation[n]).size();
564 chSize.second += HeRu::GetRuSpecs(ruAllocation[n + 1]).size();
565 if (ruAllocation[n] >= 208)
566 {
567 // 996 tone RU occupies 80 MHz
568 n += 4;
569 continue;
570 }
571 n += 2;
572 }
573 break;
574 }
575 return chSize;
576}
577
578void
579WifiTxVector::SetInactiveSubchannels(const std::vector<bool>& inactiveSubchannels)
580{
582 "Only HE (or later) authorized for preamble puncturing");
584 m_channelWidth < 80,
585 "Preamble puncturing only possible for transmission bandwidth of 80 MHz or larger");
586 NS_ABORT_MSG_IF(!inactiveSubchannels.empty() &&
587 inactiveSubchannels.size() != (m_channelWidth / 20),
588 "The size of the inactive subchannnels bitmap should be equal to the number of "
589 "20 MHz subchannels");
590 m_inactiveSubchannels = inactiveSubchannels;
591}
592
593const std::vector<bool>&
595{
597}
598
599std::ostream&
600operator<<(std::ostream& os, const WifiTxVector& v)
601{
602 if (!v.IsValid())
603 {
604 os << "TXVECTOR not valid";
605 return os;
606 }
607 os << "txpwrlvl: " << +v.GetTxPowerLevel() << " preamble: " << v.GetPreambleType()
608 << " channel width: " << v.GetChannelWidth() << " GI: " << v.GetGuardInterval()
609 << " NTx: " << +v.GetNTx() << " Ness: " << +v.GetNess()
610 << " MPDU aggregation: " << v.IsAggregation() << " STBC: " << v.IsStbc()
611 << " FEC coding: " << (v.IsLdpc() ? "LDPC" : "BCC");
613 {
614 os << " BSS color: " << +v.GetBssColor();
615 }
616 if (v.IsUlMu())
617 {
618 os << " Length: " << v.GetLength();
619 }
621 {
622 os << " SIG-B mode: " << v.GetSigBMode();
623 }
624 if (v.IsMu())
625 {
627 os << " num User Infos: " << userInfoMap.size();
628 for (auto& ui : userInfoMap)
629 {
630 os << ", {STA-ID: " << ui.first << ", " << ui.second.ru << ", MCS: " << +ui.second.mcs
631 << ", Nss: " << +ui.second.nss << "}";
632 }
633 }
634 else
635 {
636 os << " mode: " << v.GetMode() << " Nss: " << +v.GetNss();
637 }
638 const auto& puncturedSubchannels = v.GetInactiveSubchannels();
639 if (!puncturedSubchannels.empty())
640 {
641 os << " Punctured subchannels: ";
642 std::copy(puncturedSubchannels.cbegin(),
643 puncturedSubchannels.cend(),
644 std::ostream_iterator<bool>(os, ", "));
645 }
646 if (IsEht(v.GetPreambleType()))
647 {
648 os << " EHT PPDU type: " << +v.GetEhtPpduType();
649 }
650 return os;
651}
652
653bool
655{
656 return ru == other.ru && mcs == other.mcs && nss == other.nss;
657}
658
659bool
661{
662 return !(*this == other);
663}
664
667{
668 ContentChannelAllocation channelAlloc{{}};
669
670 if (m_channelWidth > 20)
671 {
672 channelAlloc.emplace_back();
673 }
674
675 for (const auto& [staId, userInfo] : m_muUserInfos)
676 {
677 auto ruType = userInfo.ru.GetRuType();
678 auto ruIdx = userInfo.ru.GetIndex();
679
680 if ((ruType == HeRu::RU_484_TONE) || (ruType == HeRu::RU_996_TONE))
681 {
682 channelAlloc[0].push_back(staId);
683 channelAlloc[1].push_back(staId);
684 continue;
685 }
686
687 size_t numRus{1};
688 if (ruType < HeRu::RU_242_TONE)
689 {
690 numRus = HeRu::m_heRuSubcarrierGroups.at({20, ruType}).size();
691 }
692
693 if (((ruIdx - 1) / numRus) % 2 == 0)
694 {
695 channelAlloc[0].push_back(staId);
696 }
697 else
698 {
699 channelAlloc[1].push_back(staId);
700 }
701 }
702
703 return channelAlloc;
704}
705
708{
709 std::all_of(m_muUserInfos.cbegin(), m_muUserInfos.cend(), [&](const auto& userInfo) {
710 return userInfo.second.ru.GetRuType() == m_muUserInfos.cbegin()->second.ru.GetRuType();
711 });
713 std::vector<HeRu::RuType> ruTypes{};
714 ruTypes.resize(ruAllocations.size());
715 for (auto it = m_muUserInfos.begin(); it != m_muUserInfos.end(); ++it)
716 {
717 const auto ruType = it->second.ru.GetRuType();
718 const auto ruBw = HeRu::GetBandwidth(ruType);
719 const auto isPrimary80MHz = it->second.ru.GetPrimary80MHz();
720 const auto rusPerSubchannel = HeRu::GetRusOfType(ruBw > 20 ? ruBw : 20, ruType);
721 auto ruIndex = it->second.ru.GetIndex();
722 if ((m_channelWidth >= 80) && (ruIndex > 19))
723 {
724 // take into account the center 26-tone RU in the primary 80 MHz
725 ruIndex--;
726 }
727 if ((!isPrimary80MHz) && (ruIndex > 19))
728 {
729 // take into account the center 26-tone RU in the secondary 80 MHz
730 ruIndex--;
731 }
732 if (!isPrimary80MHz && (ruType != HeRu::RU_2x996_TONE))
733 {
735 // adjust RU index for the secondary 80 MHz: in that case index is restarting at 1,
736 // hence we need to add an offset corresponding to the number of RUs of the same type in
737 // the primary 80 MHz
738 ruIndex += HeRu::GetRusOfType(80, ruType).size();
739 }
740 const auto index =
741 (ruBw < 20) ? ((ruIndex - 1) / rusPerSubchannel.size()) : ((ruIndex - 1) * (ruBw / 20));
742 const auto numSubchannelsForRu = (ruBw < 20) ? 1 : (ruBw / 20);
743 NS_ABORT_IF(index >= (m_channelWidth / 20));
744 auto ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, false);
745 if (ruAllocations.at(index) != HeRu::EMPTY_242_TONE_RU)
746 {
747 if (ruType == ruTypes.at(index))
748 {
749 continue;
750 }
751 if (ruType == HeRu::RU_26_TONE)
752 {
753 ruAlloc = HeRu::GetEqualizedRuAllocation(ruTypes.at(index), true);
754 }
755 else if (ruTypes.at(index) == HeRu::RU_26_TONE)
756 {
757 ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, true);
758 }
759 else
760 {
761 NS_ASSERT_MSG(false, "unsupported RU combination");
762 }
763 }
764 for (auto i = 0; i < numSubchannelsForRu; ++i)
765 {
766 ruTypes.at(index + i) = ruType;
767 ruAllocations.at(index + i) = ruAlloc;
768 }
769 }
770 return ruAllocations;
771}
772
773} // namespace ns3
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
Definition: eht-phy.cc:226
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1559
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:374
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:744
static constexpr uint8_t EMPTY_242_TONE_RU
Empty 242-tone RU identifier.
Definition: he-ru.h:276
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:492
static const SubcarrierGroups m_heRuSubcarrierGroups
Subcarrier groups for all RUs (with indices being applicable to primary 80 MHz channel)
Definition: he-ru.h:256
static uint8_t GetEqualizedRuAllocation(RuType ruType, bool isOdd)
Get the RU_ALLOCATION value for equal size RUs.
Definition: he-ru.cc:402
@ 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 IsTriggerResponding() const
Return true if the Trigger Responding parameter is set to true, false otherwise.
bool m_aggregation
Flag whether the PSDU contains A-MPDU.
void SetEhtPpduType(uint8_t type)
Set the EHT_PPDU_TYPE parameter.
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 parameters indexed by STA-ID
uint8_t GetNTx() const
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
void SetTriggerResponding(bool triggerResponding)
Set the Trigger Responding parameter to the given value.
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
bool m_triggerResponding
The Trigger Responding parameter.
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
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.
uint8_t GetEhtPpduType() const
Get the EHT_PPDU_TYPE parameter.
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
void SetSigBMode(const WifiMode &mode)
Set the MCS used for SIG-B.
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.
uint8_t m_ehtPpduType
EHT_PPDU_TYPE per Table 36-1 IEEE 802.11be D2.3.
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
bool IsNonHtDuplicate() const
Checks whether this TXVECTOR corresponds to a non-HT duplicate.
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:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#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_EHT_MU
@ WIFI_PREAMBLE_HE_SU
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsEht(WifiPreamble preamble)
Return true if a preamble corresponds to an EHT transmission.
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.
WifiModulationClass GetModulationClassForPreamble(WifiPreamble preamble)
Return the modulation class corresponding to the given preamble type.
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.
uint8_t mcs
MCS index.
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.
Declaration of the following enums: