14#include "ns3/wifi-phy-operating-channel.h"
15#include "ns3/wifi-psdu.h"
31 :
HePpdu(psdus, txVector, channel, ppduDuration, uid, flag)
33 NS_LOG_FUNCTION(
this << psdus << txVector << channel << ppduDuration << uid << flag);
54 .m_bssColor = bssColor,
58 .m_puncturedChannelInfo =
82 .m_bssColor = bssColor,
137 const auto ruAllocation = ehtPhyHeader->m_ruAllocationA;
140 ruAllocation.has_value())
143 const auto isMuMimo = (ehtPhyHeader->m_ppduType == 2);
144 const auto muMimoUsers =
146 ? std::accumulate(ehtPhyHeader->m_contentChannels.cbegin(),
147 ehtPhyHeader->m_contentChannels.cend(),
149 [](uint8_t
prev,
const auto& cc) { return prev + cc.size(); })
152 ruAllocation.value(),
153 ehtPhyHeader->m_contentChannels,
154 ehtPhyHeader->m_ppduType == 2,
157 if (ehtPhyHeader->m_ppduType == 1)
159 NS_ASSERT(ehtPhyHeader->m_contentChannels.size() == 1 &&
160 ehtPhyHeader->m_contentChannels.front().size() == 1);
163 txVector.
SetNss(ehtPhyHeader->m_contentChannels.front().front().nss);
176std::pair<std::size_t, std::size_t>
181 std::size_t numMuMimoUsers)
183 if (ehtPpduType == 1)
210 std::size_t numMuMimoUsers)
216 commonFieldSize = 4 + 6 ;
217 if (channelWidth <=
MHz_u{40})
219 commonFieldSize += 8;
224 8 * (channelWidth /
MHz_u{40}) +
234 auto maxNumRusPerContentChannel =
235 std::max(numRusPerContentChannel.first, numRusPerContentChannel.second);
236 auto maxNumUserBlockFields = maxNumRusPerContentChannel /
238 std::size_t userSpecificFieldSize =
239 maxNumUserBlockFields * (2 * 21 + 4 + 6 );
240 if (maxNumRusPerContentChannel % 2 != 0)
242 userSpecificFieldSize += 21 + 4 + 6 ;
245 return commonFieldSize + userSpecificFieldSize;
251 std::optional<bool> isLow80MHz)
253 if (inactiveSubchannels.size() < 4)
259 "Puncturing over more than 160 MHz is not supported");
260 if (ehtPpduType == 0)
263 NS_ASSERT(inactiveSubchannels.size() <= 4 || isLow80MHz.has_value());
264 const auto startIndex = (inactiveSubchannels.size() <= 4) ? 0 : (*isLow80MHz ? 0 : 4);
265 const auto stopIndex =
266 (inactiveSubchannels.size() <= 4) ? inactiveSubchannels.size() : (*isLow80MHz ? 4 : 8);
267 uint8_t puncturedInfoField = 0;
268 for (std::size_t i = startIndex; i < stopIndex; ++i)
270 if (!inactiveSubchannels.at(i))
272 puncturedInfoField |= 1 << (i / 4);
275 return puncturedInfoField;
278 const auto numPunctured = std::count_if(inactiveSubchannels.cbegin(),
279 inactiveSubchannels.cend(),
280 [](
bool punctured) { return punctured; });
281 if (numPunctured == 0)
286 const auto firstPunctured = std::find_if(inactiveSubchannels.cbegin(),
287 inactiveSubchannels.cend(),
288 [](
bool punctured) { return punctured; });
289 const auto firstIndex = std::distance(inactiveSubchannels.cbegin(), firstPunctured);
290 switch (numPunctured)
293 return firstIndex + 1;
295 NS_ASSERT_MSG(((firstIndex % 2) == 0) && inactiveSubchannels.at(firstIndex + 1),
296 "invalid 40 MHz puncturing pattern");
297 return 9 + (firstIndex / 2);
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.
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.
void SetPhyHeaders(const WifiTxVector &txVector, Time ppduDuration)
Fill in the 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...
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...
void SetHeMuUserInfos(WifiTxVector &txVector, const RuAllocation &ruAllocation, const HeSigBContentChannels &contentChannels, bool sigBCompression, uint8_t numMuMimoUsers) const
Reconstruct HeMuUserInfoMap from HE-SIG-B header.
std::vector< std::vector< HeSigBUserSpecificField > > HeSigBContentChannels
HE SIG-B Content Channels.
static std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(MHz_u channelWidth, const RuAllocation &ruAllocation, bool sigBCompression, uint8_t numMuMimoUsers)
Get the number of STAs per HE-SIG-B content channel.
static MHz_u GetChannelWidthMhzFromEncoding(uint8_t bandwidth)
Convert channel width expressed in MHz from bandwidth field encoding in HE-SIG-A.
static uint8_t GetChannelWidthEncodingFromMhz(MHz_u channelWidth)
Convert channel width expressed in MHz to bandwidth field encoding in HE-SIG-A.
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
WifiConstPsduMap m_psdus
the PSDUs contained in this PPDU
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.
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 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