A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
eht-ppdu.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 DERONNE SOFTWARE ENGINEERING
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7 */
8
9#include "eht-ppdu.h"
10
11#include "eht-phy.h"
12
13#include "ns3/log.h"
14#include "ns3/wifi-phy-operating-channel.h"
15#include "ns3/wifi-psdu.h"
16
17#include <numeric>
18
19namespace ns3
20{
21
23
25 const WifiTxVector& txVector,
26 const WifiPhyOperatingChannel& channel,
27 Time ppduDuration,
28 uint64_t uid,
29 TxPsdFlag flag)
30 : HePpdu(psdus, txVector, channel, ppduDuration, uid, flag)
31{
32 NS_LOG_FUNCTION(this << psdus << txVector << channel << ppduDuration << uid << flag);
33 SetPhyHeaders(txVector, ppduDuration);
34}
35
36void
37EhtPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
38{
39 NS_LOG_FUNCTION(this << txVector << ppduDuration);
40 SetEhtPhyHeader(txVector);
41}
42
43void
45{
46 const auto bssColor = txVector.GetBssColor();
47 NS_ASSERT(bssColor < 64);
49 {
50 const auto p20Index = m_operatingChannel.GetPrimaryChannelIndex(20);
53 .m_bssColor = bssColor,
54 .m_ppduType = txVector.GetEhtPpduType(),
55 .m_ehtSigMcs = txVector.GetSigBMode().GetMcsValue(),
56 .m_giLtfSize = GetGuardIntervalAndNltfEncoding(txVector.GetGuardInterval(),
57 2 /*NLTF currently unused*/),
58 /* See section 36.3.12.8.2 of IEEE 802.11be D3.0 (EHT-SIG content channels):
59 * In non-OFDMA transmission, the Common field of the EHT-SIG content channel does not
60 * contain the RU Allocation subfield. For non-OFDMA transmission except for EHT
61 * sounding NDP, the Common field of the EHT-SIG content channel is encoded together
62 * with the first User field and this encoding block contains a CRC and Tail, referred
63 * to as a common encoding block. */
64 .m_ruAllocationA =
65 txVector.IsMu() ? std::optional{txVector.GetRuAllocation(p20Index)} : std::nullopt,
66 // TODO: RU Allocation-B not supported yet
67 .m_contentChannels = GetEhtSigContentChannels(txVector, p20Index)});
68 }
69 else if (ns3::IsUlMu(m_preamble))
70 {
73 .m_bssColor = bssColor,
74 .m_ppduType = txVector.GetEhtPpduType()});
75 }
76}
77
80{
81 if (m_psdus.contains(SU_STA_ID))
82 {
83 return WIFI_PPDU_TYPE_SU;
84 }
85 switch (m_preamble)
86 {
91 default:
92 NS_ASSERT_MSG(false, "invalid preamble " << m_preamble);
93 return WIFI_PPDU_TYPE_SU;
94 }
95}
96
97bool
99{
100 return (m_preamble == WIFI_PREAMBLE_EHT_MU) && !m_psdus.contains(SU_STA_ID);
101}
102
103bool
105{
106 return (m_preamble == WIFI_PREAMBLE_EHT_TB) && !m_psdus.contains(SU_STA_ID);
107}
108
109void
111{
112 txVector.SetLength(m_lSig.GetLength());
113 txVector.SetAggregation(m_psdus.size() > 1 || m_psdus.begin()->second->IsAggregate());
115 {
116 auto ehtPhyHeader = std::get_if<EhtMuPhyHeader>(&m_ehtPhyHeader);
117 NS_ASSERT(ehtPhyHeader);
118 txVector.SetChannelWidth(GetChannelWidthMhzFromEncoding(ehtPhyHeader->m_bandwidth));
119 txVector.SetBssColor(ehtPhyHeader->m_bssColor);
120 txVector.SetEhtPpduType(ehtPhyHeader->m_ppduType);
121 txVector.SetSigBMode(HePhy::GetVhtMcs(ehtPhyHeader->m_ehtSigMcs));
122 txVector.SetGuardInterval(GetGuardIntervalFromEncoding(ehtPhyHeader->m_giLtfSize));
123 const auto ruAllocation = ehtPhyHeader->m_ruAllocationA; // RU Allocation-B not supported
124 // yet
125 if (const auto p20Index = m_operatingChannel.GetPrimaryChannelIndex(20);
126 ruAllocation.has_value())
127 {
128 txVector.SetRuAllocation(ruAllocation.value(), p20Index);
129 const auto isMuMimo = (ehtPhyHeader->m_ppduType == 2);
130 const auto muMimoUsers =
131 isMuMimo
132 ? std::accumulate(ehtPhyHeader->m_contentChannels.cbegin(),
133 ehtPhyHeader->m_contentChannels.cend(),
134 0,
135 [](uint8_t prev, const auto& cc) { return prev + cc.size(); })
136 : 0;
137 SetHeMuUserInfos(txVector,
138 ruAllocation.value(),
139 ehtPhyHeader->m_contentChannels,
140 ehtPhyHeader->m_ppduType == 2,
141 muMimoUsers);
142 }
143 if (ehtPhyHeader->m_ppduType == 1) // EHT SU
144 {
145 NS_ASSERT(ehtPhyHeader->m_contentChannels.size() == 1 &&
146 ehtPhyHeader->m_contentChannels.front().size() == 1);
147 txVector.SetMode(
148 EhtPhy::GetEhtMcs(ehtPhyHeader->m_contentChannels.front().front().mcs));
149 txVector.SetNss(ehtPhyHeader->m_contentChannels.front().front().nss);
150 }
151 }
152 else if (ns3::IsUlMu(m_preamble))
153 {
154 auto ehtPhyHeader = std::get_if<EhtTbPhyHeader>(&m_ehtPhyHeader);
155 NS_ASSERT(ehtPhyHeader);
156 txVector.SetChannelWidth(GetChannelWidthMhzFromEncoding(ehtPhyHeader->m_bandwidth));
157 txVector.SetBssColor(ehtPhyHeader->m_bssColor);
158 txVector.SetEhtPpduType(ehtPhyHeader->m_ppduType);
159 }
160}
161
162std::pair<std::size_t, std::size_t>
164 uint8_t ehtPpduType,
165 const RuAllocation& ruAllocation,
166 bool compression,
167 std::size_t numMuMimoUsers)
168{
169 if (ehtPpduType == 1)
170 {
171 return {1, 0};
172 }
174 ruAllocation,
175 compression,
176 numMuMimoUsers);
177}
178
180EhtPpdu::GetEhtSigContentChannels(const WifiTxVector& txVector, uint8_t p20Index)
181{
182 if (txVector.GetEhtPpduType() == 1)
183 {
184 // according to spec the TXVECTOR shall have a correct STA-ID even for SU transmission,
185 // but this is not set by the MAC for simplification, so set to 0 for now.
186 return HeSigBContentChannels{{{0, txVector.GetNss(), txVector.GetMode().GetMcsValue()}}};
187 }
188 return HePpdu::GetHeSigBContentChannels(txVector, p20Index);
189}
190
193 const RuAllocation& ruAllocation,
194 uint8_t ehtPpduType,
195 bool compression,
196 std::size_t numMuMimoUsers)
197{
198 // FIXME: EHT-SIG is not implemented yet, hence this is a copy of HE-SIG-B
199 uint32_t commonFieldSize = 0;
200 if (!compression)
201 {
202 commonFieldSize = 4 /* CRC */ + 6 /* tail */;
203 if (channelWidth <= 40)
204 {
205 commonFieldSize += 8; // only one allocation subfield
206 }
207 else
208 {
209 commonFieldSize +=
210 8 * (channelWidth / 40) /* one allocation field per 40 MHz */ + 1 /* center RU */;
211 }
212 }
213
214 auto numRusPerContentChannel = GetNumRusPerEhtSigBContentChannel(channelWidth,
215 ehtPpduType,
216 ruAllocation,
217 compression,
218 numMuMimoUsers);
219 auto maxNumRusPerContentChannel =
220 std::max(numRusPerContentChannel.first, numRusPerContentChannel.second);
221 auto maxNumUserBlockFields = maxNumRusPerContentChannel /
222 2; // handle last user block with single user, if any, further down
223 std::size_t userSpecificFieldSize =
224 maxNumUserBlockFields * (2 * 21 /* user fields (2 users) */ + 4 /* tail */ + 6 /* CRC */);
225 if (maxNumRusPerContentChannel % 2 != 0)
226 {
227 userSpecificFieldSize += 21 /* last user field */ + 4 /* CRC */ + 6 /* tail */;
228 }
229
230 return commonFieldSize + userSpecificFieldSize;
231}
232
235{
236 return Ptr<WifiPpdu>(new EhtPpdu(*this), false);
237}
238
239} // namespace ns3
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
Definition eht-phy.cc:232
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...
Definition eht-ppdu.cc:180
bool IsDlMu() const override
Return true if the PPDU is a DL MU PPDU.
Definition eht-ppdu.cc:98
bool IsUlMu() const override
Return true if the PPDU is an UL MU PPDU.
Definition eht-ppdu.cc:104
void SetEhtPhyHeader(const WifiTxVector &txVector)
Fill in the EHT PHY header.
Definition eht-ppdu.cc:44
static uint32_t GetEhtSigFieldSize(MHz_u channelWidth, const std::vector< uint8_t > &ruAllocation, uint8_t ehtPpduType, bool compression, std::size_t numMuMimoUsers)
Get variable length EHT-SIG field size.
Definition eht-ppdu.cc:192
static std::pair< std::size_t, std::size_t > GetNumRusPerEhtSigBContentChannel(MHz_u channelWidth, uint8_t ehtPpduType, const std::vector< uint8_t > &ruAllocation, bool compression, std::size_t numMuMimoUsers)
Get the number of RUs per EHT-SIG-B content channel.
Definition eht-ppdu.cc:163
Ptr< WifiPpdu > Copy() const override
Copy this instance.
Definition eht-ppdu.cc:234
void SetTxVectorFromPhyHeaders(WifiTxVector &txVector) const override
Fill in the TXVECTOR from PHY headers.
Definition eht-ppdu.cc:110
void SetPhyHeaders(const WifiTxVector &txVector, Time ppduDuration)
Fill in the PHY headers.
Definition eht-ppdu.cc:37
WifiPpduType GetType() const override
Return the PPDU type (.
Definition eht-ppdu.cc:79
EhtPhyHeader m_ehtPhyHeader
the EHT PHY header
Definition eht-ppdu.h:159
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.
Definition eht-ppdu.cc:24
HE PPDU (11ax)
Definition he-ppdu.h:39
TxPsdFlag
The transmit power spectral density flag, namely used to correctly build PSDs for pre-HE and HE porti...
Definition he-ppdu.h:104
static Time GetGuardIntervalFromEncoding(uint8_t giAndNltfSize)
Convert guard interval from its encoding in HE-SIG-A.
Definition he-ppdu.cc:749
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...
Definition he-ppdu.cc:544
void SetHeMuUserInfos(WifiTxVector &txVector, const RuAllocation &ruAllocation, const HeSigBContentChannels &contentChannels, bool sigBCompression, uint8_t numMuMimoUsers) const
Reconstruct HeMuUserInfoMap from HE-SIG-B header.
Definition he-ppdu.cc:214
std::vector< std::vector< HeSigBUserSpecificField > > HeSigBContentChannels
HE SIG-B Content Channels.
Definition he-ppdu.h:50
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.
Definition he-ppdu.cc:475
static MHz_u GetChannelWidthMhzFromEncoding(uint8_t bandwidth)
Convert channel width expressed in MHz from bandwidth field encoding in HE-SIG-A.
Definition he-ppdu.cc:706
static uint8_t GetChannelWidthEncodingFromMhz(MHz_u channelWidth)
Convert channel width expressed in MHz to bandwidth field encoding in HE-SIG-A.
Definition he-ppdu.cc:685
static uint8_t GetGuardIntervalAndNltfEncoding(Time guardInterval, uint8_t nltf)
Convert guard interval and NLTF to its encoding in HE-SIG-A.
Definition he-ppdu.cc:727
uint16_t GetLength() const
Return the LENGTH field of L-SIG (in bytes).
Definition ofdm-ppdu.cc:199
LSigHeader m_lSig
the L-SIG PHY header
Definition ofdm-ppdu.h:99
Smart pointer class similar to boost::intrusive_ptr.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
static WifiMode GetVhtMcs(uint8_t index)
Return the VHT MCS corresponding to the provided index.
Definition vht-phy.cc:334
uint8_t GetMcsValue() const
Definition wifi-mode.cc:152
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
Definition wifi-ppdu.h:201
WifiPreamble m_preamble
the PHY preamble
Definition wifi-ppdu.h:192
WifiConstPsduMap m_psdus
the PSDUs contained in this PPDU
Definition wifi-ppdu.h:194
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.
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,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#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)
@ WIFI_PREAMBLE_EHT_TB
@ WIFI_PREAMBLE_EHT_MU
@ WIFI_PPDU_TYPE_DL_MU
@ WIFI_PPDU_TYPE_UL_MU
@ WIFI_PPDU_TYPE_SU
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
bool IsDlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a downlink multi-user transmission.
std::vector< uint8_t > RuAllocation
8 bit RU_ALLOCATION per 20 MHz
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition wifi-mode.h:24
bool IsUlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a uplink multi-user transmission.
PHY header for EHT MU PPDUs.
Definition eht-ppdu.h:51
uint8_t m_bandwidth
Bandwidth field.
Definition eht-ppdu.h:54
PHY header for EHT TB PPDUs.
Definition eht-ppdu.h:38
uint8_t m_bandwidth
Bandwidth field.
Definition eht-ppdu.h:41
uint32_t prev