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
127{
128 m_muUserInfos.clear();
129}
130
131bool
133{
134 return m_modeInitialized;
135}
136
138WifiTxVector::GetMode(uint16_t staId) const
139{
141 {
142 NS_FATAL_ERROR("WifiTxVector mode must be set before using");
143 }
144 if (!IsMu())
145 {
146 return m_mode;
147 }
148 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
149 const auto userInfoIt = m_muUserInfos.find(staId);
150 NS_ASSERT(userInfoIt != m_muUserInfos.cend());
152 {
154 return EhtPhy::GetEhtMcs(userInfoIt->second.mcs);
156 return HePhy::GetHeMcs(userInfoIt->second.mcs);
157 default:
158 NS_ABORT_MSG("Unsupported modulation class: " << GetModulationClassForPreamble(m_preamble));
159 }
160 return WifiMode(); // invalid WifiMode
161}
162
165{
166 NS_ABORT_MSG_IF(!m_modeInitialized, "WifiTxVector mode must be set before using");
167
168 if (IsMu())
169 {
170 NS_ASSERT(!m_muUserInfos.empty());
171 // all the modes belong to the same modulation class
173 }
174 return m_mode.GetModulationClass();
175}
176
177uint8_t
179{
180 return m_txPowerLevel;
181}
182
185{
186 return m_preamble;
187}
188
189uint16_t
191{
192 return m_channelWidth;
193}
194
195uint16_t
197{
198 return m_guardInterval;
199}
200
201uint8_t
203{
204 return m_nTx;
205}
206
207uint8_t
208WifiTxVector::GetNss(uint16_t staId) const
209{
210 if (IsMu())
211 {
212 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
213 NS_ASSERT(m_muUserInfos.find(staId) != m_muUserInfos.end());
214 return m_muUserInfos.at(staId).nss;
215 }
216 return m_nss;
217}
218
219uint8_t
221{
222 // We do not support mixed OFDMA and MU-MIMO
223 uint8_t nss = 0;
224 if (IsMu())
225 {
226 for (const auto& info : m_muUserInfos)
227 {
228 nss = (nss < info.second.nss) ? info.second.nss : nss;
229 }
230 }
231 else
232 {
233 nss = m_nss;
234 }
235 return nss;
236}
237
238uint8_t
240{
241 // We do not support mixed OFDMA and MU-MIMO
242 uint8_t nss = 0;
243 if (IsMu())
244 {
245 nss = std::accumulate(
246 m_muUserInfos.cbegin(),
247 m_muUserInfos.cend(),
248 0,
249 [](uint8_t prevNss, const auto& info) { return prevNss + info.second.nss; });
250 }
251 else
252 {
253 nss = m_nss;
254 }
255 return nss;
256}
257
258uint8_t
260{
261 return m_ness;
262}
263
264bool
266{
267 return m_aggregation;
268}
269
270bool
272{
273 return m_stbc;
274}
275
276bool
278{
279 return m_ldpc;
280}
281
282bool
284{
285 return ((m_channelWidth >= 40) && !IsMu() && (GetModulationClass() < WIFI_MOD_CLASS_HT));
286}
287
288void
290{
291 m_mode = mode;
292 m_modeInitialized = true;
293}
294
295void
296WifiTxVector::SetMode(WifiMode mode, uint16_t staId)
297{
298 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
299 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
300 m_muUserInfos[staId].mcs = mode.GetMcsValue();
301 m_modeInitialized = true;
302}
303
304void
306{
307 m_txPowerLevel = powerlevel;
308}
309
310void
312{
313 m_preamble = preamble;
314}
315
316void
317WifiTxVector::SetChannelWidth(uint16_t channelWidth)
318{
319 m_channelWidth = channelWidth;
320}
321
322void
323WifiTxVector::SetGuardInterval(uint16_t guardInterval)
324{
325 m_guardInterval = guardInterval;
326}
327
328void
330{
331 m_nTx = nTx;
332}
333
334void
336{
337 m_nss = nss;
338}
339
340void
341WifiTxVector::SetNss(uint8_t nss, uint16_t staId)
342{
343 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
344 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
345 m_muUserInfos[staId].nss = nss;
346}
347
348void
350{
351 m_ness = ness;
352}
353
354void
356{
357 m_aggregation = aggregation;
358}
359
360void
362{
363 m_stbc = stbc;
364}
365
366void
368{
369 m_ldpc = ldpc;
370}
371
372void
374{
375 m_bssColor = color;
376}
377
378uint8_t
380{
381 return m_bssColor;
382}
383
384void
386{
387 m_length = length;
388}
389
390uint16_t
392{
393 return m_length;
394}
395
396bool
398{
399 return m_triggerResponding;
400}
401
402void
404{
405 m_triggerResponding = triggerResponding;
406}
407
408void
410{
411 m_sigBMcs = mode;
412}
413
416{
417 return m_sigBMcs;
418}
419
420void
421WifiTxVector::SetRuAllocation(const RuAllocation& ruAlloc, uint8_t p20Index)
422{
423 if (ns3::IsDlMu(m_preamble) && !m_muUserInfos.empty())
424 {
425 NS_ASSERT(ruAlloc == DeriveRuAllocation(p20Index));
426 }
427 m_ruAllocation = ruAlloc;
428}
429
430const RuAllocation&
431WifiTxVector::GetRuAllocation(uint8_t p20Index) const
432{
433 if (ns3::IsDlMu(m_preamble) && m_ruAllocation.empty())
434 {
436 }
437 return m_ruAllocation;
438}
439
440void
442{
444 m_ehtPpduType = type;
445}
446
447uint8_t
449{
450 return m_ehtPpduType;
451}
452
453bool
455{
456 if (!GetModeInitialized())
457 {
458 return false;
459 }
460 std::string modeName = m_mode.GetUniqueName();
461 if (m_channelWidth == 20)
462 {
463 if (m_nss != 3 && m_nss != 6)
464 {
465 if (modeName == "VhtMcs9")
466 {
467 return false;
468 }
469 }
470 }
471 else if (m_channelWidth == 80)
472 {
473 if (m_nss == 3 || m_nss == 7)
474 {
475 if (modeName == "VhtMcs6")
476 {
477 return false;
478 }
479 }
480 else if (m_nss == 6)
481 {
482 if (modeName == "VhtMcs9")
483 {
484 return false;
485 }
486 }
487 }
488 else if (m_channelWidth == 160)
489 {
490 if (m_nss == 3)
491 {
492 if (modeName == "VhtMcs9")
493 {
494 return false;
495 }
496 }
497 }
498 for (const auto& userInfo : m_muUserInfos)
499 {
500 if (GetNumStasInRu(userInfo.second.ru) > 8)
501 {
502 return false;
503 }
504 }
505 std::map<HeRu::RuSpec, uint8_t> streamsPerRu{};
506 for (const auto& info : m_muUserInfos)
507 {
508 auto it = streamsPerRu.find(info.second.ru);
509 if (it == streamsPerRu.end())
510 {
511 streamsPerRu[info.second.ru] = info.second.nss;
512 }
513 else
514 {
515 it->second += info.second.nss;
516 }
517 }
518 for (auto& streams : streamsPerRu)
519 {
520 if (streams.second > 8)
521 {
522 return false;
523 }
524 }
525 return true;
526}
527
528bool
530{
531 return IsDlMu() || IsUlMu();
532}
533
534bool
536{
537 return ns3::IsDlMu(m_preamble) && !(IsEht(m_preamble) && m_ehtPpduType == 1);
538}
539
540bool
542{
543 return ns3::IsUlMu(m_preamble);
544}
545
546bool
548{
549 if (!IsDlMu())
550 {
551 return false;
552 }
553 if (IsEht(m_preamble))
554 {
555 return m_ehtPpduType == 0;
556 }
557 if (m_muUserInfos.size() == 1)
558 {
559 return true;
560 }
561 std::set<HeRu::RuSpec> rus{};
562 for (const auto& userInfo : m_muUserInfos)
563 {
564 rus.insert(userInfo.second.ru);
565 if (rus.size() > 1)
566 {
567 return true;
568 }
569 }
570 return false;
571}
572
573bool
575{
576 if (!IsDlMu())
577 {
578 return false;
579 }
580 if (IsEht(m_preamble))
581 {
582 return m_ehtPpduType == 2;
583 }
584 if (m_muUserInfos.size() < 2)
585 {
586 return false;
587 }
588 // TODO: mixed OFDMA and MU-MIMO is not supported
589 return !IsDlOfdma();
590}
591
592uint8_t
594{
595 return std::count_if(m_muUserInfos.cbegin(),
596 m_muUserInfos.cend(),
597 [&ru](const auto& info) -> bool { return (ru == info.second.ru); });
598}
599
600bool
601WifiTxVector::IsAllocated(uint16_t staId) const
602{
603 return m_muUserInfos.count(staId) > 0;
604}
605
607WifiTxVector::GetRu(uint16_t staId) const
608{
609 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
610 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
611 return m_muUserInfos.at(staId).ru;
612}
613
614void
616{
617 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
618 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
619 m_muUserInfos[staId].ru = ru;
620}
621
623WifiTxVector::GetHeMuUserInfo(uint16_t staId) const
624{
625 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
626 return m_muUserInfos.at(staId);
627}
628
629void
631{
632 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
633 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
634 m_muUserInfos[staId] = userInfo;
635 m_modeInitialized = true;
636 m_ruAllocation.clear();
637}
638
641{
642 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
643 return m_muUserInfos;
644}
645
648{
649 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
650 m_ruAllocation.clear();
651 return m_muUserInfos;
652}
653
654bool
656{
657 return IsDlMuMimo() && !IsDlOfdma();
658}
659
660void
661WifiTxVector::SetInactiveSubchannels(const std::vector<bool>& inactiveSubchannels)
662{
664 "Only HE (or later) authorized for preamble puncturing");
666 m_channelWidth < 80,
667 "Preamble puncturing only possible for transmission bandwidth of 80 MHz or larger");
668 NS_ABORT_MSG_IF(!inactiveSubchannels.empty() &&
669 inactiveSubchannels.size() != (m_channelWidth / 20),
670 "The size of the inactive subchannnels bitmap should be equal to the number of "
671 "20 MHz subchannels");
672 m_inactiveSubchannels = inactiveSubchannels;
673}
674
675const std::vector<bool>&
677{
679}
680
681void
683{
684 if (IsDlMu())
685 {
686 NS_ASSERT(center26ToneRuIndication == DeriveCenter26ToneRuIndication());
687 }
688 m_center26ToneRuIndication = center26ToneRuIndication;
689}
690
691std::optional<Center26ToneRuIndication>
693{
694 if (!IsDlMu() || (m_channelWidth < 80))
695 {
696 return std::nullopt;
697 }
698 if (!m_center26ToneRuIndication.has_value())
699 {
701 }
703}
704
705std::ostream&
706operator<<(std::ostream& os, const WifiTxVector& v)
707{
708 if (!v.IsValid())
709 {
710 os << "TXVECTOR not valid";
711 return os;
712 }
713 os << "txpwrlvl: " << +v.GetTxPowerLevel() << " preamble: " << v.GetPreambleType()
714 << " channel width: " << v.GetChannelWidth() << " GI: " << v.GetGuardInterval()
715 << " NTx: " << +v.GetNTx() << " Ness: " << +v.GetNess()
716 << " MPDU aggregation: " << v.IsAggregation() << " STBC: " << v.IsStbc()
717 << " FEC coding: " << (v.IsLdpc() ? "LDPC" : "BCC");
719 {
720 os << " BSS color: " << +v.GetBssColor();
721 }
722 if (v.IsUlMu())
723 {
724 os << " Length: " << v.GetLength();
725 }
727 {
728 os << " SIG-B mode: " << v.GetSigBMode();
729 }
730 if (v.IsMu())
731 {
733 os << " num User Infos: " << userInfoMap.size();
734 for (auto& ui : userInfoMap)
735 {
736 os << ", {STA-ID: " << ui.first << ", " << ui.second.ru << ", MCS: " << +ui.second.mcs
737 << ", Nss: " << +ui.second.nss << "}";
738 }
739 }
740 else
741 {
742 os << " mode: " << v.GetMode() << " Nss: " << +v.GetNss();
743 }
744 const auto& puncturedSubchannels = v.GetInactiveSubchannels();
745 if (!puncturedSubchannels.empty())
746 {
747 os << " Punctured subchannels: ";
748 std::copy(puncturedSubchannels.cbegin(),
749 puncturedSubchannels.cend(),
750 std::ostream_iterator<bool>(os, ", "));
751 }
752 if (IsEht(v.GetPreambleType()))
753 {
754 os << " EHT PPDU type: " << +v.GetEhtPpduType();
755 }
756 return os;
757}
758
759bool
761{
762 return ru == other.ru && mcs == other.mcs && nss == other.nss;
763}
764
765bool
767{
768 return !(*this == other);
769}
770
773{
774 auto heRuComparator = HeRu::RuSpecCompare(m_channelWidth, p20Index);
775 UserInfoMapOrderedByRus orderedMap{heRuComparator};
776 for (const auto& userInfo : m_muUserInfos)
777 {
778 const auto ru = userInfo.second.ru;
779 if (auto it = orderedMap.find(ru); it != orderedMap.end())
780 {
781 it->second.emplace(userInfo.first);
782 }
783 else
784 {
785 orderedMap.emplace(userInfo.second.ru, std::set<uint16_t>{userInfo.first});
786 }
787 }
788 return orderedMap;
789}
790
792WifiTxVector::DeriveRuAllocation(uint8_t p20Index) const
793{
795 std::vector<HeRu::RuType> ruTypes{};
796 ruTypes.resize(ruAllocations.size());
797 const auto& orderedMap = GetUserInfoMapOrderedByRus(p20Index);
798 for (const auto& [ru, staIds] : orderedMap)
799 {
800 const auto ruType = ru.GetRuType();
801 const auto ruBw = HeRu::GetBandwidth(ruType);
802 const auto isPrimary80MHz = ru.GetPrimary80MHz();
803 const auto rusPerSubchannel = HeRu::GetRusOfType(ruBw > 20 ? ruBw : 20, ruType);
804 auto ruIndex = ru.GetIndex();
805 if ((m_channelWidth >= 80) && (ruIndex > 19))
806 {
807 // take into account the center 26-tone RU in the primary 80 MHz
808 ruIndex--;
809 }
810 if ((!isPrimary80MHz) && (ruIndex > 19))
811 {
812 // take into account the center 26-tone RU in the secondary 80 MHz
813 ruIndex--;
814 }
815 if (!isPrimary80MHz && (ruType != HeRu::RU_2x996_TONE))
816 {
818 // adjust RU index for the secondary 80 MHz: in that case index is restarting at 1,
819 // hence we need to add an offset corresponding to the number of RUs of the same type in
820 // the primary 80 MHz
821 ruIndex += HeRu::GetRusOfType(80, ruType).size();
822 }
823 const auto index =
824 (ruBw < 20) ? ((ruIndex - 1) / rusPerSubchannel.size()) : ((ruIndex - 1) * (ruBw / 20));
825 const auto numSubchannelsForRu = (ruBw < 20) ? 1 : (ruBw / 20);
826 NS_ABORT_IF(index >= (m_channelWidth / 20));
827 auto ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, false);
828 if (ruAllocations.at(index) != HeRu::EMPTY_242_TONE_RU)
829 {
830 if (ruType == ruTypes.at(index))
831 {
832 continue;
833 }
834 if (ruType == HeRu::RU_26_TONE)
835 {
836 ruAlloc = HeRu::GetEqualizedRuAllocation(ruTypes.at(index), true);
837 }
838 else if (ruTypes.at(index) == HeRu::RU_26_TONE)
839 {
840 ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, true);
841 }
842 else
843 {
844 NS_ASSERT_MSG(false, "unsupported RU combination");
845 }
846 }
847 for (auto i = 0; i < numSubchannelsForRu; ++i)
848 {
849 ruTypes.at(index + i) = ruType;
850 ruAllocations.at(index + i) = ruAlloc;
851 }
852 }
853 return ruAllocations;
854}
855
858{
859 uint8_t center26ToneRuIndication{0};
860 for (const auto& userInfo : m_muUserInfos)
861 {
862 if ((userInfo.second.ru.GetRuType() == HeRu::RU_26_TONE) &&
863 (userInfo.second.ru.GetIndex() == 19))
864 {
865 center26ToneRuIndication |= (userInfo.second.ru.GetPrimary80MHz())
868 }
869 }
870 return static_cast<Center26ToneRuIndication>(center26ToneRuIndication);
871}
872
873} // namespace ns3
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
Definition: eht-phy.cc:240
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1551
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.
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
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)
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.
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_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: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: