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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Nicola Baldo <nbaldo@cttc.es>
7 * Ghada Badawy <gbadawy@gmail.com>
8 */
9
10#include "wifi-tx-vector.h"
11
12#include "wifi-phy-common.h"
13#include "wifi-utils.h"
14
15#include "ns3/abort.h"
16#include "ns3/eht-phy.h"
17
18#include <algorithm>
19#include <iterator>
20#include <numeric>
21#include <set>
22
23namespace ns3
24{
25
27 : m_txPowerLevel(1),
28 m_preamble(WIFI_PREAMBLE_LONG),
29 m_channelWidth(MHz_u{20}),
30 m_guardInterval(NanoSeconds(800)),
31 m_nTx(1),
32 m_nss(1),
33 m_ness(0),
34 m_aggregation(false),
35 m_stbc(false),
36 m_ldpc(false),
37 m_bssColor(0),
38 m_length(0),
39 m_triggerResponding(false),
40 m_modeInitialized(false),
41 m_inactiveSubchannels(),
42 m_ruAllocation(),
43 m_center26ToneRuIndication(std::nullopt),
44 m_ehtPpduType(1) // SU transmission by default
45{
46}
47
49 uint8_t powerLevel,
50 WifiPreamble preamble,
51 Time guardInterval,
52 uint8_t nTx,
53 uint8_t nss,
54 uint8_t ness,
55 MHz_u channelWidth,
56 bool aggregation,
57 bool stbc,
58 bool ldpc,
59 uint8_t bssColor,
60 uint16_t length,
61 bool triggerResponding)
62 : m_mode(mode),
63 m_txPowerLevel(powerLevel),
64 m_preamble(preamble),
65 m_channelWidth(channelWidth),
66 m_guardInterval(guardInterval),
67 m_nTx(nTx),
68 m_nss(nss),
69 m_ness(ness),
70 m_aggregation(aggregation),
71 m_stbc(stbc),
72 m_ldpc(ldpc),
73 m_bssColor(bssColor),
74 m_length(length),
75 m_triggerResponding(triggerResponding),
76 m_modeInitialized(true),
77 m_inactiveSubchannels(),
78 m_ruAllocation(),
79 m_center26ToneRuIndication(std::nullopt),
80 m_ehtPpduType(1) // SU transmission by default
81{
82}
83
85 : m_mode(txVector.m_mode),
86 m_txPowerLevel(txVector.m_txPowerLevel),
87 m_preamble(txVector.m_preamble),
88 m_channelWidth(txVector.m_channelWidth),
89 m_guardInterval(txVector.m_guardInterval),
90 m_nTx(txVector.m_nTx),
91 m_nss(txVector.m_nss),
92 m_ness(txVector.m_ness),
93 m_aggregation(txVector.m_aggregation),
94 m_stbc(txVector.m_stbc),
95 m_ldpc(txVector.m_ldpc),
96 m_bssColor(txVector.m_bssColor),
97 m_length(txVector.m_length),
98 m_triggerResponding(txVector.m_triggerResponding),
99 m_modeInitialized(txVector.m_modeInitialized),
100 m_inactiveSubchannels(txVector.m_inactiveSubchannels),
101 m_sigBMcs(txVector.m_sigBMcs),
102 m_ruAllocation(txVector.m_ruAllocation),
103 m_center26ToneRuIndication(txVector.m_center26ToneRuIndication),
104 m_ehtPpduType(txVector.m_ehtPpduType)
105{
106 m_muUserInfos.clear();
107 if (!txVector.m_muUserInfos.empty()) // avoids crashing for loop
108 {
109 for (auto& info : txVector.m_muUserInfos)
110 {
111 m_muUserInfos.insert(std::make_pair(info.first, info.second));
112 }
113 }
114}
115
116bool
121
123WifiTxVector::GetMode(uint16_t staId) const
124{
126 {
127 NS_FATAL_ERROR("WifiTxVector mode must be set before using");
128 }
129 if (!IsMu())
130 {
131 return m_mode;
132 }
133 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
134 const auto userInfoIt = m_muUserInfos.find(staId);
135 NS_ASSERT(userInfoIt != m_muUserInfos.cend());
137 {
139 return EhtPhy::GetEhtMcs(userInfoIt->second.mcs);
141 return HePhy::GetHeMcs(userInfoIt->second.mcs);
142 default:
143 NS_ABORT_MSG("Unsupported modulation class: " << GetModulationClassForPreamble(m_preamble));
144 }
145 return WifiMode(); // invalid WifiMode
146}
147
150{
151 NS_ABORT_MSG_IF(!m_modeInitialized, "WifiTxVector mode must be set before using");
152
153 if (IsMu())
154 {
155 NS_ASSERT(!m_muUserInfos.empty());
156 // all the modes belong to the same modulation class
158 }
159 return m_mode.GetModulationClass();
160}
161
162uint8_t
164{
165 return m_txPowerLevel;
166}
167
170{
171 return m_preamble;
172}
173
174MHz_u
176{
177 return m_channelWidth;
178}
179
180Time
185
186uint8_t
188{
189 return m_nTx;
190}
191
192uint8_t
193WifiTxVector::GetNss(uint16_t staId) const
194{
195 if (IsMu())
196 {
197 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
198 NS_ASSERT(m_muUserInfos.contains(staId));
199 return m_muUserInfos.at(staId).nss;
200 }
201 return m_nss;
202}
203
204uint8_t
206{
207 // We do not support mixed OFDMA and MU-MIMO
208 uint8_t nss = 0;
209 if (IsMu())
210 {
211 for (const auto& info : m_muUserInfos)
212 {
213 nss = (nss < info.second.nss) ? info.second.nss : nss;
214 }
215 }
216 else
217 {
218 nss = m_nss;
219 }
220 return nss;
221}
222
223uint8_t
225{
226 // We do not support mixed OFDMA and MU-MIMO
227 uint8_t nss = 0;
228 if (IsMu())
229 {
230 nss = std::accumulate(
231 m_muUserInfos.cbegin(),
232 m_muUserInfos.cend(),
233 0,
234 [](uint8_t prevNss, const auto& info) { return prevNss + info.second.nss; });
235 }
236 else
237 {
238 nss = m_nss;
239 }
240 return nss;
241}
242
243uint8_t
245{
246 return m_ness;
247}
248
249bool
251{
252 return m_aggregation;
253}
254
255bool
257{
258 return m_stbc;
259}
260
261bool
263{
264 return m_ldpc;
265}
266
267bool
269{
270 return ((m_channelWidth >= MHz_u{40}) && !IsMu() && (GetModulationClass() < WIFI_MOD_CLASS_HT));
271}
272
273void
275{
276 m_mode = mode;
277 m_modeInitialized = true;
278}
279
280void
281WifiTxVector::SetMode(WifiMode mode, uint16_t staId)
282{
283 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
284 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
286 "Cannot add mode " << mode << " because the modulation class is "
287 << GetModulationClass());
288 m_muUserInfos[staId].mcs = mode.GetMcsValue();
289 m_modeInitialized = true;
290}
291
292void
294{
295 m_txPowerLevel = powerlevel;
296}
297
298void
300{
301 m_preamble = preamble;
302}
303
304void
306{
307 m_channelWidth = channelWidth;
308}
309
310void
312{
313 m_guardInterval = guardInterval;
314}
315
316void
318{
319 m_nTx = nTx;
320}
321
322void
324{
325 m_nss = nss;
326}
327
328void
329WifiTxVector::SetNss(uint8_t nss, uint16_t staId)
330{
331 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
332 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
333 m_muUserInfos[staId].nss = nss;
334}
335
336void
338{
339 m_ness = ness;
340}
341
342void
344{
345 m_aggregation = aggregation;
346}
347
348void
350{
351 m_stbc = stbc;
352}
353
354void
356{
357 m_ldpc = ldpc;
358}
359
360void
362{
363 m_bssColor = color;
364}
365
366uint8_t
368{
369 return m_bssColor;
370}
371
372void
374{
375 m_length = length;
376}
377
378uint16_t
380{
381 return m_length;
382}
383
384bool
389
390void
392{
393 m_triggerResponding = triggerResponding;
394}
395
396void
398{
399 m_sigBMcs = mode;
400}
401
404{
405 return m_sigBMcs;
406}
407
408void
409WifiTxVector::SetRuAllocation(const RuAllocation& ruAlloc, uint8_t p20Index)
410{
411 if (ns3::IsDlMu(m_preamble) && !m_muUserInfos.empty())
412 {
413 NS_ASSERT(ruAlloc == DeriveRuAllocation(p20Index));
414 }
415 m_ruAllocation = ruAlloc;
416}
417
418const RuAllocation&
419WifiTxVector::GetRuAllocation(uint8_t p20Index) const
420{
421 if (ns3::IsDlMu(m_preamble) && m_ruAllocation.empty())
422 {
424 }
425 return m_ruAllocation;
426}
427
428void
430{
432 m_ehtPpduType = type;
433}
434
435uint8_t
437{
438 return m_ehtPpduType;
439}
440
441bool
443{
444 if (!GetModeInitialized())
445 {
446 return false;
447 }
448 const auto& modeName = m_mode.GetUniqueName();
449 if (m_channelWidth == MHz_u{20})
450 {
451 if (m_nss != 3 && m_nss != 6)
452 {
453 if (modeName == "VhtMcs9")
454 {
455 return false;
456 }
457 }
458 }
459 else if (m_channelWidth == MHz_u{80})
460 {
461 if (m_nss == 3 || m_nss == 7)
462 {
463 if (modeName == "VhtMcs6")
464 {
465 return false;
466 }
467 }
468 else if (m_nss == 6)
469 {
470 if (modeName == "VhtMcs9")
471 {
472 return false;
473 }
474 }
475 }
476 else if (m_channelWidth == MHz_u{160})
477 {
478 if (m_nss == 3)
479 {
480 if (modeName == "VhtMcs9")
481 {
482 return false;
483 }
484 }
485 }
486 for (const auto& userInfo : m_muUserInfos)
487 {
488 if (GetNumStasInRu(userInfo.second.ru) > 8)
489 {
490 return false;
491 }
492 }
493 std::map<WifiRu::RuSpec, uint8_t> streamsPerRu{};
494 for (const auto& info : m_muUserInfos)
495 {
496 auto it = streamsPerRu.find(info.second.ru);
497 if (it == streamsPerRu.end())
498 {
499 streamsPerRu[info.second.ru] = info.second.nss;
500 }
501 else
502 {
503 it->second += info.second.nss;
504 }
505 }
506 for (auto& streams : streamsPerRu)
507 {
508 if (streams.second > 8)
509 {
510 return false;
511 }
512 }
513
514 if (band != WIFI_PHY_BAND_UNSPECIFIED)
515 {
517 "Cannot use OFDM modulation class in the 2.4 GHz band");
519 band != WIFI_PHY_BAND_2_4GHZ,
520 "ERP-OFDM modulation class can only be used in the 2.4 GHz band");
521 }
522
523 return true;
524}
525
526bool
528{
529 return IsDlMu() || IsUlMu();
530}
531
532bool
534{
535 return ns3::IsDlMu(m_preamble) && !(IsEht(m_preamble) && m_ehtPpduType == 1);
536}
537
538bool
540{
541 return ns3::IsUlMu(m_preamble);
542}
543
544bool
546{
547 if (!IsDlMu())
548 {
549 return false;
550 }
551 if (IsEht(m_preamble))
552 {
553 return m_ehtPpduType == 0;
554 }
555 if (m_muUserInfos.size() == 1)
556 {
557 return true;
558 }
559 std::set<WifiRu::RuSpec> rus{};
560 for (const auto& userInfo : m_muUserInfos)
561 {
562 rus.insert(userInfo.second.ru);
563 if (rus.size() > 1)
564 {
565 return true;
566 }
567 }
568 return false;
569}
570
571bool
573{
574 if (!IsDlMu())
575 {
576 return false;
577 }
578 if (IsEht(m_preamble))
579 {
580 return m_ehtPpduType == 2;
581 }
582 if (m_muUserInfos.size() < 2)
583 {
584 return false;
585 }
586 // TODO: mixed OFDMA and MU-MIMO is not supported
587 return !IsDlOfdma();
588}
589
590uint8_t
592{
593 return std::count_if(m_muUserInfos.cbegin(),
594 m_muUserInfos.cend(),
595 [&ru](const auto& info) -> bool { return (ru == info.second.ru); });
596}
597
599WifiTxVector::GetRu(uint16_t staId) const
600{
601 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
602 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
603 return m_muUserInfos.at(staId).ru;
604}
605
606void
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 m_muUserInfos[staId].ru = ru;
612}
613
615WifiTxVector::GetHeMuUserInfo(uint16_t staId) const
616{
617 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
618 return m_muUserInfos.at(staId);
619}
620
621void
623{
624 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
625 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
626 m_muUserInfos[staId] = userInfo;
627 m_modeInitialized = true;
628 m_ruAllocation.clear();
629}
630
633{
634 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
635 return m_muUserInfos;
636}
637
640{
641 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
642 m_ruAllocation.clear();
643 return m_muUserInfos;
644}
645
646bool
648{
649 // SIG-B compression is used in case of full-bandwidth MU-MIMO transmission (27.3.11.8.2
650 // HE-SIG-B content channels in IEEE802.11ax-2021) or if a single RU occupies the whole 160 MHz
651 // bandwidth (27.3.11.8.3 Common field in IEEE802.11ax-2021)
652 return (IsDlMuMimo() && !IsDlOfdma()) ||
653 ((m_muUserInfos.size() == 1) && (m_channelWidth >= MHz_u{160}) &&
654 (WifiRu::GetRuType(m_muUserInfos.cbegin()->second.ru) ==
656}
657
658void
659WifiTxVector::SetInactiveSubchannels(const std::vector<bool>& inactiveSubchannels)
660{
662 "Only HE (or later) authorized for preamble puncturing");
664 m_channelWidth < MHz_u{80},
665 "Preamble puncturing only possible for transmission bandwidth of 80 MHz or larger");
666 NS_ABORT_MSG_IF(!inactiveSubchannels.empty() &&
667 inactiveSubchannels.size() != Count20MHzSubchannels(m_channelWidth),
668 "The size of the inactive subchannnels bitmap should be equal to the number of "
669 "20 MHz subchannels");
670 m_inactiveSubchannels = inactiveSubchannels;
671}
672
673const std::vector<bool>&
678
679void
681{
682 if (IsDlMu())
683 {
684 NS_ASSERT(center26ToneRuIndication == DeriveCenter26ToneRuIndication());
685 }
686 m_center26ToneRuIndication = center26ToneRuIndication;
687}
688
689std::optional<Center26ToneRuIndication>
691{
692 if (!IsDlMu() || (m_channelWidth < MHz_u{80}))
693 {
694 return std::nullopt;
695 }
696 if (!m_center26ToneRuIndication.has_value())
697 {
699 }
701}
702
703std::ostream&
704operator<<(std::ostream& os, const WifiTxVector& v)
705{
706 if (!v.IsValid())
707 {
708 os << "TXVECTOR not valid";
709 return os;
710 }
711 os << "txpwrlvl: " << +v.GetTxPowerLevel() << " preamble: " << v.GetPreambleType()
712 << " channel width: " << v.GetChannelWidth() << " GI: " << v.GetGuardInterval()
713 << " NTx: " << +v.GetNTx() << " Ness: " << +v.GetNess()
714 << " MPDU aggregation: " << v.IsAggregation() << " STBC: " << v.IsStbc()
715 << " FEC coding: " << (v.IsLdpc() ? "LDPC" : "BCC");
717 {
718 os << " BSS color: " << +v.GetBssColor();
719 }
720 if (v.IsUlMu())
721 {
722 os << " Length: " << v.GetLength();
723 }
725 {
726 os << " SIG-B mode: " << v.GetSigBMode();
727 }
728 if (v.IsMu())
729 {
731 os << " num User Infos: " << userInfoMap.size();
732 for (auto& ui : userInfoMap)
733 {
734 os << ", {STA-ID: " << ui.first << ", " << ui.second.ru << ", MCS: " << +ui.second.mcs
735 << ", Nss: " << +ui.second.nss << "}";
736 }
737 }
738 else
739 {
740 os << " mode: " << v.GetMode() << " Nss: " << +v.GetNss();
741 }
742 const auto& puncturedSubchannels = v.GetInactiveSubchannels();
743 if (!puncturedSubchannels.empty())
744 {
745 os << " Punctured subchannels: ";
746 std::copy(puncturedSubchannels.cbegin(),
747 puncturedSubchannels.cend(),
748 std::ostream_iterator<bool>(os, ", "));
749 }
750 if (IsEht(v.GetPreambleType()))
751 {
752 os << " EHT PPDU type: " << +v.GetEhtPpduType();
753 }
754 return os;
755}
756
757bool
759{
760 return ru == other.ru && mcs == other.mcs && nss == other.nss;
761}
762
763bool
765{
766 return !(*this == other);
767}
768
771{
772 auto heRuComparator = WifiRu::RuSpecCompare(m_channelWidth, p20Index);
773 UserInfoMapOrderedByRus orderedMap{heRuComparator};
774 for (const auto& userInfo : m_muUserInfos)
775 {
776 const auto ru = userInfo.second.ru;
777 if (auto it = orderedMap.find(ru); it != orderedMap.end())
778 {
779 it->second.emplace(userInfo.first);
780 }
781 else
782 {
783 orderedMap.emplace(ru, std::set<uint16_t>{userInfo.first});
784 }
785 }
786 return orderedMap;
787}
788
790WifiTxVector::DeriveRuAllocation(uint8_t p20Index) const
791{
793 std::vector<RuType> ruTypes{};
794 ruTypes.resize(ruAllocations.size());
795 const auto& orderedMap = GetUserInfoMapOrderedByRus(p20Index);
796 std::pair<std::size_t /* number of RUs in content channel 1 */,
797 std::size_t /* number of RUs in content channel 2 */>
798 ccSizes{0, 0};
799 for (const auto& [ru, staIds] : orderedMap)
800 {
801 const auto ruType = WifiRu::GetRuType(ru);
802 auto ruIndex = WifiRu::GetPhyIndex(ru, m_channelWidth, p20Index);
803 if ((ruType == RuType::RU_26_TONE) && (ruIndex == 19))
804 {
805 continue;
806 }
807 const auto ruBw = WifiRu::GetBandwidth(ruType);
808 NS_ASSERT_MSG(WifiRu::IsHe(ru), "EHT RUs should not be used yet");
809 const auto mc{WIFI_MOD_CLASS_HE};
810 const auto rusPerSubchannel =
811 WifiRu::GetRusOfType(ruBw > MHz_u{20} ? ruBw : MHz_u{20}, ruType, mc);
812 if ((m_channelWidth >= MHz_u{80}) && (ruIndex > 19))
813 {
814 // "ignore" the center 26-tone RUs in 80 MHz channels
815 ruIndex--;
816 if (ruIndex > 37)
817 {
818 ruIndex -= (ruIndex - 19) / 37;
819 }
820 }
821 const auto numSubchannelsForRu = (ruBw < MHz_u{20}) ? 1 : Count20MHzSubchannels(ruBw);
822 const auto index = (ruBw < MHz_u{20}) ? ((ruIndex - 1) / rusPerSubchannel.size())
823 : ((ruIndex - 1) * numSubchannelsForRu);
825 auto ruAlloc = WifiRu::GetEqualizedRuAllocation(ruType, false, true, mc);
826 if (ruAllocations.at(index) != HeRu::EMPTY_242_TONE_RU)
827 {
828 if (ruType == ruTypes.at(index))
829 {
830 continue;
831 }
832 if (ruType == RuType::RU_26_TONE)
833 {
834 ruAlloc = WifiRu::GetEqualizedRuAllocation(ruTypes.at(index), true, true, mc);
835 }
836 else if (ruTypes.at(index) == RuType::RU_26_TONE)
837 {
838 ruAlloc = WifiRu::GetEqualizedRuAllocation(ruType, true, true, mc);
839 }
840 else
841 {
842 NS_ASSERT_MSG(false, "unsupported RU combination");
843 }
844 }
845 std::size_t ccIndex;
846 if (ruType >= RuType::RU_484_TONE)
847 {
848 ccIndex = (ccSizes.first <= ccSizes.second) ? 0 : 1;
849 }
850 else
851 {
852 ccIndex = (index % 2 == 0) ? 0 : 1;
853 }
854 if (ccIndex == 0)
855 {
856 ccSizes.first += staIds.size();
857 }
858 else
859 {
860 ccSizes.second += staIds.size();
861 }
862 for (std::size_t i = 0; i < numSubchannelsForRu; ++i)
863 {
864 auto ruAllocNoUsers = HeRu::GetEqualizedRuAllocation(ruType, false, false);
865 ruTypes.at(index + i) = ruType;
866 ruAllocations.at(index + i) =
867 (IsSigBCompression() || ((index + i) % 2) == ccIndex) ? ruAlloc : ruAllocNoUsers;
868 }
869 }
870 return ruAllocations;
871}
872
875{
876 uint8_t center26ToneRuIndication{0};
877 for (const auto& userInfo : m_muUserInfos)
878 {
879 NS_ASSERT(WifiRu::IsHe(userInfo.second.ru));
880 if ((WifiRu::GetRuType(userInfo.second.ru) == RuType::RU_26_TONE) &&
881 (WifiRu::GetIndex(userInfo.second.ru) == 19))
882 {
883 center26ToneRuIndication |=
884 (std::get<HeRu::RuSpec>(userInfo.second.ru).GetPrimary80MHz())
887 }
888 }
889 return static_cast<Center26ToneRuIndication>(center26ToneRuIndication);
890}
891
892} // namespace ns3
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
Definition eht-phy.cc:232
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition he-phy.cc:1550
static constexpr uint8_t EMPTY_242_TONE_RU
Empty 242-tone RU identifier.
Definition he-ru.h:243
static uint16_t GetEqualizedRuAllocation(RuType ruType, bool isOdd, bool hasUsers)
Get the RU_ALLOCATION value for equal size RUs.
Definition he-ru.cc:397
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
represent a single transmission mode
Definition wifi-mode.h:40
const std::string & GetUniqueName() const
Definition wifi-mode.cc:136
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:173
uint8_t GetMcsValue() const
Definition wifi-mode.cc:151
std::variant< HeRu::RuSpec, EhtRu::RuSpec > RuSpec
variant of the RU specification
Definition wifi-ru.h:27
static std::vector< RuSpec > GetRusOfType(MHz_u bw, RuType ruType, WifiModulationClass mc)
Get the set of distinct RUs of the given type (number of tones) available in an MU PPDU of the given ...
Definition wifi-ru.cc:173
static bool IsHe(RuSpec ru)
Get whether a given RU variant is a HE RU.
Definition wifi-ru.cc:248
static MHz_u GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition wifi-ru.cc:78
static RuType GetRuType(RuSpec ru)
Get the type of a given RU.
Definition wifi-ru.cc:45
static uint16_t GetEqualizedRuAllocation(RuType ruType, bool isOdd, bool hasUsers, WifiModulationClass mc)
Get the RU_ALLOCATION value for equal size RUs.
Definition wifi-ru.cc:149
static std::size_t GetPhyIndex(RuSpec ru, MHz_u bw, uint8_t p20Index)
Get the RU PHY index.
Definition wifi-ru.cc:57
static std::size_t GetIndex(RuSpec ru)
Get the index of a given RU.
Definition wifi-ru.cc:51
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
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.
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.
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.
void SetGuardInterval(Time guardInterval)
Sets the guard interval duration (in nanoseconds)
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
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.
MHz_u m_channelWidth
channel width
void SetRu(WifiRu::RuSpec ru, uint16_t staId)
Set the RU specification for the 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.
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.
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
bool m_ldpc
LDPC FEC coding if true, BCC otherwise.
uint16_t GetLength() const
Get the LENGTH field of the L-SIG.
bool m_stbc
STBC used or not.
std::map< WifiRu::RuSpec, std::set< uint16_t >, WifiRu::RuSpecCompare > UserInfoMapOrderedByRus
map of specific user info parameters ordered per increasing frequency RUs
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.
uint8_t GetNumStasInRu(const WifiRu::RuSpec &ru) const
Get the number of STAs in a given RU.
uint8_t GetEhtPpduType() const
Get the EHT_PPDU_TYPE parameter.
Time m_guardInterval
guard interval duration
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
MHz_u GetChannelWidth() 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
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.
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...
Time GetGuardInterval() const
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
WifiRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
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:55
#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:75
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
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.
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.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ 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:148
double MHz_u
MHz weak type.
Definition wifi-units.h:31
WifiModulationClass GetModulationClassForPreamble(WifiPreamble preamble)
Return the modulation class corresponding to the given preamble type.
std::size_t Count20MHzSubchannels(MHz_u channelWidth)
Return the number of 20 MHz subchannels covering the channel width.
Definition wifi-utils.h:135
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.
std::vector< uint16_t > RuAllocation
9 bits RU_ALLOCATION per 20 MHz
STL namespace.
HE MU specific user transmission parameters.
uint8_t mcs
MCS index.
uint8_t nss
number of spatial streams
WifiRu::RuSpec ru
RU specification.
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 wifi-ru.h:33
Declaration of the following enums: