14#include "ns3/wifi-phy-operating-channel.h"
15#include "ns3/wifi-psdu.h"
31 :
HePpdu(psdus, txVector, channel, ppduDuration, uid, flag, false)
33 NS_LOG_FUNCTION(
this << psdus << txVector << channel << ppduDuration << uid << flag);
55 .m_bssColor = bssColor,
59 .m_puncturedChannelInfo =
84 .m_bssColor = bssColor,
139 const auto ruAllocation = ehtPhyHeader->m_ruAllocationA;
142 ruAllocation.has_value())
145 const auto isMuMimo = (ehtPhyHeader->m_ppduType == 2);
146 const auto muMimoUsers =
148 ? std::accumulate(ehtPhyHeader->m_contentChannels.cbegin(),
149 ehtPhyHeader->m_contentChannels.cend(),
151 [](uint8_t
prev,
const auto& cc) { return prev + cc.size(); })
154 ruAllocation.value(),
156 ehtPhyHeader->m_contentChannels,
157 ehtPhyHeader->m_ppduType == 2,
160 else if (ehtPhyHeader->m_ppduType == 1)
162 NS_ASSERT(ehtPhyHeader->m_contentChannels.size() == 1 &&
163 ehtPhyHeader->m_contentChannels.front().size() == 1);
166 txVector.
SetNss(ehtPhyHeader->m_contentChannels.front().front().nss);
171 txVector.
SetHeMuUserInfo(ehtPhyHeader->m_contentChannels.front().front().staId,
173 ehtPhyHeader->m_contentChannels.front().front().mcs,
174 ehtPhyHeader->m_contentChannels.front().front().nss});
187std::pair<std::size_t, std::size_t>
192 std::size_t numMuMimoUsers)
194 if (ehtPpduType == 1)
222 std::size_t numMuMimoUsers)
228 commonFieldSize = 4 + 6 ;
229 if (channelWidth <=
MHz_u{40})
231 commonFieldSize += 8;
236 8 * (channelWidth /
MHz_u{40}) +
246 auto maxNumRusPerContentChannel =
247 std::max(numRusPerContentChannel.first, numRusPerContentChannel.second);
248 auto maxNumUserBlockFields = maxNumRusPerContentChannel /
250 std::size_t userSpecificFieldSize =
251 maxNumUserBlockFields * (2 * 21 + 4 + 6 );
252 if (maxNumRusPerContentChannel % 2 != 0)
254 userSpecificFieldSize += 21 + 4 + 6 ;
257 return commonFieldSize + userSpecificFieldSize;
263 std::optional<bool> isLow80MHz)
265 if (inactiveSubchannels.size() < 4)
271 "Puncturing over more than 160 MHz is not supported");
272 if (ehtPpduType == 0)
275 NS_ASSERT(inactiveSubchannels.size() <= 4 || isLow80MHz.has_value());
276 const auto startIndex = (inactiveSubchannels.size() <= 4) ? 0 : (*isLow80MHz ? 0 : 4);
277 const auto stopIndex =
278 (inactiveSubchannels.size() <= 4) ? inactiveSubchannels.size() : (*isLow80MHz ? 4 : 8);
279 uint8_t puncturedInfoField = 0;
280 for (std::size_t i = startIndex; i < stopIndex; ++i)
282 if (!inactiveSubchannels.at(i))
284 puncturedInfoField |= 1 << (i / 4);
287 return puncturedInfoField;
290 const auto numPunctured = std::count_if(inactiveSubchannels.cbegin(),
291 inactiveSubchannels.cend(),
292 [](
bool punctured) { return punctured; });
293 if (numPunctured == 0)
298 const auto firstPunctured = std::find_if(inactiveSubchannels.cbegin(),
299 inactiveSubchannels.cend(),
300 [](
bool punctured) { return punctured; });
301 const auto firstIndex = std::distance(inactiveSubchannels.cbegin(), firstPunctured);
302 switch (numPunctured)
305 return firstIndex + 1;
307 NS_ASSERT_MSG(((firstIndex % 2) == 0) && inactiveSubchannels.at(firstIndex + 1),
308 "invalid 40 MHz puncturing pattern");
309 return 9 + (firstIndex / 2);
331 if ((bssColor == 0) || (ehtPhyHeader->m_bssColor == 0) ||
332 (bssColor == ehtPhyHeader->m_bssColor))
334 return m_psdus.cbegin()->second;
341 if ((bssColor == 0) || (ehtPhyHeader->m_bssColor == 0) ||
342 (bssColor == ehtPhyHeader->m_bssColor))
344 const auto it =
m_psdus.find(staId);
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
static uint32_t GetEhtSigFieldSize(MHz_u channelWidth, const RuAllocation &ruAllocation, uint8_t ehtPpduType, bool compression, std::size_t numMuMimoUsers)
Get variable length EHT-SIG field size.
static HeSigBContentChannels GetEhtSigContentChannels(const WifiTxVector &txVector, uint8_t p20Index)
Get the EHT-SIG content channels for a given PPDU IEEE 802.11be-D3.1 36.3.12.8.2 EHT-SIG content chan...
bool IsDlMu() const override
Return true if the PPDU is a DL MU PPDU.
void SetPhyHeaders(const WifiTxVector &txVector, Time ppduDuration) override
Fill in the PHY headers.
bool IsUlMu() const override
Return true if the PPDU is an UL MU PPDU.
void SetEhtPhyHeader(const WifiTxVector &txVector)
Fill in the EHT PHY header.
static std::pair< std::size_t, std::size_t > GetNumRusPerEhtSigBContentChannel(MHz_u channelWidth, uint8_t ehtPpduType, const RuAllocation &ruAllocation, bool compression, std::size_t numMuMimoUsers)
Get the number of RUs per EHT-SIG-B content channel.
Ptr< WifiPpdu > Copy() const override
Copy this instance.
void SetTxVectorFromPhyHeaders(WifiTxVector &txVector) const override
Fill in the TXVECTOR from PHY headers.
WifiPpduType GetType() const override
Return the PPDU type (.
static uint8_t GetPuncturedInfo(const std::vector< bool > &inactiveSubchannels, uint8_t ehtPpduType, std::optional< bool > isLow80MHz)
Get the Punctured Channel Information field in the U-SIG.
EhtPhyHeader m_ehtPhyHeader
the EHT PHY header
EhtPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, const WifiPhyOperatingChannel &channel, Time ppduDuration, uint64_t uid, TxPsdFlag flag)
Create an EHT PPDU, storing a map of PSDUs.
TxPsdFlag
The transmit power spectral density flag, namely used to correctly build PSDs for pre-HE and HE porti...
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.
static Time GetGuardIntervalFromEncoding(uint8_t giAndNltfSize)
Convert guard interval from its encoding in HE-SIG-A.
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 MHz_u GetChannelWidthMhzFromEncoding(uint8_t bandwidth)
Convert channel width expressed in MHz from bandwidth field encoding in HE-SIG-A.
static std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(MHz_u channelWidth, const RuAllocation &ruAllocation, std::optional< Center26ToneRuIndication > center26ToneRuIndication, bool sigBCompression, uint8_t numMuMimoUsers)
Get the number of STAs per HE-SIG-B content channel.
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.
LSigHeader m_lSig
the L-SIG PHY header
Smart pointer class similar to boost::intrusive_ptr.
Simulation virtual time values and global simulation resolution.
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.
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...
const WifiPhyOperatingChannel & m_operatingChannel
the operating channel of the PHY
WifiPreamble m_preamble
the PHY preamble
Ptr< const WifiPsdu > GetPsdu() const
Get the payload of the PPDU.
WifiConstPsduMap m_psdus
the PSDUs contained in this PPDU
static RuType GetRuType(RuSpec ru)
Get the type 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 SetRuAllocation(const RuAllocation &ruAlloc, uint8_t p20Index)
Set RU_ALLOCATION field.
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.
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)
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.
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
uint8_t GetEhtPpduType() const
Get the EHT_PPDU_TYPE parameter.
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.
const std::vector< bool > & GetInactiveSubchannels() const
Get the 20 MHz subchannels that are punctured.
Declaration of ns3::EhtPhy class.
Declaration of ns3::EhtPpdu class.
#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_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 ",...
WifiPpduType
The type of PPDU (SU, DL MU, or UL MU)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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