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
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),
40 m_modeInitialized(false),
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),
78 m_sigBMcs(EhtPhy::GetVhtMcs(0)),
81 m_ehtPpduType(1) // SU transmission by default
82{
83}
84
86 : m_mode(txVector.m_mode),
88 m_preamble(txVector.m_preamble),
91 m_nTx(txVector.m_nTx),
92 m_nss(txVector.m_nss),
93 m_ness(txVector.m_ness),
95 m_stbc(txVector.m_stbc),
96 m_ldpc(txVector.m_ldpc),
97 m_bssColor(txVector.m_bssColor),
98 m_length(txVector.m_length),
102 m_sigBMcs(txVector.m_sigBMcs),
106{
107 m_muUserInfos.clear();
108 if (!txVector.m_muUserInfos.empty()) // avoids crashing for loop
109 {
110 for (auto& info : txVector.m_muUserInfos)
111 {
112 m_muUserInfos.insert(std::make_pair(info.first, info.second));
113 }
114 }
115}
116
117bool
122
124WifiTxVector::GetMode(uint16_t staId) const
125{
127 {
128 NS_FATAL_ERROR("WifiTxVector mode must be set before using");
129 }
130 if (!IsMu())
131 {
132 return m_mode;
133 }
134 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
135 const auto userInfoIt = m_muUserInfos.find(staId);
136 NS_ASSERT(userInfoIt != m_muUserInfos.cend());
138 {
140 return EhtPhy::GetEhtMcs(userInfoIt->second.mcs);
142 return HePhy::GetHeMcs(userInfoIt->second.mcs);
143 default:
144 NS_ABORT_MSG("Unsupported modulation class: " << GetModulationClassForPreamble(m_preamble));
145 }
146 return WifiMode(); // invalid WifiMode
147}
148
151{
152 NS_ABORT_MSG_IF(!m_modeInitialized, "WifiTxVector mode must be set before using");
153
154 if (IsMu())
155 {
156 NS_ASSERT(!m_muUserInfos.empty());
157 // all the modes belong to the same modulation class
159 }
160 return m_mode.GetModulationClass();
161}
162
163uint8_t
165{
166 return m_txPowerLevel;
167}
168
171{
172 return m_preamble;
173}
174
175MHz_u
177{
178 return m_channelWidth;
179}
180
181Time
186
187uint8_t
189{
190 return m_nTx;
191}
192
193uint8_t
194WifiTxVector::GetNss(uint16_t staId) const
195{
196 if (IsMu())
197 {
198 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
199 NS_ASSERT(m_muUserInfos.contains(staId));
200 return m_muUserInfos.at(staId).nss;
201 }
202 return m_nss;
203}
204
205uint8_t
207{
208 // We do not support mixed OFDMA and MU-MIMO
209 uint8_t nss = 0;
210 if (IsMu())
211 {
212 for (const auto& info : m_muUserInfos)
213 {
214 nss = (nss < info.second.nss) ? info.second.nss : nss;
215 }
216 }
217 else
218 {
219 nss = m_nss;
220 }
221 return nss;
222}
223
224uint8_t
226{
227 // We do not support mixed OFDMA and MU-MIMO
228 uint8_t nss = 0;
229 if (IsMu())
230 {
231 nss = std::accumulate(
232 m_muUserInfos.cbegin(),
233 m_muUserInfos.cend(),
234 0,
235 [](uint8_t prevNss, const auto& info) { return prevNss + info.second.nss; });
236 }
237 else
238 {
239 nss = m_nss;
240 }
241 return nss;
242}
243
244uint8_t
246{
247 return m_ness;
248}
249
250bool
252{
253 return m_aggregation;
254}
255
256bool
258{
259 return m_stbc;
260}
261
262bool
264{
265 return m_ldpc;
266}
267
268bool
270{
271 return ((m_channelWidth >= MHz_u{40}) && !IsMu() && (GetModulationClass() < WIFI_MOD_CLASS_HT));
272}
273
274void
276{
277 m_mode = mode;
278 m_modeInitialized = true;
279}
280
281void
282WifiTxVector::SetMode(WifiMode mode, uint16_t staId)
283{
284 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
285 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
287 "Cannot add mode " << mode << " because the modulation class is "
288 << GetModulationClass());
289 m_muUserInfos[staId].mcs = mode.GetMcsValue();
290 m_modeInitialized = true;
291}
292
293void
295{
296 NS_ABORT_MSG_IF(powerlevel < WIFI_MIN_TX_PWR_LEVEL, "TX power level set below allowed range");
297 m_txPowerLevel = powerlevel;
298}
299
300void
302{
303 m_preamble = preamble;
304}
305
306void
308{
309 m_channelWidth = channelWidth;
310}
311
312void
314{
315 m_guardInterval = guardInterval;
316}
317
318void
320{
321 m_nTx = nTx;
322}
323
324void
326{
327 m_nss = nss;
328}
329
330void
331WifiTxVector::SetNss(uint8_t nss, uint16_t staId)
332{
333 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
334 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
335 m_muUserInfos[staId].nss = nss;
336}
337
338void
340{
341 m_ness = ness;
342}
343
344void
346{
347 m_aggregation = aggregation;
348}
349
350void
352{
353 m_stbc = stbc;
354}
355
356void
358{
359 m_ldpc = ldpc;
360}
361
362void
364{
365 m_bssColor = color;
366}
367
368uint8_t
370{
371 return m_bssColor;
372}
373
374void
376{
377 m_length = length;
378}
379
380uint16_t
382{
383 return m_length;
384}
385
386bool
391
392void
394{
395 m_triggerResponding = triggerResponding;
396}
397
398void
400{
401 m_sigBMcs = mode;
402}
403
406{
407 return m_sigBMcs;
408}
409
410void
411WifiTxVector::SetRuAllocation(const RuAllocation& ruAlloc, uint8_t p20Index)
412{
413 if (ns3::IsDlMu(m_preamble) && !m_muUserInfos.empty())
414 {
415 NS_ASSERT(ruAlloc == DeriveRuAllocation(p20Index));
416 }
417 m_ruAllocation = ruAlloc;
418}
419
420const RuAllocation&
421WifiTxVector::GetRuAllocation(uint8_t p20Index) const
422{
423 if (ns3::IsDlMu(m_preamble) && m_ruAllocation.empty())
424 {
426 }
427 return m_ruAllocation;
428}
429
430void
432{
434 m_ehtPpduType = type;
435}
436
437uint8_t
439{
440 return m_ehtPpduType;
441}
442
443bool
445{
446 if (!GetModeInitialized())
447 {
448 return false;
449 }
450 const auto& modeName = m_mode.GetUniqueName();
451 if (m_channelWidth == MHz_u{20})
452 {
453 if (m_nss != 3 && m_nss != 6)
454 {
455 if (modeName == "VhtMcs9")
456 {
457 return false;
458 }
459 }
460 }
461 else if (m_channelWidth == MHz_u{80})
462 {
463 if (m_nss == 3 || m_nss == 7)
464 {
465 if (modeName == "VhtMcs6")
466 {
467 return false;
468 }
469 }
470 else if (m_nss == 6)
471 {
472 if (modeName == "VhtMcs9")
473 {
474 return false;
475 }
476 }
477 }
478 else if (m_channelWidth == MHz_u{160})
479 {
480 if (m_nss == 3)
481 {
482 if (modeName == "VhtMcs9")
483 {
484 return false;
485 }
486 }
487 }
488 else if (m_channelWidth > 160)
489 {
491 {
492 return false;
493 }
494 if ((band == WIFI_PHY_BAND_2_4GHZ) || (band == WIFI_PHY_BAND_5GHZ))
495 {
496 return false;
497 }
498 }
499 for (const auto& userInfo : m_muUserInfos)
500 {
501 if (GetNumStasInRu(userInfo.second.ru) > 8)
502 {
503 return false;
504 }
505 }
506 std::map<WifiRu::RuSpec, uint8_t> streamsPerRu{};
507 for (const auto& info : m_muUserInfos)
508 {
509 auto it = streamsPerRu.find(info.second.ru);
510 if (it == streamsPerRu.end())
511 {
512 streamsPerRu[info.second.ru] = info.second.nss;
513 }
514 else
515 {
516 it->second += info.second.nss;
517 }
518 }
519 for (auto& streams : streamsPerRu)
520 {
521 if (streams.second > 8)
522 {
523 return false;
524 }
525 }
526
527 if (band != WIFI_PHY_BAND_UNSPECIFIED)
528 {
530 "Cannot use OFDM modulation class in the 2.4 GHz band");
532 band != WIFI_PHY_BAND_2_4GHZ,
533 "ERP-OFDM modulation class can only be used in the 2.4 GHz band");
534 }
535
536 return true;
537}
538
539bool
541{
542 return IsDlMu() || IsUlMu();
543}
544
545bool
547{
548 return ns3::IsDlMu(m_preamble) && !(IsEht(m_preamble) && m_ehtPpduType == 1);
549}
550
551bool
553{
554 return ns3::IsUlMu(m_preamble);
555}
556
557bool
559{
560 if (!IsDlMu())
561 {
562 return false;
563 }
564 if (IsEht(m_preamble))
565 {
566 return m_ehtPpduType == 0;
567 }
568 if (m_muUserInfos.size() == 1)
569 {
570 return true;
571 }
572 std::set<WifiRu::RuSpec> rus{};
573 for (const auto& userInfo : m_muUserInfos)
574 {
575 rus.insert(userInfo.second.ru);
576 if (rus.size() > 1)
577 {
578 return true;
579 }
580 }
581 return false;
582}
583
584bool
586{
587 if (!IsDlMu())
588 {
589 return false;
590 }
591 if (IsEht(m_preamble))
592 {
593 return m_ehtPpduType == 2;
594 }
595 if (m_muUserInfos.size() < 2)
596 {
597 return false;
598 }
599 // TODO: mixed OFDMA and MU-MIMO is not supported
600 return !IsDlOfdma();
601}
602
603uint8_t
605{
606 return std::count_if(m_muUserInfos.cbegin(),
607 m_muUserInfos.cend(),
608 [&ru](const auto& info) -> bool { return (ru == info.second.ru); });
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 // SIG-B compression is used in case of full-bandwidth MU-MIMO transmission (27.3.11.8.2
663 // HE-SIG-B content channels in IEEE802.11ax-2021) or if a single RU occupies the whole 160 MHz
664 // bandwidth (27.3.11.8.3 Common field in IEEE802.11ax-2021)
665 return (IsDlMuMimo() && !IsDlOfdma()) ||
666 ((m_muUserInfos.size() == 1) && (m_channelWidth >= MHz_u{160}) &&
667 (WifiRu::GetRuType(m_muUserInfos.cbegin()->second.ru) ==
669}
670
671void
672WifiTxVector::SetInactiveSubchannels(const std::vector<bool>& inactiveSubchannels)
673{
675 "Only HE (or later) authorized for preamble puncturing");
677 m_channelWidth < MHz_u{80},
678 "Preamble puncturing only possible for transmission bandwidth of 80 MHz or larger");
679 NS_ABORT_MSG_IF(!inactiveSubchannels.empty() &&
680 inactiveSubchannels.size() != Count20MHzSubchannels(m_channelWidth),
681 "The size of the inactive subchannnels bitmap should be equal to the number of "
682 "20 MHz subchannels");
683 m_inactiveSubchannels = inactiveSubchannels;
684}
685
686const std::vector<bool>&
691
692void
694{
696 if (IsDlMu())
697 {
698 NS_ASSERT(center26ToneRuIndication == DeriveCenter26ToneRuIndication());
699 }
700 m_center26ToneRuIndication = center26ToneRuIndication;
701}
702
703std::optional<Center26ToneRuIndication>
705{
707 {
708 return std::nullopt;
709 }
710 if (!m_center26ToneRuIndication.has_value())
711 {
713 }
715}
716
717std::ostream&
718operator<<(std::ostream& os, const WifiTxVector& v)
719{
720 if (!v.IsValid())
721 {
722 os << "TXVECTOR not valid";
723 return os;
724 }
725 os << "txpwrlvl: " << +v.GetTxPowerLevel() << " preamble: " << v.GetPreambleType()
726 << " channel width: " << v.GetChannelWidth() << " GI: " << v.GetGuardInterval()
727 << " NTx: " << +v.GetNTx() << " Ness: " << +v.GetNess()
728 << " MPDU aggregation: " << v.IsAggregation() << " STBC: " << v.IsStbc()
729 << " FEC coding: " << (v.IsLdpc() ? "LDPC" : "BCC");
730 if (v.GetPreambleType() >= WIFI_PREAMBLE_HE_SU)
731 {
732 os << " BSS color: " << +v.GetBssColor();
733 }
734 if (v.IsUlMu())
735 {
736 os << " Length: " << v.GetLength();
737 }
738 if (ns3::IsDlMu(v.GetPreambleType()))
739 {
740 os << " SIG-B mode: " << v.GetSigBMode();
741 }
742 if (v.IsMu())
743 {
744 WifiTxVector::HeMuUserInfoMap userInfoMap = v.GetHeMuUserInfoMap();
745 os << " num User Infos: " << userInfoMap.size();
746 for (auto& ui : userInfoMap)
747 {
748 os << ", {STA-ID: " << ui.first << ", " << ui.second.ru << ", MCS: " << +ui.second.mcs
749 << ", Nss: " << +ui.second.nss << "}";
750 }
751 }
752 else
753 {
754 os << " mode: " << v.GetMode() << " Nss: " << +v.GetNss();
755 }
756 const auto& puncturedSubchannels = v.GetInactiveSubchannels();
757 if (!puncturedSubchannels.empty())
758 {
759 os << " Punctured subchannels: ";
760 std::copy(puncturedSubchannels.cbegin(),
761 puncturedSubchannels.cend(),
762 std::ostream_iterator<bool>(os, ", "));
763 }
764 if (IsEht(v.GetPreambleType()))
765 {
766 os << " EHT PPDU type: " << +v.GetEhtPpduType();
767 }
768 return os;
769}
770
771bool
773{
774 return ru == other.ru && mcs == other.mcs && nss == other.nss;
775}
776
777bool
779{
780 return !(*this == other);
781}
782
785{
786 auto heRuComparator = WifiRu::RuSpecCompare(m_channelWidth, p20Index);
787 UserInfoMapOrderedByRus orderedMap{heRuComparator};
788 for (const auto& userInfo : m_muUserInfos)
789 {
790 const auto ru = userInfo.second.ru;
791 if (auto it = orderedMap.find(ru); it != orderedMap.end())
792 {
793 it->second.emplace(userInfo.first);
794 }
795 else
796 {
797 orderedMap.emplace(ru, std::set<uint16_t>{userInfo.first});
798 }
799 }
800 return orderedMap;
801}
802
804WifiTxVector::DeriveRuAllocation(uint8_t p20Index) const
805{
806 const auto mc = GetModulationClass();
807 const auto emptyRu =
809 RuAllocation ruAllocations(Count20MHzSubchannels(m_channelWidth), emptyRu);
810 std::vector<RuType> ruTypes{};
811 ruTypes.resize(ruAllocations.size());
812 const auto& orderedMap = GetUserInfoMapOrderedByRus(p20Index);
813 std::pair<std::size_t /* number of RUs in content channel 1 */,
814 std::size_t /* number of RUs in content channel 2 */>
815 ccSizes{0, 0};
816 for (const auto& [ru, staIds] : orderedMap)
817 {
818 const auto ruType = WifiRu::GetRuType(ru);
819 auto ruIndex = WifiRu::GetPhyIndex(ru, m_channelWidth, p20Index);
820 if ((ruType == RuType::RU_26_TONE) && (ruIndex == 19))
821 {
822 continue;
823 }
824 const auto ruBw = WifiRu::GetBandwidth(ruType);
825 const auto rusPerSubchannel =
826 WifiRu::GetRusOfType(ruBw > MHz_u{20} ? ruBw : MHz_u{20}, ruType, mc);
827 if ((m_channelWidth >= MHz_u{80}) && (ruIndex > 19))
828 {
829 // "ignore" the center 26-tone RUs in 80 MHz channels
830 ruIndex--;
831 if (ruIndex > 37)
832 {
833 ruIndex -= (ruIndex - 19) / 37;
834 }
835 }
836 const auto numSubchannelsForRu = (ruBw < MHz_u{20}) ? 1 : Count20MHzSubchannels(ruBw);
837 const auto index = (ruBw < MHz_u{20}) ? ((ruIndex - 1) / rusPerSubchannel.size())
838 : ((ruIndex - 1) * numSubchannelsForRu);
840 auto ruAlloc = WifiRu::GetEqualizedRuAllocation(ruType, false, true, mc);
841 if (ruAllocations.at(index) != emptyRu)
842 {
843 if (ruType == ruTypes.at(index))
844 {
845 continue;
846 }
847 if (ruType == RuType::RU_26_TONE)
848 {
849 ruAlloc = WifiRu::GetEqualizedRuAllocation(ruTypes.at(index), true, true, mc);
850 }
851 else if (ruTypes.at(index) == RuType::RU_26_TONE)
852 {
853 ruAlloc = WifiRu::GetEqualizedRuAllocation(ruType, true, true, mc);
854 }
855 else
856 {
857 NS_ASSERT_MSG(false, "unsupported RU combination");
858 }
859 }
860 std::size_t ccIndex;
861 if (ruType >= RuType::RU_484_TONE)
862 {
863 ccIndex = (ccSizes.first <= ccSizes.second) ? 0 : 1;
864 }
865 else
866 {
867 ccIndex = (index % 2 == 0) ? 0 : 1;
868 }
869 if (ccIndex == 0)
870 {
871 ccSizes.first += staIds.size();
872 }
873 else
874 {
875 ccSizes.second += staIds.size();
876 }
877 for (std::size_t i = 0; i < numSubchannelsForRu; ++i)
878 {
879 auto ruAllocNoUsers = WifiRu::GetEqualizedRuAllocation(ruType, false, false, mc);
880 ruTypes.at(index + i) = ruType;
881 ruAllocations.at(index + i) =
882 (IsSigBCompression() || ((index + i) % 2) == ccIndex) ? ruAlloc : ruAllocNoUsers;
883 }
884 }
885 return ruAllocations;
886}
887
890{
891 uint8_t center26ToneRuIndication{0};
892 for (const auto& userInfo : m_muUserInfos)
893 {
894 NS_ASSERT(WifiRu::IsHe(userInfo.second.ru));
895 if ((WifiRu::GetRuType(userInfo.second.ru) == RuType::RU_26_TONE) &&
896 (WifiRu::GetIndex(userInfo.second.ru) == 19))
897 {
898 center26ToneRuIndication |=
899 (std::get<HeRu::RuSpec>(userInfo.second.ru).GetPrimary80MHz())
902 }
903 }
904 return static_cast<Center26ToneRuIndication>(center26ToneRuIndication);
905}
906
907} // namespace ns3
uint32_t v
PHY entity for EHT (11be).
Definition eht-phy.h:37
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
Definition eht-phy.cc:255
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition he-phy.cc:1557
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
represent a single transmission mode
Definition wifi-mode.h:38
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:172
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:1405
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_PHY_BAND_5GHZ
The 5 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.
static constexpr uint8_t EMPTY_242_TONE_HE_RU
Empty 242-tone RU identifier for HE (Section 26.11.7 802.11ax-2021).
bool IsEht(WifiPreamble preamble)
Return true if a preamble corresponds to an EHT transmission.
static constexpr uint8_t WIFI_MIN_TX_PWR_LEVEL
minimum TX power level value
static constexpr uint8_t UNASSIGNED_242_TONE_EHT_RU
Unassigned 242-tone RU identifier for EHT (Table Table 36-34 IEEE 802.11be D7.0).
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:145
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.
std::ostream & operator<<(std::ostream &os, const PairObject &obj)
Stream insertion operator.
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: