16#include "ns3/wifi-phy-operating-channel.h"
17#include "ns3/wifi-phy.h"
18#include "ns3/wifi-psdu.h"
19#include "ns3/wifi-utils.h"
35 return (os <<
"PSD_NON_HE_PORTION");
37 return (os <<
"PSD_HE_PORTION");
40 return (os <<
"INVALID");
50 bool instantiateHeaders )
58 NS_LOG_FUNCTION(
this << psdus << txVector << channel << ppduDuration << uid << flag
59 << instantiateHeaders);
62 m_psdus.begin()->second =
nullptr;
65 if (instantiateHeaders)
76 bool instantiateHeaders )
84 NS_LOG_FUNCTION(
this << psdu << txVector << channel << ppduDuration << uid
85 << instantiateHeaders);
87 if (instantiateHeaders)
104 uint8_t sigExtension = 0;
110 uint8_t m =
IsDlMu() ? 1 : 2;
111 uint16_t length = ((ceil((
static_cast<double>(ppduDuration.
GetNanoSeconds() - (20 * 1000) -
112 (sigExtension * 1000)) /
128 .m_bssColor = bssColor,
134 const uint8_t noMuMimoUsers{0};
136 .m_bssColor = bssColor,
147 .m_center26ToneRuIndication =
157 .m_bssColor = bssColor,
182 auto heSigHeader = std::get_if<HeSuSigHeader>(&
m_heSig);
183 NS_ASSERT(heSigHeader && (heSigHeader->m_format == 1));
192 auto heSigHeader = std::get_if<HeTbSigHeader>(&
m_heSig);
193 NS_ASSERT(heSigHeader && (heSigHeader->m_format == 0));
199 auto heSigHeader = std::get_if<HeMuSigHeader>(&
m_heSig);
206 heSigHeader->m_ruAllocation,
207 heSigHeader->m_center26ToneRuIndication,
208 heSigHeader->m_contentChannels,
209 heSigHeader->m_sigBCompression,
214 if (heSigHeader->m_center26ToneRuIndication.has_value())
218 if (heSigHeader->m_sigBCompression)
229 auto isPrimary80{
true};
230 auto index{phyIndex};
233 const auto isLow80 = ruAllocIndex < 4;
235 const auto primary80IsLower80 = (p20Index < bw /
MHz_u{40});
241 isPrimary80 = ((primary80IsLower80 && isLow80) || (!primary80IsLower80 && !isLow80));
254 std::optional<Center26ToneRuIndication> center26ToneRuIndication,
256 bool sigBcompression,
257 uint8_t numMuMimoUsers)
const
260 std::vector<uint8_t> remainingRuAllocIndices(ruAllocation.size());
261 std::iota(remainingRuAllocIndices.begin(), remainingRuAllocIndices.end(), 0);
262 std::size_t contentChannelIndex = 0;
263 std::size_t ruAllocIndex = 0;
264 for (
const auto& contentChannel : contentChannels)
266 std::size_t numRusLeft = 0;
267 std::size_t numUsersLeft = 0;
268 ruAllocIndex = remainingRuAllocIndices.front();
269 std::size_t numUsersLeftInCc = contentChannel.size();
270 if (contentChannel.empty())
272 const auto pos = std::find(remainingRuAllocIndices.cbegin(),
273 remainingRuAllocIndices.cend(),
275 remainingRuAllocIndices.erase(pos);
276 ++contentChannelIndex;
279 for (
const auto& userInfo : contentChannel)
281 if (center26ToneRuIndication && (numUsersLeftInCc == 1))
284 if ((contentChannelIndex == 0) &&
285 ((*center26ToneRuIndication ==
287 (*center26ToneRuIndication ==
292 {HeRu::RuSpec{RuType::RU_26_TONE, 19, true}, userInfo.mcs, userInfo.nss});
295 else if ((contentChannelIndex == 1) &&
296 ((*center26ToneRuIndication ==
298 (*center26ToneRuIndication ==
304 {HeRu::RuSpec{RuType::RU_26_TONE, 19, false}, userInfo.mcs, userInfo.nss});
308 NS_ASSERT(ruAllocIndex < ruAllocation.size());
310 while (ruSpecs.empty() && (ruAllocIndex < ruAllocation.size()))
312 const auto pos = std::find(remainingRuAllocIndices.cbegin(),
313 remainingRuAllocIndices.cend(),
315 remainingRuAllocIndices.erase(pos);
317 NS_ASSERT(ruAllocIndex < ruAllocation.size());
322 numRusLeft = ruSpecs.size();
324 if (numUsersLeft == 0)
328 numUsersLeft = numMuMimoUsers;
336 auto ruIndex = (ruSpecs.size() - numRusLeft);
337 const auto ruSpec = ruSpecs.at(ruIndex);
344 const auto num20MhzSubchannelsInRu =
348 const std::size_t numRus =
350 const std::size_t ruIndexOffset = (ruBw <
MHz_u{20})
351 ? (numRus * ruAllocIndex)
352 : (ruAllocIndex / num20MhzSubchannelsInRu);
353 std::size_t phyIndex =
WifiRu::GetIndex(ruSpecs.at(ruIndex)) + ruIndexOffset;
356 txVector.
SetHeMuUserInfo(userInfo.staId, {ru, userInfo.mcs, userInfo.nss});
361 if (numRusLeft == 0 && numUsersLeft == 0)
363 const auto pos = std::find(remainingRuAllocIndices.cbegin(),
364 remainingRuAllocIndices.cend(),
366 remainingRuAllocIndices.erase(pos);
367 ruAllocIndex += num20MhzSubchannelsInRu;
368 if (ruAllocIndex % 2 != contentChannelIndex)
374 contentChannelIndex++;
383 const auto length =
m_lSig.GetLength();
388 uint8_t m =
IsDlMu() ? 1 : 2;
390 const auto calculatedDuration =
391 MicroSeconds(((ceil(
static_cast<double>(length + 3 + m) / 3)) * 4) + 20 + sigExtension);
392 NS_ASSERT(calculatedDuration > preambleDuration);
394 floor(
static_cast<double>((calculatedDuration - preambleDuration).GetNanoSeconds() -
395 (sigExtension * 1000)) /
396 tSymbol.GetNanoSeconds());
397 return (preambleDuration + (nSymbols * tSymbol) +
MicroSeconds(sigExtension));
449 auto heSigHeader = std::get_if<HeTbSigHeader>(&
m_heSig);
452 if ((bssColor == 0) || (heSigHeader->m_bssColor == 0) ||
453 (bssColor == heSigHeader->m_bssColor))
455 return m_psdus.cbegin()->second;
460 auto heSigHeader = std::get_if<HeMuSigHeader>(&
m_heSig);
462 if ((bssColor == 0) || (heSigHeader->m_bssColor == 0) ||
463 (bssColor == heSigHeader->m_bssColor))
465 const auto it =
m_psdus.find(staId);
518 if (trigVector.has_value())
534 if (trigVector.has_value() && trigVector->IsUlMu() &&
535 (trigVector->GetHeMuUserInfoMap().contains(staId)))
539 m_txVector->SetGuardInterval(trigVector->GetGuardInterval());
540 m_txVector->SetHeMuUserInfo(staId, trigVector->GetHeMuUserInfo(staId));
551std::pair<std::size_t, std::size_t>
556 std::optional<Center26ToneRuIndication> center26ToneRuIndication,
557 bool sigBCompression,
558 uint8_t numMuMimoUsers)
560 std::pair<std::size_t ,
569 if (channelWidth ==
MHz_u{20})
571 return {numMuMimoUsers, 0};
573 chSize.first = numMuMimoUsers / 2;
574 chSize.second = numMuMimoUsers / 2;
575 if (numMuMimoUsers != (chSize.first + chSize.second))
582 NS_ASSERT_MSG(!ruAllocation.empty(),
"RU allocation is not set");
584 "RU allocation is not consistent with packet bandwidth");
586 switch (
static_cast<uint16_t
>(channelWidth))
598 const auto ruAlloc = ruAllocation.at(n);
599 std::size_t num20MHz{1};
601 const auto nRuSpecs = ruSpecs.size();
614 ccIndex = (chSize.first <= chSize.second) ? 0 : 1;
618 ccIndex = (n % 2 == 0) ? 0 : 1;
622 chSize.first += nRuSpecs;
626 chSize.second += nRuSpecs;
630 const auto skipNumIndices = (ccIndex == 0) ? num20MHz : num20MHz - 1;
640 if (center26ToneRuIndication)
642 switch (*center26ToneRuIndication)
668 if (channelWidth >
MHz_u{20})
670 contentChannels.emplace_back();
673 std::optional<HeSigBUserSpecificField> cc1Central26ToneRu;
674 std::optional<HeSigBUserSpecificField> cc2Central26ToneRu;
678 std::size_t prevRuIndex{0};
679 std::size_t prevCcIndex{0};
680 for (
const auto& [ru, staIds] : orderedMap)
687 const auto staId = *staIds.cbegin();
689 if (std::get<HeRu::RuSpec>(ru).GetPrimary80MHz())
709 for (
auto staId : staIds)
713 (contentChannels.at(0).size() <= contentChannels.at(1).size()) ? 0 : 1;
716 contentChannels[ccIndex].push_back({staId, userInfo.nss, userInfo.mcs});
723 while (prevRuIndex < ruIndex - 1)
725 std::size_t ccIndex{0};
726 if (channelWidth <
MHz_u{40})
734 ccIndex = (contentChannels.at(0).size() <= contentChannels.at(1).size()) ? 0 : 1;
738 ccIndex = ((prevRuIndex / numRus) % 2 == 0) ? 0 : 1;
740 const auto central26TonesRus =
742 const auto isCentral26ToneRu = std::none_of(
743 central26TonesRus.cbegin(),
744 central26TonesRus.cend(),
745 [ruIndex, channelWidth, p20Index](
const auto& ruSpec) {
746 return WifiRu::GetPhyIndex(ruSpec, channelWidth, p20Index) == ruIndex;
754 prevCcIndex = ccIndex;
756 prevRuIndex = ruIndex;
758 for (
auto staId : staIds)
762 std::size_t ccIndex{0};
763 if (channelWidth <
MHz_u{40})
771 ccIndex = (contentChannels.at(0).size() <= contentChannels.at(1).size()) ? 0 : 1;
782 ruIdx -= (ruIdx - 19) / 37;
785 ccIndex = (((ruIdx - 1) / numRus) % 2 == 0) ? 0 : 1;
787 contentChannels.at(ccIndex).push_back({staId, userInfo.nss, userInfo.mcs});
788 prevCcIndex = ccIndex;
792 if (cc1Central26ToneRu)
794 contentChannels.at(0).push_back(*cc1Central26ToneRu);
796 if (cc2Central26ToneRu)
798 contentChannels.at(1).push_back(*cc2Central26ToneRu);
802 if (!isSigBCompression)
812 std::size_t contentChannelIndex = 1;
813 for (
auto& contentChannel : contentChannels)
815 const auto totalUsersInContentChannel = (contentChannelIndex == 1)
816 ? numNumRusPerHeSigBContentChannel.first
817 : numNumRusPerHeSigBContentChannel.second;
818 NS_ASSERT(contentChannel.size() <= totalUsersInContentChannel);
819 std::size_t unallocatedRus = totalUsersInContentChannel - contentChannel.size();
820 for (std::size_t i = 0; i < unallocatedRus; i++)
824 contentChannelIndex++;
828 return contentChannels;
835 std::optional<Center26ToneRuIndication> center26ToneRuIndication,
836 bool sigBCompression,
837 std::size_t numMuMimoUsers)
841 if (!sigBCompression)
843 commonFieldSize = 4 + 6 ;
844 if (channelWidth <=
MHz_u{40})
846 commonFieldSize += 8;
851 8 * (channelWidth /
MHz_u{40}) +
859 center26ToneRuIndication,
862 auto maxNumRusPerContentChannel =
863 std::max(numRusPerContentChannel.first, numRusPerContentChannel.second);
864 auto maxNumUserBlockFields = maxNumRusPerContentChannel /
866 std::size_t userSpecificFieldSize =
867 maxNumUserBlockFields * (2 * 21 + 4 + 6 );
868 if (maxNumRusPerContentChannel % 2 != 0)
870 userSpecificFieldSize += 21 + 4 + 6 ;
873 return commonFieldSize + userSpecificFieldSize;
879 std::ostringstream ss;
895 if (channelWidth ==
MHz_u{160})
899 else if (channelWidth ==
MHz_u{80})
903 else if (channelWidth ==
MHz_u{40})
920 else if (bandwidth == 2)
924 else if (bandwidth == 1)
938 if ((gi == 800) && (nltf == 1))
942 else if ((gi == 800) && (nltf == 2))
946 else if ((gi == 1600) && (nltf == 2))
959 if (giAndNltfSize == 3)
964 else if (giAndNltfSize == 2)
997 return (encoding + 1);
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
static Time GetSymbolDuration(Time guardInterval)
HeSigHeader m_heSig
the HE-SIG PHY header
void SetTxPsdFlag(TxPsdFlag flag) const
WifiTxVector DoGetTxVector() const override
Get the TXVECTOR used to send the PPDU.
virtual void SetTxVectorFromPhyHeaders(WifiTxVector &txVector) const
Fill in the TXVECTOR from PHY headers.
void UpdateTxVectorForUlMu(const std::optional< WifiTxVector > &trigVector) const
Update the TXVECTOR for HE TB PPDUs, since the information to decode HE TB PPDUs is not available fro...
Ptr< WifiPpdu > Copy() const override
Copy this instance.
MHz_u GetTxChannelWidth() const override
Get the channel width over which the PPDU will effectively be transmitted.
TxPsdFlag
The transmit power spectral density flag, namely used to correctly build PSDs for pre-HE and HE porti...
@ PSD_HE_PORTION
HE portion of an HE PPDU.
@ PSD_NON_HE_PORTION
Non-HE portion of an HE PPDU.
virtual bool IsDlMu() const
Return true if the PPDU is a DL MU PPDU.
Time GetTxDuration() const override
Get the total transmission duration of the PPDU.
virtual bool IsUlMu() const
Return true if the PPDU is an UL MU PPDU.
virtual Ptr< const WifiPsdu > GetPsdu(uint8_t bssColor, uint16_t staId=SU_STA_ID) const
Get the payload of the PPDU.
static uint8_t GetNstsEncodingFromNss(uint8_t nss)
Convert number of spatial streams to NSTS field encoding in HE-SIG-A.
static std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(MHz_u channelWidth, WifiModulationClass mc, const RuAllocation &ruAllocation, std::optional< Center26ToneRuIndication > center26ToneRuIndication, bool sigBCompression, uint8_t numMuMimoUsers)
Get the number of STAs per HE-SIG-B content channel.
static uint32_t GetSigBFieldSize(MHz_u channelWidth, WifiModulationClass mc, const RuAllocation &ruAllocation, std::optional< Center26ToneRuIndication > center26ToneRuIndication, bool sigBCompression, std::size_t numMuMimoUsers)
Get variable length HE SIG-B field size.
void SetHeSigHeader(const WifiTxVector &txVector)
Fill in the HE-SIG header.
static uint8_t GetNssFromNstsEncoding(uint8_t nsts)
Convert number of spatial streams from NSTS field encoding in HE-SIG-A.
static Time GetGuardIntervalFromEncoding(uint8_t giAndNltfSize)
Convert guard interval from its encoding in HE-SIG-A.
virtual void SetPhyHeaders(const WifiTxVector &txVector, Time ppduDuration)
Fill in the PHY headers.
std::string PrintPayload() const override
Print the payload of the PPDU.
uint16_t GetStaId() const override
Get the ID of the STA that transmitted the PPDU for UL MU, SU_STA_ID otherwise.
static HeSigBContentChannels GetHeSigBContentChannels(const WifiTxVector &txVector, uint8_t p20Index)
Get the HE SIG-B content channels for a given PPDU IEEE 802.11ax-2021 27.3.11.8.2 HE-SIG-B content ch...
std::vector< std::vector< HeSigBUserSpecificField > > HeSigBContentChannels
HE SIG-B Content Channels.
WifiPpduType GetType() const override
Return the PPDU type (.
TxPsdFlag GetTxPsdFlag() const
static uint8_t GetMuMimoUsersEncoding(uint8_t nUsers)
Convert number of MU-MIMO users to its encoding in HE-SIG-A.
static MHz_u GetChannelWidthMhzFromEncoding(uint8_t bandwidth)
Convert channel width expressed in MHz from bandwidth field encoding in HE-SIG-A.
virtual bool IsMu() const
Return true if the PPDU is a MU PPDU.
HePpdu(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector, const WifiPhyOperatingChannel &channel, Time ppduDuration, uint64_t uid, bool instantiateHeaders=true)
Create an SU HE PPDU, storing a PSDU.
static uint8_t GetChannelWidthEncodingFromMhz(MHz_u channelWidth)
Convert channel width expressed in MHz to bandwidth field encoding in HE-SIG-A.
void SetLSigHeader(Time ppduDuration)
Fill in the L-SIG header.
void SetHeMuUserInfos(WifiTxVector &txVector, WifiModulationClass mc, const RuAllocation &ruAllocation, std::optional< Center26ToneRuIndication > center26ToneRuIndication, const HeSigBContentChannels &contentChannels, bool sigBCompression, uint8_t numMuMimoUsers) const
Reconstruct HeMuUserInfoMap from HE-SIG-B header.
static uint8_t GetGuardIntervalAndNltfEncoding(Time guardInterval, uint8_t nltf)
Convert guard interval and NLTF to its encoding in HE-SIG-A.
TxPsdFlag m_txPsdFlag
the transmit power spectral density flag
static uint8_t GetMuMimoUsersFromEncoding(uint8_t encoding)
Convert number of MU-MIMO users from its encoding in HE-SIG-A.
virtual WifiRu::RuSpec GetRuSpec(std::size_t ruAllocIndex, MHz_u bw, RuType ruType, std::size_t phyIndex) const
Get the RU specification that has been assigned a given user.
static std::vector< RuSpec > GetRusOfType(MHz_u bw, RuType ruType)
Get the set of distinct RUs of the given type (number of tones) available in a HE PPDU of the given b...
static std::size_t GetNRus(MHz_u bw, RuType ruType)
Get the number of distinct RUs of the given type (number of tones) available in a HE PPDU of the give...
OfdmPpdu(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector, const WifiPhyOperatingChannel &channel, uint64_t uid, bool instantiateLSig=true)
Create an OFDM PPDU.
LSigHeader m_lSig
the L-SIG PHY header
Smart pointer class similar to boost::intrusive_ptr.
Simulation virtual time values and global simulation resolution.
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
static WifiMode GetVhtMcs(uint8_t index)
Return the VHT MCS corresponding to the provided index.
uint8_t GetMcsValue() const
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Class that keeps track of all information about the current PHY operating channel.
virtual MHz_u GetTxChannelWidth() const
Get the channel width over which the PPDU will effectively be transmitted.
const WifiPhyOperatingChannel & m_operatingChannel
the operating channel of the PHY
std::optional< WifiTxVector > m_txVector
the TXVECTOR at TX PHY or the reconstructed TXVECTOR at RX PHY (or std::nullopt if TXVECTOR has not b...
WifiPreamble m_preamble
the PHY preamble
const WifiTxVector & GetTxVector() const
Get the TXVECTOR used to send the PPDU.
WifiModulationClass GetModulation() const
Get the modulation used for the PPDU.
WifiConstPsduMap m_psdus
the PSDUs contained in this PPDU
static std::vector< RuSpec > GetRuSpecs(uint16_t ruAllocation, WifiModulationClass mc)
Get the RU specs based on RU_ALLOCATION.
static std::size_t GetNRus(MHz_u bw, RuType ruType, WifiModulationClass mc)
Get the number of distinct RUs of the given type (number of tones) available in a PPDU of the given b...
std::variant< HeRu::RuSpec, EhtRu::RuSpec > RuSpec
variant of the RU specification
static bool IsHe(RuSpec ru)
Get whether a given RU variant is a HE RU.
static MHz_u GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
static RuType GetRuType(RuSpec ru)
Get the type of a given RU.
static std::vector< RuSpec > GetCentral26TonesRus(MHz_u bw, RuType ruType, WifiModulationClass mc)
Get the set of 26-tone RUs that can be additionally allocated if the given bandwidth is split in RUs ...
static std::size_t GetPhyIndex(RuSpec ru, MHz_u bw, uint8_t p20Index)
Get the RU PHY index.
static std::size_t GetIndex(RuSpec ru)
Get the index of a given RU.
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.
UserInfoMapOrderedByRus GetUserInfoMapOrderedByRus(uint8_t p20Index) const
Get the map of specific user info parameters ordered per increasing frequency RUs.
bool IsSigBCompression() const
Indicate whether the Common field is present in the HE-SIG-B field.
uint8_t GetBssColor() const
Get the BSS color.
const RuAllocation & GetRuAllocation(uint8_t p20Index) const
Get RU_ALLOCATION field.
void SetGuardInterval(Time guardInterval)
Sets the guard interval duration (in nanoseconds)
std::optional< Center26ToneRuIndication > GetCenter26ToneRuIndication() const
Get CENTER_26_TONE_RU field This field is present if format is HE_MU and when channel width is set to...
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.
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
HeMuUserInfo GetHeMuUserInfo(uint16_t staId) const
Get the HE MU user-specific transmission information for the given STA-ID.
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
const HeMuUserInfoMap & GetHeMuUserInfoMap() const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
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.
MHz_u GetChannelWidth() const
void SetSigBMode(const WifiMode &mode)
Set the MCS used for SIG-B.
void SetBssColor(uint8_t color)
Set the BSS color.
Time GetGuardInterval() const
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.
#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_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Center26ToneRuIndication
Enum for the different values for CENTER_26_TONE_RU.
WifiPpduType
The type of PPDU (SU, DL MU, or UL MU)
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
@ CENTER_26_TONE_RU_LOW_AND_HIGH_80_MHZ_ALLOCATED
@ CENTER_26_TONE_RU_UNALLOCATED
@ CENTER_26_TONE_RU_HIGH_80_MHZ_ALLOCATED
@ CENTER_26_TONE_RU_LOW_80_MHZ_ALLOCATED
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Declaration of ns3::HePhy class and ns3::HeSigAParameters struct.
Declaration of ns3::HePpdu class.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
RuType
The different Resource Unit (RU) types.
double MHz_u
MHz weak type.
static constexpr uint16_t NO_USER_STA_ID
STA_ID for a RU that is intended for no user (Section 26.11.1 802.11ax-2021)
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.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
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
User Specific Fields in HE-SIG-Bs.