A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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#include <numeric>
31#include <set>
32
33namespace ns3
34{
35
37 : m_txPowerLevel(1),
38 m_preamble(WIFI_PREAMBLE_LONG),
39 m_channelWidth(20),
40 m_guardInterval(800),
41 m_nTx(1),
42 m_nss(1),
43 m_ness(0),
44 m_aggregation(false),
45 m_stbc(false),
46 m_ldpc(false),
47 m_bssColor(0),
48 m_length(0),
49 m_triggerResponding(false),
50 m_modeInitialized(false),
51 m_inactiveSubchannels(),
52 m_ruAllocation(),
53 m_center26ToneRuIndication(std::nullopt),
54 m_ehtPpduType(1) // SU transmission by default
55{
56}
57
59 uint8_t powerLevel,
60 WifiPreamble preamble,
61 uint16_t guardInterval,
62 uint8_t nTx,
63 uint8_t nss,
64 uint8_t ness,
65 uint16_t channelWidth,
66 bool aggregation,
67 bool stbc,
68 bool ldpc,
69 uint8_t bssColor,
70 uint16_t length,
71 bool triggerResponding)
72 : m_mode(mode),
73 m_txPowerLevel(powerLevel),
74 m_preamble(preamble),
75 m_channelWidth(channelWidth),
76 m_guardInterval(guardInterval),
77 m_nTx(nTx),
78 m_nss(nss),
79 m_ness(ness),
80 m_aggregation(aggregation),
81 m_stbc(stbc),
82 m_ldpc(ldpc),
83 m_bssColor(bssColor),
84 m_length(length),
85 m_triggerResponding(triggerResponding),
86 m_modeInitialized(true),
87 m_inactiveSubchannels(),
88 m_ruAllocation(),
89 m_center26ToneRuIndication(std::nullopt),
90 m_ehtPpduType(1) // SU transmission by default
91{
92}
93
95 : m_mode(txVector.m_mode),
96 m_txPowerLevel(txVector.m_txPowerLevel),
97 m_preamble(txVector.m_preamble),
98 m_channelWidth(txVector.m_channelWidth),
99 m_guardInterval(txVector.m_guardInterval),
100 m_nTx(txVector.m_nTx),
101 m_nss(txVector.m_nss),
102 m_ness(txVector.m_ness),
103 m_aggregation(txVector.m_aggregation),
104 m_stbc(txVector.m_stbc),
105 m_ldpc(txVector.m_ldpc),
106 m_bssColor(txVector.m_bssColor),
107 m_length(txVector.m_length),
108 m_triggerResponding(txVector.m_triggerResponding),
109 m_modeInitialized(txVector.m_modeInitialized),
110 m_inactiveSubchannels(txVector.m_inactiveSubchannels),
111 m_sigBMcs(txVector.m_sigBMcs),
112 m_ruAllocation(txVector.m_ruAllocation),
113 m_center26ToneRuIndication(txVector.m_center26ToneRuIndication),
114 m_ehtPpduType(txVector.m_ehtPpduType)
115{
116 m_muUserInfos.clear();
117 if (!txVector.m_muUserInfos.empty()) // avoids crashing for loop
118 {
119 for (auto& info : txVector.m_muUserInfos)
120 {
121 m_muUserInfos.insert(std::make_pair(info.first, info.second));
122 }
123 }
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.contains(staId));
209 return m_muUserInfos.at(staId).nss;
210 }
211 return m_nss;
212}
213
214uint8_t
216{
217 // We do not support mixed OFDMA and MU-MIMO
218 uint8_t nss = 0;
219 if (IsMu())
220 {
221 for (const auto& info : m_muUserInfos)
222 {
223 nss = (nss < info.second.nss) ? info.second.nss : nss;
224 }
225 }
226 else
227 {
228 nss = m_nss;
229 }
230 return nss;
231}
232
233uint8_t
235{
236 // We do not support mixed OFDMA and MU-MIMO
237 uint8_t nss = 0;
238 if (IsMu())
239 {
240 nss = std::accumulate(
241 m_muUserInfos.cbegin(),
242 m_muUserInfos.cend(),
243 0,
244 [](uint8_t prevNss, const auto& info) { return prevNss + info.second.nss; });
245 }
246 else
247 {
248 nss = m_nss;
249 }
250 return nss;
251}
252
253uint8_t
255{
256 return m_ness;
257}
258
259bool
261{
262 return m_aggregation;
263}
264
265bool
267{
268 return m_stbc;
269}
270
271bool
273{
274 return m_ldpc;
275}
276
277bool
279{
280 return ((m_channelWidth >= 40) && !IsMu() && (GetModulationClass() < WIFI_MOD_CLASS_HT));
281}
282
283void
285{
286 m_mode = mode;
287 m_modeInitialized = true;
288}
289
290void
291WifiTxVector::SetMode(WifiMode mode, uint16_t staId)
292{
293 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
294 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
295 m_muUserInfos[staId].mcs = mode.GetMcsValue();
296 m_modeInitialized = true;
297}
298
299void
301{
302 m_txPowerLevel = powerlevel;
303}
304
305void
307{
308 m_preamble = preamble;
309}
310
311void
312WifiTxVector::SetChannelWidth(uint16_t channelWidth)
313{
314 m_channelWidth = channelWidth;
315}
316
317void
318WifiTxVector::SetGuardInterval(uint16_t guardInterval)
319{
320 m_guardInterval = guardInterval;
321}
322
323void
325{
326 m_nTx = nTx;
327}
328
329void
331{
332 m_nss = nss;
333}
334
335void
336WifiTxVector::SetNss(uint8_t nss, uint16_t staId)
337{
338 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
339 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
340 m_muUserInfos[staId].nss = nss;
341}
342
343void
345{
346 m_ness = ness;
347}
348
349void
351{
352 m_aggregation = aggregation;
353}
354
355void
357{
358 m_stbc = stbc;
359}
360
361void
363{
364 m_ldpc = ldpc;
365}
366
367void
369{
370 m_bssColor = color;
371}
372
373uint8_t
375{
376 return m_bssColor;
377}
378
379void
381{
382 m_length = length;
383}
384
385uint16_t
387{
388 return m_length;
389}
390
391bool
393{
394 return m_triggerResponding;
395}
396
397void
399{
400 m_triggerResponding = triggerResponding;
401}
402
403void
405{
406 m_sigBMcs = mode;
407}
408
411{
412 return m_sigBMcs;
413}
414
415void
416WifiTxVector::SetRuAllocation(const RuAllocation& ruAlloc, uint8_t p20Index)
417{
418 if (ns3::IsDlMu(m_preamble) && !m_muUserInfos.empty())
419 {
420 NS_ASSERT(ruAlloc == DeriveRuAllocation(p20Index));
421 }
422 m_ruAllocation = ruAlloc;
423}
424
425const RuAllocation&
426WifiTxVector::GetRuAllocation(uint8_t p20Index) const
427{
428 if (ns3::IsDlMu(m_preamble) && m_ruAllocation.empty())
429 {
431 }
432 return m_ruAllocation;
433}
434
435void
437{
439 m_ehtPpduType = type;
440}
441
442uint8_t
444{
445 return m_ehtPpduType;
446}
447
448bool
450{
451 if (!GetModeInitialized())
452 {
453 return false;
454 }
455 std::string modeName = m_mode.GetUniqueName();
456 if (m_channelWidth == 20)
457 {
458 if (m_nss != 3 && m_nss != 6)
459 {
460 if (modeName == "VhtMcs9")
461 {
462 return false;
463 }
464 }
465 }
466 else if (m_channelWidth == 80)
467 {
468 if (m_nss == 3 || m_nss == 7)
469 {
470 if (modeName == "VhtMcs6")
471 {
472 return false;
473 }
474 }
475 else if (m_nss == 6)
476 {
477 if (modeName == "VhtMcs9")
478 {
479 return false;
480 }
481 }
482 }
483 else if (m_channelWidth == 160)
484 {
485 if (m_nss == 3)
486 {
487 if (modeName == "VhtMcs9")
488 {
489 return false;
490 }
491 }
492 }
493 for (const auto& userInfo : m_muUserInfos)
494 {
495 if (GetNumStasInRu(userInfo.second.ru) > 8)
496 {
497 return false;
498 }
499 }
500 std::map<HeRu::RuSpec, uint8_t> streamsPerRu{};
501 for (const auto& info : m_muUserInfos)
502 {
503 auto it = streamsPerRu.find(info.second.ru);
504 if (it == streamsPerRu.end())
505 {
506 streamsPerRu[info.second.ru] = info.second.nss;
507 }
508 else
509 {
510 it->second += info.second.nss;
511 }
512 }
513 for (auto& streams : streamsPerRu)
514 {
515 if (streams.second > 8)
516 {
517 return false;
518 }
519 }
520
521 if (band != WIFI_PHY_BAND_UNSPECIFIED)
522 {
524 "Cannot use OFDM modulation class in the 2.4 GHz band");
526 band != WIFI_PHY_BAND_2_4GHZ,
527 "ERP-OFDM modulation class can only be used in the 2.4 GHz band");
528 }
529
530 return true;
531}
532
533bool
535{
536 return IsDlMu() || IsUlMu();
537}
538
539bool
541{
542 return ns3::IsDlMu(m_preamble) && !(IsEht(m_preamble) && m_ehtPpduType == 1);
543}
544
545bool
547{
548 return ns3::IsUlMu(m_preamble);
549}
550
551bool
553{
554 if (!IsDlMu())
555 {
556 return false;
557 }
558 if (IsEht(m_preamble))
559 {
560 return m_ehtPpduType == 0;
561 }
562 if (m_muUserInfos.size() == 1)
563 {
564 return true;
565 }
566 std::set<HeRu::RuSpec> rus{};
567 for (const auto& userInfo : m_muUserInfos)
568 {
569 rus.insert(userInfo.second.ru);
570 if (rus.size() > 1)
571 {
572 return true;
573 }
574 }
575 return false;
576}
577
578bool
580{
581 if (!IsDlMu())
582 {
583 return false;
584 }
585 if (IsEht(m_preamble))
586 {
587 return m_ehtPpduType == 2;
588 }
589 if (m_muUserInfos.size() < 2)
590 {
591 return false;
592 }
593 // TODO: mixed OFDMA and MU-MIMO is not supported
594 return !IsDlOfdma();
595}
596
597uint8_t
599{
600 return std::count_if(m_muUserInfos.cbegin(),
601 m_muUserInfos.cend(),
602 [&ru](const auto& info) -> bool { return (ru == info.second.ru); });
603}
604
605bool
606WifiTxVector::IsAllocated(uint16_t staId) const
607{
608 return m_muUserInfos.contains(staId);
609}
610
612WifiTxVector::GetRu(uint16_t staId) const
613{
614 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
615 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
616 return m_muUserInfos.at(staId).ru;
617}
618
619void
621{
622 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
623 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
624 m_muUserInfos[staId].ru = ru;
625}
626
628WifiTxVector::GetHeMuUserInfo(uint16_t staId) const
629{
630 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
631 return m_muUserInfos.at(staId);
632}
633
634void
636{
637 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
638 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
639 m_muUserInfos[staId] = userInfo;
640 m_modeInitialized = true;
641 m_ruAllocation.clear();
642}
643
646{
647 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
648 return m_muUserInfos;
649}
650
653{
654 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
655 m_ruAllocation.clear();
656 return m_muUserInfos;
657}
658
659bool
661{
662 return IsDlMuMimo() && !IsDlOfdma();
663}
664
665void
666WifiTxVector::SetInactiveSubchannels(const std::vector<bool>& inactiveSubchannels)
667{
669 "Only HE (or later) authorized for preamble puncturing");
671 m_channelWidth < 80,
672 "Preamble puncturing only possible for transmission bandwidth of 80 MHz or larger");
673 NS_ABORT_MSG_IF(!inactiveSubchannels.empty() &&
674 inactiveSubchannels.size() != (m_channelWidth / 20),
675 "The size of the inactive subchannnels bitmap should be equal to the number of "
676 "20 MHz subchannels");
677 m_inactiveSubchannels = inactiveSubchannels;
678}
679
680const std::vector<bool>&
682{
684}
685
686void
688{
689 if (IsDlMu())
690 {
691 NS_ASSERT(center26ToneRuIndication == DeriveCenter26ToneRuIndication());
692 }
693 m_center26ToneRuIndication = center26ToneRuIndication;
694}
695
696std::optional<Center26ToneRuIndication>
698{
699 if (!IsDlMu() || (m_channelWidth < 80))
700 {
701 return std::nullopt;
702 }
703 if (!m_center26ToneRuIndication.has_value())
704 {
706 }
708}
709
710std::ostream&
711operator<<(std::ostream& os, const WifiTxVector& v)
712{
713 if (!v.IsValid())
714 {
715 os << "TXVECTOR not valid";
716 return os;
717 }
718 os << "txpwrlvl: " << +v.GetTxPowerLevel() << " preamble: " << v.GetPreambleType()
719 << " channel width: " << v.GetChannelWidth() << " GI: " << v.GetGuardInterval()
720 << " NTx: " << +v.GetNTx() << " Ness: " << +v.GetNess()
721 << " MPDU aggregation: " << v.IsAggregation() << " STBC: " << v.IsStbc()
722 << " FEC coding: " << (v.IsLdpc() ? "LDPC" : "BCC");
724 {
725 os << " BSS color: " << +v.GetBssColor();
726 }
727 if (v.IsUlMu())
728 {
729 os << " Length: " << v.GetLength();
730 }
732 {
733 os << " SIG-B mode: " << v.GetSigBMode();
734 }
735 if (v.IsMu())
736 {
738 os << " num User Infos: " << userInfoMap.size();
739 for (auto& ui : userInfoMap)
740 {
741 os << ", {STA-ID: " << ui.first << ", " << ui.second.ru << ", MCS: " << +ui.second.mcs
742 << ", Nss: " << +ui.second.nss << "}";
743 }
744 }
745 else
746 {
747 os << " mode: " << v.GetMode() << " Nss: " << +v.GetNss();
748 }
749 const auto& puncturedSubchannels = v.GetInactiveSubchannels();
750 if (!puncturedSubchannels.empty())
751 {
752 os << " Punctured subchannels: ";
753 std::copy(puncturedSubchannels.cbegin(),
754 puncturedSubchannels.cend(),
755 std::ostream_iterator<bool>(os, ", "));
756 }
757 if (IsEht(v.GetPreambleType()))
758 {
759 os << " EHT PPDU type: " << +v.GetEhtPpduType();
760 }
761 return os;
762}
763
764bool
766{
767 return ru == other.ru && mcs == other.mcs && nss == other.nss;
768}
769
770bool
772{
773 return !(*this == other);
774}
775
778{
779 auto heRuComparator = HeRu::RuSpecCompare(m_channelWidth, p20Index);
780 UserInfoMapOrderedByRus orderedMap{heRuComparator};
781 for (const auto& userInfo : m_muUserInfos)
782 {
783 const auto ru = userInfo.second.ru;
784 if (auto it = orderedMap.find(ru); it != orderedMap.end())
785 {
786 it->second.emplace(userInfo.first);
787 }
788 else
789 {
790 orderedMap.emplace(userInfo.second.ru, std::set<uint16_t>{userInfo.first});
791 }
792 }
793 return orderedMap;
794}
795
797WifiTxVector::DeriveRuAllocation(uint8_t p20Index) const
798{
800 std::vector<HeRu::RuType> ruTypes{};
801 ruTypes.resize(ruAllocations.size());
802 const auto& orderedMap = GetUserInfoMapOrderedByRus(p20Index);
803 for (const auto& [ru, staIds] : orderedMap)
804 {
805 const auto ruType = ru.GetRuType();
806 const auto ruBw = HeRu::GetBandwidth(ruType);
807 const auto isPrimary80MHz = ru.GetPrimary80MHz();
808 const auto rusPerSubchannel = HeRu::GetRusOfType(ruBw > 20 ? ruBw : 20, ruType);
809 auto ruIndex = ru.GetIndex();
810 if ((m_channelWidth >= 80) && (ruIndex > 19))
811 {
812 // take into account the center 26-tone RU in the primary 80 MHz
813 ruIndex--;
814 }
815 if ((!isPrimary80MHz) && (ruIndex > 19))
816 {
817 // take into account the center 26-tone RU in the secondary 80 MHz
818 ruIndex--;
819 }
820 if (!isPrimary80MHz && (ruType != HeRu::RU_2x996_TONE))
821 {
823 // adjust RU index for the secondary 80 MHz: in that case index is restarting at 1,
824 // hence we need to add an offset corresponding to the number of RUs of the same type in
825 // the primary 80 MHz
826 ruIndex += HeRu::GetRusOfType(80, ruType).size();
827 }
828 const auto index =
829 (ruBw < 20) ? ((ruIndex - 1) / rusPerSubchannel.size()) : ((ruIndex - 1) * (ruBw / 20));
830 const auto numSubchannelsForRu = (ruBw < 20) ? 1 : (ruBw / 20);
831 NS_ABORT_IF(index >= (m_channelWidth / 20));
832 auto ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, false);
833 if (ruAllocations.at(index) != HeRu::EMPTY_242_TONE_RU)
834 {
835 if (ruType == ruTypes.at(index))
836 {
837 continue;
838 }
839 if (ruType == HeRu::RU_26_TONE)
840 {
841 ruAlloc = HeRu::GetEqualizedRuAllocation(ruTypes.at(index), true);
842 }
843 else if (ruTypes.at(index) == HeRu::RU_26_TONE)
844 {
845 ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, true);
846 }
847 else
848 {
849 NS_ASSERT_MSG(false, "unsupported RU combination");
850 }
851 }
852 for (auto i = 0; i < numSubchannelsForRu; ++i)
853 {
854 ruTypes.at(index + i) = ruType;
855 ruAllocations.at(index + i) = ruAlloc;
856 }
857 }
858 return ruAllocations;
859}
860
863{
864 uint8_t center26ToneRuIndication{0};
865 for (const auto& userInfo : m_muUserInfos)
866 {
867 if ((userInfo.second.ru.GetRuType() == HeRu::RU_26_TONE) &&
868 (userInfo.second.ru.GetIndex() == 19))
869 {
870 center26ToneRuIndication |= (userInfo.second.ru.GetPrimary80MHz())
873 }
874 }
875 return static_cast<Center26ToneRuIndication>(center26ToneRuIndication);
876}
877
878} // namespace ns3
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
Definition: eht-phy.cc:243
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1549
RU Specification.
Definition: he-ru.h:66
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:763
static constexpr uint8_t EMPTY_242_TONE_RU
Empty 242-tone RU identifier.
Definition: he-ru.h:311
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:511
static uint8_t GetEqualizedRuAllocation(RuType ruType, bool isOdd)
Get the RU_ALLOCATION value for equal size RUs.
Definition: he-ru.cc:421
@ RU_26_TONE
Definition: he-ru.h:42
@ RU_2x996_TONE
Definition: he-ru.h:48
represent a single transmission mode
Definition: wifi-mode.h:51
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 SetCenter26ToneRuIndication(Center26ToneRuIndication center26ToneRuIndication)
Set CENTER_26_TONE_RU field.
void SetRuAllocation(const RuAllocation &ruAlloc, uint8_t p20Index)
Set RU_ALLOCATION field.
void SetStbc(bool stbc)
Sets if STBC is being used.
void SetNess(uint8_t ness)
Sets the Ness number.
UserInfoMapOrderedByRus GetUserInfoMapOrderedByRus(uint8_t p20Index) const
Get the map of specific user info parameters ordered per increasing frequency RUs.
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.
uint8_t GetNumStasInRu(const HeRu::RuSpec &ru) const
Get the number of STAs in a given RU.
uint16_t GetGuardInterval() const
bool IsSigBCompression() const
Indicate whether the Common field is present in the HE-SIG-B field.
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)
uint8_t GetBssColor() const
Get the BSS color.
bool GetModeInitialized() const
const RuAllocation & GetRuAllocation(uint8_t p20Index) const
Get RU_ALLOCATION field.
std::optional< Center26ToneRuIndication > m_center26ToneRuIndication
CENTER_26_TONE_RU field when format is HE_MU and when channel width is set to 80 MHz or larger (Table...
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)
bool IsValid(WifiPhyBand band=WIFI_PHY_BAND_UNSPECIFIED) const
The standard disallows certain combinations of WifiMode, number of spatial streams,...
std::optional< Center26ToneRuIndication > GetCenter26ToneRuIndication() const
Get CENTER_26_TONE_RU field This field is present if format is HE_MU and when channel width is set to...
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
uint8_t GetNssTotal() const
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.
uint8_t GetEhtPpduType() const
Get the EHT_PPDU_TYPE parameter.
bool IsDlOfdma() const
Return true if this TX vector is used for a downlink multi-user transmission using OFDMA.
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.
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
std::map< HeRu::RuSpec, std::set< uint16_t >, HeRu::RuSpecCompare > UserInfoMapOrderedByRus
map of specific user info parameters ordered per increasing frequency RUs
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.
bool IsAllocated(uint16_t staId) const
Check if STA ID is allocated.
uint16_t GetChannelWidth() const
WifiPreamble m_preamble
preamble
Center26ToneRuIndication DeriveCenter26ToneRuIndication() const
Derive the CENTER_26_TONE_RU field from the TXVECTOR for which its CENTER_26_TONE_RU has not been set...
RuAllocation DeriveRuAllocation(uint8_t p20Index) const
Derive the RU_ALLOCATION field from the TXVECTOR for which its RU_ALLOCATION field has not been set y...
bool m_modeInitialized
Internal initialization flag.
bool IsDlMuMimo() const
Return true if this TX vector is used for a downlink multi-user transmission using MU-MIMO.
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.
Center26ToneRuIndication
Enum for the different values for CENTER_26_TONE_RU.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
@ WIFI_PREAMBLE_LONG
@ WIFI_PREAMBLE_HE_SU
@ CENTER_26_TONE_RU_HIGH_80_MHZ_ALLOCATED
@ CENTER_26_TONE_RU_LOW_80_MHZ_ALLOCATED
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
Definition: wifi-phy-band.h:43
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_MOD_CLASS_ERP_OFDM
ERP-OFDM (18.4)
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:159
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.
STL namespace.
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.
Struct providing a function call operator to compare two RUs.
Definition: he-ru.h:141
Declaration of the following enums: