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 )
82 m_txPsdFlag(PSD_NON_HE_PORTION)
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)) /
134 const uint8_t noMuMimoUsers{0};
147 .m_center26ToneRuIndication =
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_center26ToneRuIndication,
207 heSigHeader->m_contentChannels,
208 heSigHeader->m_sigBCompression,
213 if (heSigHeader->m_center26ToneRuIndication.has_value())
217 if (heSigHeader->m_sigBCompression)
227 const std::vector<WifiRu::RuSpec>& ruSpecs,
235 const std::size_t ruIndexOffset =
236 (ruBw <
MHz_u{20}) ? (numRus * ruAllocIndex) : (ruAllocIndex / num20MhzSubchannelsInRu);
238 auto isPrimary80 =
true;
241 const auto isLow80 = ruAllocIndex < 4;
243 const auto primary80IsLower80 = (p20Index < bw /
MHz_u{40});
249 isPrimary80 = ((primary80IsLower80 && isLow80) || (!primary80IsLower80 && !isLow80));
261 std::optional<Center26ToneRuIndication> center26ToneRuIndication,
263 bool sigBcompression,
264 uint8_t numMuMimoUsers)
const
267 std::vector<uint8_t> remainingRuAllocIndices(ruAllocation.size());
268 std::iota(remainingRuAllocIndices.begin(), remainingRuAllocIndices.end(), 0);
269 std::size_t contentChannelIndex = 0;
270 std::size_t ruAllocIndex = 0;
271 for (
const auto& contentChannel : contentChannels)
273 std::size_t numRusLeft = 0;
274 std::size_t numUsersLeft = 0;
275 ruAllocIndex = remainingRuAllocIndices.front();
276 std::size_t numUsersLeftInCc = contentChannel.size();
277 if (contentChannel.empty())
279 const auto pos = std::find(remainingRuAllocIndices.cbegin(),
280 remainingRuAllocIndices.cend(),
282 remainingRuAllocIndices.erase(pos);
283 ++contentChannelIndex;
286 for (
const auto& userInfo : contentChannel)
288 if (center26ToneRuIndication && (numUsersLeftInCc == 1))
291 if ((contentChannelIndex == 0) &&
292 ((*center26ToneRuIndication ==
294 (*center26ToneRuIndication ==
302 else if ((contentChannelIndex == 1) &&
303 ((*center26ToneRuIndication ==
305 (*center26ToneRuIndication ==
315 NS_ASSERT(ruAllocIndex < ruAllocation.size());
316 const auto mc{WIFI_MOD_CLASS_HE};
317 auto ruSpecs = WifiRu::GetRuSpecs(ruAllocation.at(ruAllocIndex), mc);
318 while (ruSpecs.empty() && (ruAllocIndex < ruAllocation.size()))
320 const auto pos = std::find(remainingRuAllocIndices.cbegin(),
321 remainingRuAllocIndices.cend(),
323 remainingRuAllocIndices.erase(pos);
325 NS_ASSERT(ruAllocIndex < ruAllocation.size());
326 ruSpecs = WifiRu::GetRuSpecs(ruAllocation.at(ruAllocIndex), mc);
330 numRusLeft = ruSpecs.size();
332 if (numUsersLeft == 0)
336 numUsersLeft = numMuMimoUsers;
344 auto ruIndex = (ruSpecs.size() - numRusLeft);
345 const auto ruSpec = ruSpecs.at(ruIndex);
346 auto ruType = WifiRu::GetRuType(ruSpec);
349 ruType = WifiRu::GetRuType(ruAllocation.size() * MHz_u{20});
351 if (userInfo.staId != NO_USER_STA_ID)
354 GetRuSpec(ruAllocIndex, ruSpecs, ruType, ruIndex, txVector.GetChannelWidth())};
355 txVector.SetHeMuUserInfo(userInfo.staId, {ru, userInfo.mcs, userInfo.nss});
360 if (numRusLeft == 0 && numUsersLeft == 0)
362 const auto ruBw = WifiRu::GetBandwidth(ruType);
363 const uint8_t num20MhzSubchannelsInRu =
365 const auto pos = std::find(remainingRuAllocIndices.cbegin(),
366 remainingRuAllocIndices.cend(),
368 remainingRuAllocIndices.erase(pos);
369 ruAllocIndex += num20MhzSubchannelsInRu;
370 if (ruAllocIndex % 2 != contentChannelIndex)
376 contentChannelIndex++;
381HePpdu::GetTxDuration()
const
384 const auto& txVector = GetTxVector();
385 const auto length = m_lSig.GetLength();
386 const auto tSymbol = HePhy::GetSymbolDuration(txVector.GetGuardInterval());
387 const auto preambleDuration = WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector);
390 uint8_t m =
IsDlMu() ? 1 : 2;
392 const auto calculatedDuration =
393 MicroSeconds(((ceil(
static_cast<double>(length + 3 + m) / 3)) * 4) + 20 + sigExtension);
394 NS_ASSERT(calculatedDuration > preambleDuration);
396 floor(
static_cast<double>((calculatedDuration - preambleDuration).GetNanoSeconds() -
397 (sigExtension * 1000)) /
398 tSymbol.GetNanoSeconds());
399 return (preambleDuration + (nSymbols * tSymbol) +
MicroSeconds(sigExtension));
409HePpdu::GetType()
const
429HePpdu::IsDlMu()
const
435HePpdu::IsUlMu()
const
441HePpdu::GetPsdu(uint8_t bssColor, uint16_t staId )
const
446 return m_psdus.at(SU_STA_ID);
451 auto heSigHeader = std::get_if<HeTbSigHeader>(&m_heSig);
454 if ((bssColor == 0) || (heSigHeader->m_bssColor == 0) ||
455 (bssColor == heSigHeader->m_bssColor))
457 return m_psdus.cbegin()->second;
462 auto heSigHeader = std::get_if<HeMuSigHeader>(&m_heSig);
464 if ((bssColor == 0) || (heSigHeader->m_bssColor == 0) ||
465 (bssColor == heSigHeader->m_bssColor))
467 const auto it = m_psdus.find(staId);
468 if (it != m_psdus.cend())
478HePpdu::GetStaId()
const
481 return m_psdus.begin()->first;
485HePpdu::GetTxChannelWidth()
const
487 if (
const auto& txVector = GetTxVector();
488 txVector.IsValid() && txVector.IsUlMu() && GetStaId() != SU_STA_ID)
491 const auto ruWidth = WifiRu::GetBandwidth(WifiRu::GetRuType(txVector.GetRu(GetStaId())));
493 (flag == PSD_NON_HE_PORTION && ruWidth <
MHz_u{20}) ?
MHz_u{20} : ruWidth;
494 NS_LOG_INFO(
"Use " << channelWidth <<
" MHz for TB PPDU from " << GetStaId() <<
" for "
500 return OfdmPpdu::GetTxChannelWidth();
505HePpdu::GetTxPsdFlag()
const
518HePpdu::UpdateTxVectorForUlMu(
const std::optional<WifiTxVector>& trigVector)
const
520 if (trigVector.has_value())
528 if (!m_txVector.has_value())
530 m_txVector = GetTxVector();
535 const auto staId = GetStaId();
536 if (trigVector.has_value() && trigVector->IsUlMu() &&
537 (trigVector->GetHeMuUserInfoMap().contains(staId)))
541 m_txVector->SetGuardInterval(trigVector->GetGuardInterval());
542 m_txVector->SetHeMuUserInfo(staId, trigVector->GetHeMuUserInfo(staId));
547 m_txVector->SetHeMuUserInfo(
549 {
HeRu::RuSpec{(WifiRu::GetRuType(m_txVector->GetChannelWidth())), 1,
true}, 0, 1});
553std::pair<std::size_t, std::size_t>
554HePpdu::GetNumRusPerHeSigBContentChannel(
557 std::optional<Center26ToneRuIndication> center26ToneRuIndication,
558 bool sigBCompression,
559 uint8_t numMuMimoUsers)
561 std::pair<std::size_t ,
570 if (channelWidth ==
MHz_u{20})
572 return {numMuMimoUsers, 0};
574 chSize.first = numMuMimoUsers / 2;
575 chSize.second = numMuMimoUsers / 2;
576 if (numMuMimoUsers != (chSize.first + chSize.second))
583 NS_ASSERT_MSG(!ruAllocation.empty(),
"RU allocation is not set");
585 "RU allocation is not consistent with packet bandwidth");
588 switch (
static_cast<uint16_t
>(channelWidth))
591 chSize.second += WifiRu::GetRuSpecs(ruAllocation[1], mc).size();
594 chSize.first += WifiRu::GetRuSpecs(ruAllocation[0], mc).size();
600 const auto ruAlloc = ruAllocation.at(n);
601 std::size_t num20MHz{1};
602 const auto ruSpecs = WifiRu::GetRuSpecs(ruAlloc, mc);
603 const auto nRuSpecs = ruSpecs.size();
606 const auto ruBw = WifiRu::GetBandwidth(WifiRu::GetRuType(ruSpecs.front()));
616 ccIndex = (chSize.first <= chSize.second) ? 0 : 1;
620 ccIndex = (n % 2 == 0) ? 0 : 1;
624 chSize.first += nRuSpecs;
628 chSize.second += nRuSpecs;
632 const auto skipNumIndices = (ccIndex == 0) ? num20MHz : num20MHz - 1;
642 if (center26ToneRuIndication)
644 switch (*center26ToneRuIndication)
646 case Center26ToneRuIndication::CENTER_26_TONE_RU_LOW_80_MHZ_ALLOCATED:
649 case Center26ToneRuIndication::CENTER_26_TONE_RU_HIGH_80_MHZ_ALLOCATED:
652 case Center26ToneRuIndication::CENTER_26_TONE_RU_LOW_AND_HIGH_80_MHZ_ALLOCATED:
656 case Center26ToneRuIndication::CENTER_26_TONE_RU_UNALLOCATED:
665HePpdu::GetHeSigBContentChannels(
const WifiTxVector& txVector, uint8_t p20Index)
670 if (channelWidth >
MHz_u{20})
672 contentChannels.emplace_back();
675 std::optional<HeSigBUserSpecificField> cc1Central26ToneRu;
676 std::optional<HeSigBUserSpecificField> cc2Central26ToneRu;
679 RuType prevRuType{RuType::RU_TYPE_MAX};
680 std::size_t prevRuIndex{0};
681 std::size_t prevCcIndex{0};
682 for (
const auto& [ru, staIds] : orderedMap)
684 const auto ruType = WifiRu::GetRuType(ru);
685 auto ruIdx = WifiRu::GetIndex(ru);
686 if ((ruType == RuType::RU_26_TONE) && (ruIdx == 19))
689 const auto staId = *staIds.cbegin();
691 if (std::get<HeRu::RuSpec>(ru).GetPrimary80MHz())
704 const auto ruIndex = WifiRu::GetPhyIndex(ru, channelWidth, p20Index);
705 if ((prevRuType < RuType::RU_TYPE_MAX) && (prevRuType != ruType))
707 prevRuIndex *= WifiRu::GetBandwidth(prevRuType) / WifiRu::GetBandwidth(ruType);
709 if (ruType >= RuType::RU_484_TONE)
711 for (
auto staId : staIds)
715 (contentChannels.at(0).size() <= contentChannels.at(1).size()) ? 0 : 1;
718 contentChannels[ccIndex].push_back({staId, userInfo.nss, userInfo.mcs});
724 const auto numRus = WifiRu::GetNRus(
MHz_u{20}, ruType, mc);
725 while (prevRuIndex < ruIndex - 1)
727 std::size_t ccIndex{0};
728 if (channelWidth <
MHz_u{40})
736 ccIndex = (contentChannels.at(0).size() <= contentChannels.at(1).size()) ? 0 : 1;
740 ccIndex = ((prevRuIndex / numRus) % 2 == 0) ? 0 : 1;
742 const auto central26TonesRus =
743 WifiRu::GetCentral26TonesRus(channelWidth, prevRuType, mc);
744 const auto isCentral26ToneRu = std::none_of(
745 central26TonesRus.cbegin(),
746 central26TonesRus.cend(),
747 [ruIndex, channelWidth, p20Index](
const auto& ruSpec) {
748 return WifiRu::GetPhyIndex(ruSpec, channelWidth, p20Index) == ruIndex;
750 if (ruType < RuType::RU_242_TONE && prevCcIndex == ccIndex &&
751 (ruType != RuType::RU_26_TONE || isCentral26ToneRu))
753 contentChannels[ccIndex].push_back({NO_USER_STA_ID, 0, 0});
756 prevCcIndex = ccIndex;
758 prevRuIndex = ruIndex;
760 for (
auto staId : staIds)
764 std::size_t ccIndex{0};
765 if (channelWidth <
MHz_u{40})
773 ccIndex = (contentChannels.at(0).size() <= contentChannels.at(1).size()) ? 0 : 1;
777 if (ruType == RuType::RU_26_TONE && ruIdx > 19)
782 ccIndex = (((ruIdx - 1) / numRus) % 2 == 0) ? 0 : 1;
784 contentChannels.at(ccIndex).push_back({staId, userInfo.nss, userInfo.mcs});
785 prevCcIndex = ccIndex;
789 if (cc1Central26ToneRu)
791 contentChannels.at(0).push_back(*cc1Central26ToneRu);
793 if (cc2Central26ToneRu)
795 contentChannels.at(1).push_back(*cc2Central26ToneRu);
799 if (!isSigBCompression)
802 auto numNumRusPerHeSigBContentChannel = GetNumRusPerHeSigBContentChannel(
808 std::size_t contentChannelIndex = 1;
809 for (
auto& contentChannel : contentChannels)
811 const auto totalUsersInContentChannel = (contentChannelIndex == 1)
812 ? numNumRusPerHeSigBContentChannel.first
813 : numNumRusPerHeSigBContentChannel.second;
814 NS_ASSERT(contentChannel.size() <= totalUsersInContentChannel);
815 std::size_t unallocatedRus = totalUsersInContentChannel - contentChannel.size();
816 for (std::size_t i = 0; i < unallocatedRus; i++)
818 contentChannel.push_back({NO_USER_STA_ID, 0, 0});
820 contentChannelIndex++;
824 return contentChannels;
828HePpdu::GetSigBFieldSize(
MHz_u channelWidth,
830 std::optional<Center26ToneRuIndication> center26ToneRuIndication,
831 bool sigBCompression,
832 std::size_t numMuMimoUsers)
836 if (!sigBCompression)
838 commonFieldSize = 4 + 6 ;
839 if (channelWidth <=
MHz_u{40})
841 commonFieldSize += 8;
846 8 * (channelWidth /
MHz_u{40}) +
851 auto numRusPerContentChannel = GetNumRusPerHeSigBContentChannel(channelWidth,
853 center26ToneRuIndication,
856 auto maxNumRusPerContentChannel =
857 std::max(numRusPerContentChannel.first, numRusPerContentChannel.second);
858 auto maxNumUserBlockFields = maxNumRusPerContentChannel /
860 std::size_t userSpecificFieldSize =
861 maxNumUserBlockFields * (2 * 21 + 4 + 6 );
862 if (maxNumRusPerContentChannel % 2 != 0)
864 userSpecificFieldSize += 21 + 4 + 6 ;
867 return commonFieldSize + userSpecificFieldSize;
871HePpdu::PrintPayload()
const
873 std::ostringstream ss;
877 ss <<
", " << m_txPsdFlag;
881 ss <<
"PSDU=" << m_psdus.at(SU_STA_ID) <<
" ";
887HePpdu::GetChannelWidthEncodingFromMhz(
MHz_u channelWidth)
889 if (channelWidth ==
MHz_u{160})
893 else if (channelWidth ==
MHz_u{80})
897 else if (channelWidth ==
MHz_u{40})
908HePpdu::GetChannelWidthMhzFromEncoding(uint8_t bandwidth)
914 else if (bandwidth == 2)
918 else if (bandwidth == 1)
929HePpdu::GetGuardIntervalAndNltfEncoding(
Time guardInterval, uint8_t nltf)
932 if ((gi == 800) && (nltf == 1))
936 else if ((gi == 800) && (nltf == 2))
940 else if ((gi == 1600) && (nltf == 2))
951HePpdu::GetGuardIntervalFromEncoding(uint8_t giAndNltfSize)
953 if (giAndNltfSize == 3)
958 else if (giAndNltfSize == 2)
969HePpdu::GetNstsEncodingFromNss(uint8_t nss)
976HePpdu::GetNssFromNstsEncoding(uint8_t nsts)
982HePpdu::GetMuMimoUsersEncoding(uint8_t nUsers)
989HePpdu::GetMuMimoUsersFromEncoding(uint8_t encoding)
991 return (encoding + 1);
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
HeSigHeader m_heSig
the HE-SIG PHY header
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.
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.
void SetHeMuUserInfos(WifiTxVector &txVector, const RuAllocation &ruAllocation, std::optional< Center26ToneRuIndication > center26ToneRuIndication, const HeSigBContentChannels &contentChannels, bool sigBCompression, uint8_t numMuMimoUsers) const
Reconstruct HeMuUserInfoMap from HE-SIG-B header.
virtual bool IsUlMu() const
Return true if the PPDU is an UL MU PPDU.
static uint8_t GetNstsEncodingFromNss(uint8_t nss)
Convert number of spatial streams to NSTS field encoding in HE-SIG-A.
virtual WifiRu::RuSpec GetRuSpec(std::size_t ruAllocIndex, const std::vector< WifiRu::RuSpec > &ruSpecs, RuType ruType, std::size_t ruIndex, MHz_u bw) const
Get the RU specification that has been assigned a given user.
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.
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.
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.
static uint8_t GetGuardIntervalAndNltfEncoding(Time guardInterval, uint8_t nltf)
Convert guard interval and NLTF to its encoding in HE-SIG-A.
static uint8_t GetMuMimoUsersFromEncoding(uint8_t encoding)
Convert number of MU-MIMO users from its encoding in HE-SIG-A.
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...
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
Class that keeps track of all information about the current PHY operating channel.
bool IsSet() const
Return true if a valid channel has been set, false otherwise.
uint8_t GetPrimaryChannelIndex(MHz_u primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
WifiPhyBand GetPhyBand() const
Return the PHY band of the operating channel.
const WifiPhyOperatingChannel & m_operatingChannel
the operating channel of the PHY
WifiPreamble m_preamble
the PHY preamble
WifiConstPsduMap m_psdus
the PSDUs contained in this PPDU
std::variant< HeRu::RuSpec, EhtRu::RuSpec > RuSpec
variant of the RU specification
static MHz_u GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
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.
RuAllocation m_ruAllocation
RU allocations that are going to be carried in SIG-B common field per Table 27-1 IEEE.
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.
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)
@ CENTER_26_TONE_RU_LOW_AND_HIGH_80_MHZ_ALLOCATED
@ 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.
bool IsMu(WifiPreamble preamble)
Return true if a preamble corresponds to a multi-user transmission.
double MHz_u
MHz weak 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.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
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.
uint8_t nss
number of spatial streams