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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
18 */
19
20#include "eht-ppdu.h"
21
22#include "eht-phy.h"
23
24#include "ns3/log.h"
25#include "ns3/wifi-phy-operating-channel.h"
26#include "ns3/wifi-psdu.h"
27
28#include <numeric>
29
30namespace ns3
31{
32
34
36 const WifiTxVector& txVector,
37 const WifiPhyOperatingChannel& channel,
38 Time ppduDuration,
39 uint64_t uid,
40 TxPsdFlag flag)
41 : HePpdu(psdus, txVector, channel, ppduDuration, uid, flag)
42{
43 NS_LOG_FUNCTION(this << psdus << txVector << channel << ppduDuration << uid << flag);
44 SetPhyHeaders(txVector, ppduDuration);
45}
46
47void
48EhtPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
49{
50 NS_LOG_FUNCTION(this << txVector << ppduDuration);
51 SetEhtPhyHeader(txVector);
52}
53
54void
56{
57 const auto bssColor = txVector.GetBssColor();
58 NS_ASSERT(bssColor < 64);
60 {
61 const auto p20Index = m_operatingChannel.GetPrimaryChannelIndex(20);
64 .m_bssColor = bssColor,
65 .m_ppduType = txVector.GetEhtPpduType(),
66 .m_ehtSigMcs = txVector.GetSigBMode().GetMcsValue(),
67 .m_giLtfSize = GetGuardIntervalAndNltfEncoding(txVector.GetGuardInterval(),
68 2 /*NLTF currently unused*/),
69 /* See section 36.3.12.8.2 of IEEE 802.11be D3.0 (EHT-SIG content channels):
70 * In non-OFDMA transmission, the Common field of the EHT-SIG content channel does not
71 * contain the RU Allocation subfield. For non-OFDMA transmission except for EHT
72 * sounding NDP, the Common field of the EHT-SIG content channel is encoded together
73 * with the first User field and this encoding block contains a CRC and Tail, referred
74 * to as a common encoding block. */
75 .m_ruAllocationA =
76 txVector.IsMu() ? std::optional{txVector.GetRuAllocation(p20Index)} : std::nullopt,
77 // TODO: RU Allocation-B not supported yet
78 .m_contentChannels = GetEhtSigContentChannels(txVector, p20Index)});
79 }
80 else if (ns3::IsUlMu(m_preamble))
81 {
84 .m_bssColor = bssColor,
85 .m_ppduType = txVector.GetEhtPpduType()});
86 }
87}
88
91{
92 if (m_psdus.contains(SU_STA_ID))
93 {
94 return WIFI_PPDU_TYPE_SU;
95 }
96 switch (m_preamble)
97 {
102 default:
103 NS_ASSERT_MSG(false, "invalid preamble " << m_preamble);
104 return WIFI_PPDU_TYPE_SU;
105 }
106}
107
108bool
110{
111 return (m_preamble == WIFI_PREAMBLE_EHT_MU) && !m_psdus.contains(SU_STA_ID);
112}
113
114bool
116{
117 return (m_preamble == WIFI_PREAMBLE_EHT_TB) && !m_psdus.contains(SU_STA_ID);
118}
119
120void
122{
123 txVector.SetLength(m_lSig.GetLength());
124 txVector.SetAggregation(m_psdus.size() > 1 || m_psdus.begin()->second->IsAggregate());
126 {
127 auto ehtPhyHeader = std::get_if<EhtMuPhyHeader>(&m_ehtPhyHeader);
128 NS_ASSERT(ehtPhyHeader);
129 txVector.SetChannelWidth(GetChannelWidthMhzFromEncoding(ehtPhyHeader->m_bandwidth));
130 txVector.SetBssColor(ehtPhyHeader->m_bssColor);
131 txVector.SetEhtPpduType(ehtPhyHeader->m_ppduType);
132 txVector.SetSigBMode(HePhy::GetVhtMcs(ehtPhyHeader->m_ehtSigMcs));
133 txVector.SetGuardInterval(GetGuardIntervalFromEncoding(ehtPhyHeader->m_giLtfSize));
134 const auto ruAllocation = ehtPhyHeader->m_ruAllocationA; // RU Allocation-B not supported
135 // yet
136 if (const auto p20Index = m_operatingChannel.GetPrimaryChannelIndex(20);
137 ruAllocation.has_value())
138 {
139 txVector.SetRuAllocation(ruAllocation.value(), p20Index);
140 const auto isMuMimo = (ehtPhyHeader->m_ppduType == 2);
141 const auto muMimoUsers =
142 isMuMimo
143 ? std::accumulate(ehtPhyHeader->m_contentChannels.cbegin(),
144 ehtPhyHeader->m_contentChannels.cend(),
145 0,
146 [](uint8_t prev, const auto& cc) { return prev + cc.size(); })
147 : 0;
148 SetHeMuUserInfos(txVector,
149 ruAllocation.value(),
150 ehtPhyHeader->m_contentChannels,
151 ehtPhyHeader->m_ppduType == 2,
152 muMimoUsers);
153 }
154 if (ehtPhyHeader->m_ppduType == 1) // EHT SU
155 {
156 NS_ASSERT(ehtPhyHeader->m_contentChannels.size() == 1 &&
157 ehtPhyHeader->m_contentChannels.front().size() == 1);
158 txVector.SetMode(
159 EhtPhy::GetEhtMcs(ehtPhyHeader->m_contentChannels.front().front().mcs));
160 txVector.SetNss(ehtPhyHeader->m_contentChannels.front().front().nss);
161 }
162 }
163 else if (ns3::IsUlMu(m_preamble))
164 {
165 auto ehtPhyHeader = std::get_if<EhtTbPhyHeader>(&m_ehtPhyHeader);
166 NS_ASSERT(ehtPhyHeader);
167 txVector.SetChannelWidth(GetChannelWidthMhzFromEncoding(ehtPhyHeader->m_bandwidth));
168 txVector.SetBssColor(ehtPhyHeader->m_bssColor);
169 txVector.SetEhtPpduType(ehtPhyHeader->m_ppduType);
170 }
171}
172
173std::pair<std::size_t, std::size_t>
175 uint8_t ehtPpduType,
176 const RuAllocation& ruAllocation,
177 bool compression,
178 std::size_t numMuMimoUsers)
179{
180 if (ehtPpduType == 1)
181 {
182 return {1, 0};
183 }
185 ruAllocation,
186 compression,
187 numMuMimoUsers);
188}
189
191EhtPpdu::GetEhtSigContentChannels(const WifiTxVector& txVector, uint8_t p20Index)
192{
193 if (txVector.GetEhtPpduType() == 1)
194 {
195 // according to spec the TXVECTOR shall have a correct STA-ID even for SU transmission,
196 // but this is not set by the MAC for simplification, so set to 0 for now.
197 return HeSigBContentChannels{{{0, txVector.GetNss(), txVector.GetMode().GetMcsValue()}}};
198 }
199 return HePpdu::GetHeSigBContentChannels(txVector, p20Index);
200}
201
203EhtPpdu::GetEhtSigFieldSize(uint16_t channelWidth,
204 const RuAllocation& ruAllocation,
205 uint8_t ehtPpduType,
206 bool compression,
207 std::size_t numMuMimoUsers)
208{
209 // FIXME: EHT-SIG is not implemented yet, hence this is a copy of HE-SIG-B
210 uint32_t commonFieldSize = 0;
211 if (!compression)
212 {
213 commonFieldSize = 4 /* CRC */ + 6 /* tail */;
214 if (channelWidth <= 40)
215 {
216 commonFieldSize += 8; // only one allocation subfield
217 }
218 else
219 {
220 commonFieldSize +=
221 8 * (channelWidth / 40) /* one allocation field per 40 MHz */ + 1 /* center RU */;
222 }
223 }
224
225 auto numRusPerContentChannel = GetNumRusPerEhtSigBContentChannel(channelWidth,
226 ehtPpduType,
227 ruAllocation,
228 compression,
229 numMuMimoUsers);
230 auto maxNumRusPerContentChannel =
231 std::max(numRusPerContentChannel.first, numRusPerContentChannel.second);
232 auto maxNumUserBlockFields = maxNumRusPerContentChannel /
233 2; // handle last user block with single user, if any, further down
234 std::size_t userSpecificFieldSize =
235 maxNumUserBlockFields * (2 * 21 /* user fields (2 users) */ + 4 /* tail */ + 6 /* CRC */);
236 if (maxNumRusPerContentChannel % 2 != 0)
237 {
238 userSpecificFieldSize += 21 /* last user field */ + 4 /* CRC */ + 6 /* tail */;
239 }
240
241 return commonFieldSize + userSpecificFieldSize;
242}
243
246{
247 return Ptr<WifiPpdu>(new EhtPpdu(*this), false);
248}
249
250} // namespace ns3
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
Definition: eht-phy.cc:243
EHT PPDU (11be)
Definition: eht-ppdu.h:43
static std::pair< std::size_t, std::size_t > GetNumRusPerEhtSigBContentChannel(uint16_t 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:174
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:191
bool IsDlMu() const override
Return true if the PPDU is a DL MU PPDU.
Definition: eht-ppdu.cc:109
static uint32_t GetEhtSigFieldSize(uint16_t 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:203
bool IsUlMu() const override
Return true if the PPDU is an UL MU PPDU.
Definition: eht-ppdu.cc:115
void SetEhtPhyHeader(const WifiTxVector &txVector)
Fill in the EHT PHY header.
Definition: eht-ppdu.cc:55
Ptr< WifiPpdu > Copy() const override
Copy this instance.
Definition: eht-ppdu.cc:245
void SetTxVectorFromPhyHeaders(WifiTxVector &txVector) const override
Fill in the TXVECTOR from PHY headers.
Definition: eht-ppdu.cc:121
void SetPhyHeaders(const WifiTxVector &txVector, Time ppduDuration)
Fill in the PHY headers.
Definition: eht-ppdu.cc:48
WifiPpduType GetType() const override
Return the PPDU type (.
Definition: eht-ppdu.cc:90
EhtPhyHeader m_ehtPhyHeader
the EHT PHY header
Definition: eht-ppdu.h:170
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:35
HE PPDU (11ax)
Definition: he-ppdu.h:50
std::vector< std::vector< HeSigBUserSpecificField > > HeSigBContentChannels
HE SIG-B Content Channels.
Definition: he-ppdu.h:61
static uint16_t GetGuardIntervalFromEncoding(uint8_t giAndNltfSize)
Convert guard interval (in ns) from its encoding in HE-SIG-A.
Definition: he-ppdu.cc:758
static uint16_t GetChannelWidthMhzFromEncoding(uint8_t bandwidth)
Convert channel width expressed in MHz from bandwidth field encoding in HE-SIG-A.
Definition: he-ppdu.cc:716
TxPsdFlag
The transmit power spectral density flag, namely used to correctly build PSDs for pre-HE and HE porti...
Definition: he-ppdu.h:115
static std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(uint16_t channelWidth, const RuAllocation &ruAllocation, bool sigBCompression, uint8_t numMuMimoUsers)
Get the number of STAs per HE-SIG-B content channel.
Definition: he-ppdu.cc:486
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:554
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:225
static uint8_t GetGuardIntervalAndNltfEncoding(uint16_t gi, uint8_t nltf)
Convert guard interval (in ns) and NLTF to its encoding in HE-SIG-A.
Definition: he-ppdu.cc:737
static uint8_t GetChannelWidthEncodingFromMhz(uint16_t channelWidth)
Convert channel width expressed in MHz to bandwidth field encoding in HE-SIG-A.
Definition: he-ppdu.cc:695
uint16_t GetLength() const
Return the LENGTH field of L-SIG (in bytes).
Definition: ofdm-ppdu.cc:210
LSigHeader m_lSig
the L-SIG PHY header
Definition: ofdm-ppdu.h:110
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
static WifiMode GetVhtMcs(uint8_t index)
Return the VHT MCS corresponding to the provided index.
Definition: vht-phy.cc:345
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
Class that keeps track of all information about the current PHY operating channel.
uint8_t GetPrimaryChannelIndex(uint16_t 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:210
WifiPreamble m_preamble
the PHY preamble
Definition: wifi-ppdu.h:202
WifiConstPsduMap m_psdus
the PSDUs contained in this PPDU
Definition: wifi-ppdu.h:204
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.
uint16_t GetGuardInterval() const
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
uint8_t GetBssColor() const
Get the BSS color.
const RuAllocation & GetRuAllocation(uint8_t p20Index) const
Get RU_ALLOCATION field.
void SetGuardInterval(uint16_t 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.
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.
void SetSigBMode(const WifiMode &mode)
Set the MCS used for SIG-B.
void SetBssColor(uint8_t color)
Set the BSS color.
uint16_t GetChannelWidth() 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:66
#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:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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.
std::vector< uint8_t > RuAllocation
8 bit RU_ALLOCATION per 20 MHz
bool IsDlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a downlink multi-user transmission.
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
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:62
uint8_t m_bandwidth
Bandwidth field.
Definition: eht-ppdu.h:65
PHY header for EHT TB PPDUs.
Definition: eht-ppdu.h:49
uint8_t m_bandwidth
Bandwidth field.
Definition: eht-ppdu.h:52
uint32_t prev