16#include "ns3/eht-phy.h"
29 m_channelWidth(
MHz_u{20}),
39 m_triggerResponding(false),
40 m_modeInitialized(false),
41 m_inactiveSubchannels(),
43 m_center26ToneRuIndication(
std::nullopt),
61 bool triggerResponding)
63 m_txPowerLevel(powerLevel),
65 m_channelWidth(channelWidth),
66 m_guardInterval(guardInterval),
70 m_aggregation(aggregation),
75 m_triggerResponding(triggerResponding),
76 m_modeInitialized(true),
77 m_inactiveSubchannels(),
79 m_center26ToneRuIndication(
std::nullopt),
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)
111 m_muUserInfos.insert(std::make_pair(info.first, info.second));
133 NS_ABORT_MSG_IF(staId > 2048,
"STA-ID should be correctly set for MU (" << staId <<
")");
197 NS_ABORT_MSG_IF(staId > 2048,
"STA-ID should be correctly set for MU (" << staId <<
")");
213 nss = (nss < info.second.nss) ? info.second.nss : nss;
230 nss = std::accumulate(
234 [](uint8_t prevNss,
const auto& info) { return prevNss + info.second.nss; });
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 "
332 NS_ABORT_MSG_IF(staId > 2048,
"STA-ID should be correctly set for MU");
453 if (modeName ==
"VhtMcs9")
463 if (modeName ==
"VhtMcs6")
470 if (modeName ==
"VhtMcs9")
480 if (modeName ==
"VhtMcs9")
493 std::map<HeRu::RuSpec, uint8_t> streamsPerRu{};
496 auto it = streamsPerRu.find(info.second.ru);
497 if (it == streamsPerRu.end())
499 streamsPerRu[info.second.ru] = info.second.nss;
503 it->second += info.second.nss;
506 for (
auto& streams : streamsPerRu)
508 if (streams.second > 8)
517 "Cannot use OFDM modulation class in the 2.4 GHz band");
520 "ERP-OFDM modulation class can only be used in the 2.4 GHz band");
559 std::set<HeRu::RuSpec> rus{};
562 rus.insert(userInfo.second.ru);
595 [&ru](
const auto& info) ->
bool { return (ru == info.second.ru); });
602 NS_ABORT_MSG_IF(staId > 2048,
"STA-ID should be correctly set for MU");
610 NS_ABORT_MSG_IF(staId > 2048,
"STA-ID should be correctly set for MU");
625 NS_ABORT_MSG_IF(staId > 2048,
"STA-ID should be correctly set for MU");
661 "Only HE (or later) authorized for preamble puncturing");
664 "Preamble puncturing only possible for transmission bandwidth of 80 MHz or larger");
667 "The size of the inactive subchannnels bitmap should be equal to the number of "
668 "20 MHz subchannels");
672const std::vector<bool>&
688std::optional<Center26ToneRuIndication>
707 os <<
"TXVECTOR not valid";
714 <<
" FEC coding: " << (v.
IsLdpc() ?
"LDPC" :
"BCC");
730 os <<
" num User Infos: " << userInfoMap.size();
731 for (
auto& ui : userInfoMap)
733 os <<
", {STA-ID: " << ui.first <<
", " << ui.second.ru <<
", MCS: " << +ui.second.mcs
734 <<
", Nss: " << +ui.second.nss <<
"}";
742 if (!puncturedSubchannels.empty())
744 os <<
" Punctured subchannels: ";
745 std::copy(puncturedSubchannels.cbegin(),
746 puncturedSubchannels.cend(),
747 std::ostream_iterator<bool>(os,
", "));
765 return !(*
this == other);
775 const auto ru = userInfo.second.ru;
776 if (
auto it = orderedMap.find(ru); it != orderedMap.end())
778 it->second.emplace(userInfo.first);
782 orderedMap.emplace(userInfo.second.ru, std::set<uint16_t>{userInfo.first});
789WifiTxVector::DeriveRuAllocation(uint8_t p20Index)
const
792 std::vector<HeRu::RuType> ruTypes{};
793 ruTypes.resize(ruAllocations.size());
794 const auto& orderedMap = GetUserInfoMapOrderedByRus(p20Index);
795 std::pair<std::size_t ,
798 for (
const auto& [ru, staIds] : orderedMap)
800 if ((ru.GetRuType() == HeRu::RU_26_TONE) && (ru.GetIndex() == 19))
804 const auto ruType = ru.GetRuType();
805 const auto ruBw = HeRu::GetBandwidth(ruType);
806 const auto rusPerSubchannel =
807 HeRu::GetRusOfType(ruBw >
MHz_u{20} ? ruBw :
MHz_u{20}, ruType);
808 auto ruIndex = ru.GetIndex();
809 if ((m_channelWidth >=
MHz_u{80}) && (ruIndex > 19))
814 const auto isPrimary80MHz = ru.GetPrimary80MHz();
815 const auto primary80IsLower80 = (p20Index < m_channelWidth /
MHz_u{40});
817 (primary80IsLower80 && isPrimary80MHz) || (!primary80IsLower80 && !isPrimary80MHz);
818 if ((m_channelWidth >
MHz_u{80}) && !isLow80 && (ruIndex > 19))
823 if ((m_channelWidth >
MHz_u{80}) && !isLow80 && (ruType != HeRu::GetRuType(m_channelWidth)))
828 ruIndex += HeRu::GetRusOfType(
MHz_u{80}, ruType).size();
831 const auto index = (ruBw <
MHz_u{20}) ? ((ruIndex - 1) / rusPerSubchannel.size())
832 : ((ruIndex - 1) * numSubchannelsForRu);
834 auto ruAlloc = HeRu::GetEqualizedRuAllocation(ruType,
false,
true);
835 if (ruAllocations.at(index) != HeRu::EMPTY_242_TONE_RU)
837 if (ruType == ruTypes.at(index))
841 if (ruType == HeRu::RU_26_TONE)
843 ruAlloc = HeRu::GetEqualizedRuAllocation(ruTypes.at(index),
true,
true);
845 else if (ruTypes.at(index) == HeRu::RU_26_TONE)
847 ruAlloc = HeRu::GetEqualizedRuAllocation(ruType,
true,
true);
855 if (ruType >= HeRu::RU_484_TONE)
857 ccIndex = (ccSizes.first <= ccSizes.second) ? 0 : 1;
861 ccIndex = (index % 2 == 0) ? 0 : 1;
865 ccSizes.first += staIds.size();
869 ccSizes.second += staIds.size();
871 for (std::size_t i = 0; i < numSubchannelsForRu; ++i)
873 auto ruAllocNoUsers = HeRu::GetEqualizedRuAllocation(ruType,
false,
false);
874 ruTypes.at(index + i) = ruType;
875 ruAllocations.at(index + i) =
876 (IsSigBCompression() || ((index + i) % 2) == ccIndex) ? ruAlloc : ruAllocNoUsers;
879 return ruAllocations;
883WifiTxVector::DeriveCenter26ToneRuIndication()
const
885 uint8_t center26ToneRuIndication{0};
886 for (
const auto& userInfo : m_muUserInfos)
888 if ((userInfo.second.ru.GetRuType() == HeRu::RU_26_TONE) &&
889 (userInfo.second.ru.GetIndex() == 19))
891 center26ToneRuIndication |= (userInfo.second.ru.GetPrimary80MHz())
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
static RuType GetRuType(MHz_u bandwidth)
Get the RU corresponding to the approximate bandwidth.
Simulation virtual time values and global simulation resolution.
represent a single transmission mode
const std::string & GetUniqueName() const
WifiModulationClass GetModulationClass() const
uint8_t GetMcsValue() const
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
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.
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 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,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#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.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
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....
@ 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)
double MHz_u
MHz weak type.
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.
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
HE MU specific user transmission parameters.
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.
Declaration of the following enums: