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
14#include "ns3/abort.h"
15#include "ns3/eht-phy.h"
16
17#include <algorithm>
18#include <iterator>
19#include <numeric>
20#include <set>
21
22namespace ns3
23{
24
26 : m_txPowerLevel(1),
27 m_preamble(WIFI_PREAMBLE_LONG),
28 m_channelWidth(20),
29 m_guardInterval(NanoSeconds(800)),
30 m_nTx(1),
31 m_nss(1),
32 m_ness(0),
33 m_aggregation(false),
34 m_stbc(false),
35 m_ldpc(false),
36 m_bssColor(0),
37 m_length(0),
38 m_triggerResponding(false),
39 m_modeInitialized(false),
40 m_inactiveSubchannels(),
41 m_ruAllocation(),
42 m_center26ToneRuIndication(std::nullopt),
43 m_ehtPpduType(1) // SU transmission by default
44{
45}
46
48 uint8_t powerLevel,
49 WifiPreamble preamble,
50 Time guardInterval,
51 uint8_t nTx,
52 uint8_t nss,
53 uint8_t ness,
54 MHz_u channelWidth,
55 bool aggregation,
56 bool stbc,
57 bool ldpc,
58 uint8_t bssColor,
59 uint16_t length,
60 bool triggerResponding)
61 : m_mode(mode),
62 m_txPowerLevel(powerLevel),
63 m_preamble(preamble),
64 m_channelWidth(channelWidth),
65 m_guardInterval(guardInterval),
66 m_nTx(nTx),
67 m_nss(nss),
68 m_ness(ness),
69 m_aggregation(aggregation),
70 m_stbc(stbc),
71 m_ldpc(ldpc),
72 m_bssColor(bssColor),
73 m_length(length),
74 m_triggerResponding(triggerResponding),
75 m_modeInitialized(true),
76 m_inactiveSubchannels(),
77 m_ruAllocation(),
78 m_center26ToneRuIndication(std::nullopt),
79 m_ehtPpduType(1) // SU transmission by default
80{
81}
82
84 : m_mode(txVector.m_mode),
85 m_txPowerLevel(txVector.m_txPowerLevel),
86 m_preamble(txVector.m_preamble),
87 m_channelWidth(txVector.m_channelWidth),
88 m_guardInterval(txVector.m_guardInterval),
89 m_nTx(txVector.m_nTx),
90 m_nss(txVector.m_nss),
91 m_ness(txVector.m_ness),
92 m_aggregation(txVector.m_aggregation),
93 m_stbc(txVector.m_stbc),
94 m_ldpc(txVector.m_ldpc),
95 m_bssColor(txVector.m_bssColor),
96 m_length(txVector.m_length),
97 m_triggerResponding(txVector.m_triggerResponding),
98 m_modeInitialized(txVector.m_modeInitialized),
99 m_inactiveSubchannels(txVector.m_inactiveSubchannels),
100 m_sigBMcs(txVector.m_sigBMcs),
101 m_ruAllocation(txVector.m_ruAllocation),
102 m_center26ToneRuIndication(txVector.m_center26ToneRuIndication),
103 m_ehtPpduType(txVector.m_ehtPpduType)
104{
105 m_muUserInfos.clear();
106 if (!txVector.m_muUserInfos.empty()) // avoids crashing for loop
107 {
108 for (auto& info : txVector.m_muUserInfos)
109 {
110 m_muUserInfos.insert(std::make_pair(info.first, info.second));
111 }
112 }
113}
114
115bool
120
122WifiTxVector::GetMode(uint16_t staId) const
123{
125 {
126 NS_FATAL_ERROR("WifiTxVector mode must be set before using");
127 }
128 if (!IsMu())
129 {
130 return m_mode;
131 }
132 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
133 const auto userInfoIt = m_muUserInfos.find(staId);
134 NS_ASSERT(userInfoIt != m_muUserInfos.cend());
136 {
138 return EhtPhy::GetEhtMcs(userInfoIt->second.mcs);
140 return HePhy::GetHeMcs(userInfoIt->second.mcs);
141 default:
142 NS_ABORT_MSG("Unsupported modulation class: " << GetModulationClassForPreamble(m_preamble));
143 }
144 return WifiMode(); // invalid WifiMode
145}
146
149{
150 NS_ABORT_MSG_IF(!m_modeInitialized, "WifiTxVector mode must be set before using");
151
152 if (IsMu())
153 {
154 NS_ASSERT(!m_muUserInfos.empty());
155 // all the modes belong to the same modulation class
157 }
158 return m_mode.GetModulationClass();
159}
160
161uint8_t
163{
164 return m_txPowerLevel;
165}
166
169{
170 return m_preamble;
171}
172
173MHz_u
175{
176 return m_channelWidth;
177}
178
179Time
184
185uint8_t
187{
188 return m_nTx;
189}
190
191uint8_t
192WifiTxVector::GetNss(uint16_t staId) const
193{
194 if (IsMu())
195 {
196 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
197 NS_ASSERT(m_muUserInfos.contains(staId));
198 return m_muUserInfos.at(staId).nss;
199 }
200 return m_nss;
201}
202
203uint8_t
205{
206 // We do not support mixed OFDMA and MU-MIMO
207 uint8_t nss = 0;
208 if (IsMu())
209 {
210 for (const auto& info : m_muUserInfos)
211 {
212 nss = (nss < info.second.nss) ? info.second.nss : nss;
213 }
214 }
215 else
216 {
217 nss = m_nss;
218 }
219 return nss;
220}
221
222uint8_t
224{
225 // We do not support mixed OFDMA and MU-MIMO
226 uint8_t nss = 0;
227 if (IsMu())
228 {
229 nss = std::accumulate(
230 m_muUserInfos.cbegin(),
231 m_muUserInfos.cend(),
232 0,
233 [](uint8_t prevNss, const auto& info) { return prevNss + info.second.nss; });
234 }
235 else
236 {
237 nss = m_nss;
238 }
239 return nss;
240}
241
242uint8_t
244{
245 return m_ness;
246}
247
248bool
250{
251 return m_aggregation;
252}
253
254bool
256{
257 return m_stbc;
258}
259
260bool
262{
263 return m_ldpc;
264}
265
266bool
268{
269 return ((m_channelWidth >= 40) && !IsMu() && (GetModulationClass() < WIFI_MOD_CLASS_HT));
270}
271
272void
274{
275 m_mode = mode;
276 m_modeInitialized = true;
277}
278
279void
280WifiTxVector::SetMode(WifiMode mode, uint16_t staId)
281{
282 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
283 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
284 m_muUserInfos[staId].mcs = mode.GetMcsValue();
285 m_modeInitialized = true;
286}
287
288void
290{
291 m_txPowerLevel = powerlevel;
292}
293
294void
296{
297 m_preamble = preamble;
298}
299
300void
302{
303 m_channelWidth = channelWidth;
304}
305
306void
308{
309 m_guardInterval = guardInterval;
310}
311
312void
314{
315 m_nTx = nTx;
316}
317
318void
320{
321 m_nss = nss;
322}
323
324void
325WifiTxVector::SetNss(uint8_t nss, uint16_t staId)
326{
327 NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
328 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
329 m_muUserInfos[staId].nss = nss;
330}
331
332void
334{
335 m_ness = ness;
336}
337
338void
340{
341 m_aggregation = aggregation;
342}
343
344void
346{
347 m_stbc = stbc;
348}
349
350void
352{
353 m_ldpc = ldpc;
354}
355
356void
358{
359 m_bssColor = color;
360}
361
362uint8_t
364{
365 return m_bssColor;
366}
367
368void
370{
371 m_length = length;
372}
373
374uint16_t
376{
377 return m_length;
378}
379
380bool
385
386void
388{
389 m_triggerResponding = triggerResponding;
390}
391
392void
394{
395 m_sigBMcs = mode;
396}
397
400{
401 return m_sigBMcs;
402}
403
404void
405WifiTxVector::SetRuAllocation(const RuAllocation& ruAlloc, uint8_t p20Index)
406{
407 if (ns3::IsDlMu(m_preamble) && !m_muUserInfos.empty())
408 {
409 NS_ASSERT(ruAlloc == DeriveRuAllocation(p20Index));
410 }
411 m_ruAllocation = ruAlloc;
412}
413
414const RuAllocation&
415WifiTxVector::GetRuAllocation(uint8_t p20Index) const
416{
417 if (ns3::IsDlMu(m_preamble) && m_ruAllocation.empty())
418 {
420 }
421 return m_ruAllocation;
422}
423
424void
426{
428 m_ehtPpduType = type;
429}
430
431uint8_t
433{
434 return m_ehtPpduType;
435}
436
437bool
439{
440 if (!GetModeInitialized())
441 {
442 return false;
443 }
444 const auto& modeName = m_mode.GetUniqueName();
445 if (m_channelWidth == 20)
446 {
447 if (m_nss != 3 && m_nss != 6)
448 {
449 if (modeName == "VhtMcs9")
450 {
451 return false;
452 }
453 }
454 }
455 else if (m_channelWidth == 80)
456 {
457 if (m_nss == 3 || m_nss == 7)
458 {
459 if (modeName == "VhtMcs6")
460 {
461 return false;
462 }
463 }
464 else if (m_nss == 6)
465 {
466 if (modeName == "VhtMcs9")
467 {
468 return false;
469 }
470 }
471 }
472 else if (m_channelWidth == 160)
473 {
474 if (m_nss == 3)
475 {
476 if (modeName == "VhtMcs9")
477 {
478 return false;
479 }
480 }
481 }
482 for (const auto& userInfo : m_muUserInfos)
483 {
484 if (GetNumStasInRu(userInfo.second.ru) > 8)
485 {
486 return false;
487 }
488 }
489 std::map<HeRu::RuSpec, uint8_t> streamsPerRu{};
490 for (const auto& info : m_muUserInfos)
491 {
492 auto it = streamsPerRu.find(info.second.ru);
493 if (it == streamsPerRu.end())
494 {
495 streamsPerRu[info.second.ru] = info.second.nss;
496 }
497 else
498 {
499 it->second += info.second.nss;
500 }
501 }
502 for (auto& streams : streamsPerRu)
503 {
504 if (streams.second > 8)
505 {
506 return false;
507 }
508 }
509
510 if (band != WIFI_PHY_BAND_UNSPECIFIED)
511 {
513 "Cannot use OFDM modulation class in the 2.4 GHz band");
515 band != WIFI_PHY_BAND_2_4GHZ,
516 "ERP-OFDM modulation class can only be used in the 2.4 GHz band");
517 }
518
519 return true;
520}
521
522bool
524{
525 return IsDlMu() || IsUlMu();
526}
527
528bool
530{
531 return ns3::IsDlMu(m_preamble) && !(IsEht(m_preamble) && m_ehtPpduType == 1);
532}
533
534bool
536{
537 return ns3::IsUlMu(m_preamble);
538}
539
540bool
542{
543 if (!IsDlMu())
544 {
545 return false;
546 }
547 if (IsEht(m_preamble))
548 {
549 return m_ehtPpduType == 0;
550 }
551 if (m_muUserInfos.size() == 1)
552 {
553 return true;
554 }
555 std::set<HeRu::RuSpec> rus{};
556 for (const auto& userInfo : m_muUserInfos)
557 {
558 rus.insert(userInfo.second.ru);
559 if (rus.size() > 1)
560 {
561 return true;
562 }
563 }
564 return false;
565}
566
567bool
569{
570 if (!IsDlMu())
571 {
572 return false;
573 }
574 if (IsEht(m_preamble))
575 {
576 return m_ehtPpduType == 2;
577 }
578 if (m_muUserInfos.size() < 2)
579 {
580 return false;
581 }
582 // TODO: mixed OFDMA and MU-MIMO is not supported
583 return !IsDlOfdma();
584}
585
586uint8_t
588{
589 return std::count_if(m_muUserInfos.cbegin(),
590 m_muUserInfos.cend(),
591 [&ru](const auto& info) -> bool { return (ru == info.second.ru); });
592}
593
594bool
595WifiTxVector::IsAllocated(uint16_t staId) const
596{
597 return m_muUserInfos.contains(staId);
598}
599
601WifiTxVector::GetRu(uint16_t staId) const
602{
603 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
604 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
605 return m_muUserInfos.at(staId).ru;
606}
607
608void
610{
611 NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
612 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
613 m_muUserInfos[staId].ru = ru;
614}
615
617WifiTxVector::GetHeMuUserInfo(uint16_t staId) const
618{
619 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
620 return m_muUserInfos.at(staId);
621}
622
623void
625{
626 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
627 NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
628 m_muUserInfos[staId] = userInfo;
629 m_modeInitialized = true;
630 m_ruAllocation.clear();
631}
632
635{
636 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
637 return m_muUserInfos;
638}
639
642{
643 NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
644 m_ruAllocation.clear();
645 return m_muUserInfos;
646}
647
648bool
650{
651 return IsDlMuMimo() && !IsDlOfdma();
652}
653
654void
655WifiTxVector::SetInactiveSubchannels(const std::vector<bool>& inactiveSubchannels)
656{
658 "Only HE (or later) authorized for preamble puncturing");
660 m_channelWidth < 80,
661 "Preamble puncturing only possible for transmission bandwidth of 80 MHz or larger");
662 [[maybe_unused]] const std::size_t num20MhzSubchannels = m_channelWidth / 20;
663 NS_ABORT_MSG_IF(!inactiveSubchannels.empty() &&
664 inactiveSubchannels.size() != num20MhzSubchannels,
665 "The size of the inactive subchannnels bitmap should be equal to the number of "
666 "20 MHz subchannels");
667 m_inactiveSubchannels = inactiveSubchannels;
668}
669
670const std::vector<bool>&
675
676void
678{
679 if (IsDlMu())
680 {
681 NS_ASSERT(center26ToneRuIndication == DeriveCenter26ToneRuIndication());
682 }
683 m_center26ToneRuIndication = center26ToneRuIndication;
684}
685
686std::optional<Center26ToneRuIndication>
688{
689 if (!IsDlMu() || (m_channelWidth < 80))
690 {
691 return std::nullopt;
692 }
693 if (!m_center26ToneRuIndication.has_value())
694 {
696 }
698}
699
700std::ostream&
701operator<<(std::ostream& os, const WifiTxVector& v)
702{
703 if (!v.IsValid())
704 {
705 os << "TXVECTOR not valid";
706 return os;
707 }
708 os << "txpwrlvl: " << +v.GetTxPowerLevel() << " preamble: " << v.GetPreambleType()
709 << " channel width: " << v.GetChannelWidth() << " GI: " << v.GetGuardInterval()
710 << " NTx: " << +v.GetNTx() << " Ness: " << +v.GetNess()
711 << " MPDU aggregation: " << v.IsAggregation() << " STBC: " << v.IsStbc()
712 << " FEC coding: " << (v.IsLdpc() ? "LDPC" : "BCC");
714 {
715 os << " BSS color: " << +v.GetBssColor();
716 }
717 if (v.IsUlMu())
718 {
719 os << " Length: " << v.GetLength();
720 }
722 {
723 os << " SIG-B mode: " << v.GetSigBMode();
724 }
725 if (v.IsMu())
726 {
728 os << " num User Infos: " << userInfoMap.size();
729 for (auto& ui : userInfoMap)
730 {
731 os << ", {STA-ID: " << ui.first << ", " << ui.second.ru << ", MCS: " << +ui.second.mcs
732 << ", Nss: " << +ui.second.nss << "}";
733 }
734 }
735 else
736 {
737 os << " mode: " << v.GetMode() << " Nss: " << +v.GetNss();
738 }
739 const auto& puncturedSubchannels = v.GetInactiveSubchannels();
740 if (!puncturedSubchannels.empty())
741 {
742 os << " Punctured subchannels: ";
743 std::copy(puncturedSubchannels.cbegin(),
744 puncturedSubchannels.cend(),
745 std::ostream_iterator<bool>(os, ", "));
746 }
747 if (IsEht(v.GetPreambleType()))
748 {
749 os << " EHT PPDU type: " << +v.GetEhtPpduType();
750 }
751 return os;
752}
753
754bool
756{
757 return ru == other.ru && mcs == other.mcs && nss == other.nss;
758}
759
760bool
762{
763 return !(*this == other);
764}
765
768{
769 auto heRuComparator = HeRu::RuSpecCompare(m_channelWidth, p20Index);
770 UserInfoMapOrderedByRus orderedMap{heRuComparator};
771 for (const auto& userInfo : m_muUserInfos)
772 {
773 const auto ru = userInfo.second.ru;
774 if (auto it = orderedMap.find(ru); it != orderedMap.end())
775 {
776 it->second.emplace(userInfo.first);
777 }
778 else
779 {
780 orderedMap.emplace(userInfo.second.ru, std::set<uint16_t>{userInfo.first});
781 }
782 }
783 return orderedMap;
784}
785
786RuAllocation
787WifiTxVector::DeriveRuAllocation(uint8_t p20Index) const
788{
789 RuAllocation ruAllocations(m_channelWidth / 20, HeRu::EMPTY_242_TONE_RU);
790 std::vector<HeRu::RuType> ruTypes{};
791 ruTypes.resize(ruAllocations.size());
792 const auto& orderedMap = GetUserInfoMapOrderedByRus(p20Index);
793 for (const auto& [ru, staIds] : orderedMap)
794 {
795 const auto ruType = ru.GetRuType();
796 const auto ruBw = HeRu::GetBandwidth(ruType);
797 const auto isPrimary80MHz = ru.GetPrimary80MHz();
798 const auto rusPerSubchannel = HeRu::GetRusOfType(ruBw > 20 ? ruBw : 20, ruType);
799 auto ruIndex = ru.GetIndex();
800 if ((m_channelWidth >= 80) && (ruIndex > 19))
801 {
802 // take into account the center 26-tone RU in the primary 80 MHz
803 ruIndex--;
804 }
805 if ((!isPrimary80MHz) && (ruIndex > 19))
806 {
807 // take into account the center 26-tone RU in the secondary 80 MHz
808 ruIndex--;
809 }
810 if (!isPrimary80MHz && (ruType != HeRu::RU_2x996_TONE))
811 {
812 NS_ASSERT(m_channelWidth > 80);
813 // adjust RU index for the secondary 80 MHz: in that case index is restarting at 1,
814 // hence we need to add an offset corresponding to the number of RUs of the same type in
815 // the primary 80 MHz
816 ruIndex += HeRu::GetRusOfType(80, ruType).size();
817 }
818 const auto index =
819 (ruBw < 20) ? ((ruIndex - 1) / rusPerSubchannel.size()) : ((ruIndex - 1) * (ruBw / 20));
820 const auto numSubchannelsForRu = (ruBw < 20) ? 1 : (ruBw / 20);
821 [[maybe_unused]] const std::size_t num20MhzSubchannels = m_channelWidth / 20;
822 NS_ABORT_IF(index >= num20MhzSubchannels);
823 auto ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, false);
824 if (ruAllocations.at(index) != HeRu::EMPTY_242_TONE_RU)
825 {
826 if (ruType == ruTypes.at(index))
827 {
828 continue;
829 }
830 if (ruType == HeRu::RU_26_TONE)
831 {
832 ruAlloc = HeRu::GetEqualizedRuAllocation(ruTypes.at(index), true);
833 }
834 else if (ruTypes.at(index) == HeRu::RU_26_TONE)
835 {
836 ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, true);
837 }
838 else
839 {
840 NS_ASSERT_MSG(false, "unsupported RU combination");
841 }
842 }
843 for (auto i = 0; i < numSubchannelsForRu; ++i)
844 {
845 ruTypes.at(index + i) = ruType;
846 ruAllocations.at(index + i) = ruAlloc;
847 }
848 }
849 return ruAllocations;
850}
851
853WifiTxVector::DeriveCenter26ToneRuIndication() const
854{
855 uint8_t center26ToneRuIndication{0};
856 for (const auto& userInfo : m_muUserInfos)
857 {
858 if ((userInfo.second.ru.GetRuType() == HeRu::RU_26_TONE) &&
859 (userInfo.second.ru.GetIndex() == 19))
860 {
861 center26ToneRuIndication |= (userInfo.second.ru.GetPrimary80MHz())
864 }
865 }
866 return static_cast<Center26ToneRuIndication>(center26ToneRuIndication);
867}
868
869} // 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:1573
RU Specification.
Definition he-ru.h:57
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:137
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:174
uint8_t GetMcsValue() const
Definition wifi-mode.cc:152
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.
uint8_t GetNumStasInRu(const HeRu::RuSpec &ru) const
Get the number of STAs in a given RU.
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
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.
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.
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.
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
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.
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
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:1344
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.
bool IsDlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a downlink multi-user transmission.
std::vector< uint8_t > RuAllocation
8 bit RU_ALLOCATION per 20 MHz
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:132
Declaration of the following enums: