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 =
83 .m_bssColor = bssColor,
138 const auto ruAllocation = ehtPhyHeader->m_ruAllocationA;
141 ruAllocation.has_value())
144 const auto isMuMimo = (ehtPhyHeader->m_ppduType == 2);
145 const auto muMimoUsers =
147 ? std::accumulate(ehtPhyHeader->m_contentChannels.cbegin(),
148 ehtPhyHeader->m_contentChannels.cend(),
150 [](uint8_t
prev,
const auto& cc) { return prev + cc.size(); })
153 ruAllocation.value(),
155 ehtPhyHeader->m_contentChannels,
156 ehtPhyHeader->m_ppduType == 2,
159 else if (ehtPhyHeader->m_ppduType == 1)
161 NS_ASSERT(ehtPhyHeader->m_contentChannels.size() == 1 &&
162 ehtPhyHeader->m_contentChannels.front().size() == 1);
165 txVector.
SetNss(ehtPhyHeader->m_contentChannels.front().front().nss);
170 txVector.
SetHeMuUserInfo(ehtPhyHeader->m_contentChannels.front().front().staId,
172 ehtPhyHeader->m_contentChannels.front().front().mcs,
173 ehtPhyHeader->m_contentChannels.front().front().nss});
186std::pair<std::size_t, std::size_t>
191 std::size_t numMuMimoUsers)
193 if (ehtPpduType == 1)
221 std::size_t numMuMimoUsers)
227 commonFieldSize = 4 + 6 ;
228 if (channelWidth <=
MHz_u{40})
230 commonFieldSize += 8;
235 8 * (channelWidth /
MHz_u{40}) +
245 auto maxNumRusPerContentChannel =
246 std::max(numRusPerContentChannel.first, numRusPerContentChannel.second);
247 auto maxNumUserBlockFields = maxNumRusPerContentChannel /
249 std::size_t userSpecificFieldSize =
250 maxNumUserBlockFields * (2 * 21 + 4 + 6 );
251 if (maxNumRusPerContentChannel % 2 != 0)
253 userSpecificFieldSize += 21 + 4 + 6 ;
256 return commonFieldSize + userSpecificFieldSize;
262 std::optional<bool> isLow80MHz)
264 if (inactiveSubchannels.size() < 4)
270 "Puncturing over more than 160 MHz is not supported");
271 if (ehtPpduType == 0)
274 NS_ASSERT(inactiveSubchannels.size() <= 4 || isLow80MHz.has_value());
275 const auto startIndex = (inactiveSubchannels.size() <= 4) ? 0 : (*isLow80MHz ? 0 : 4);
276 const auto stopIndex =
277 (inactiveSubchannels.size() <= 4) ? inactiveSubchannels.size() : (*isLow80MHz ? 4 : 8);
278 uint8_t puncturedInfoField = 0;
279 for (std::size_t i = startIndex; i < stopIndex; ++i)
281 if (!inactiveSubchannels.at(i))
283 puncturedInfoField |= 1 << (i / 4);
286 return puncturedInfoField;
289 const auto numPunctured = std::count_if(inactiveSubchannels.cbegin(),
290 inactiveSubchannels.cend(),
291 [](
bool punctured) { return punctured; });
292 if (numPunctured == 0)
297 const auto firstPunctured = std::find_if(inactiveSubchannels.cbegin(),
298 inactiveSubchannels.cend(),
299 [](
bool punctured) { return punctured; });
300 const auto firstIndex = std::distance(inactiveSubchannels.cbegin(), firstPunctured);
301 switch (numPunctured)
304 return firstIndex + 1;
306 NS_ASSERT_MSG(((firstIndex % 2) == 0) && inactiveSubchannels.at(firstIndex + 1),
307 "invalid 40 MHz puncturing pattern");
308 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...
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.
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
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