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
28namespace ns3
29{
30
32
34 const WifiTxVector& txVector,
35 const WifiPhyOperatingChannel& channel,
36 Time ppduDuration,
37 uint64_t uid,
38 TxPsdFlag flag)
39 : HePpdu(psdus, txVector, channel, ppduDuration, uid, flag)
40{
41 NS_LOG_FUNCTION(this << psdus << txVector << channel << ppduDuration << uid << flag);
42 SetPhyHeaders(txVector, ppduDuration);
43}
44
45void
46EhtPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
47{
48 NS_LOG_FUNCTION(this << txVector << ppduDuration);
49 SetEhtPhyHeader(txVector);
50}
51
52void
54{
55 const auto bssColor = txVector.GetBssColor();
56 NS_ASSERT(bssColor < 64);
58 {
59 const auto p20Index = m_operatingChannel.GetPrimaryChannelIndex(20);
62 .m_bssColor = bssColor,
63 .m_ppduType = txVector.GetEhtPpduType(),
64 .m_ehtSigMcs = txVector.GetSigBMode().GetMcsValue(),
65 .m_giLtfSize = GetGuardIntervalAndNltfEncoding(txVector.GetGuardInterval(),
66 2 /*NLTF currently unused*/),
67 /* See section 36.3.12.8.2 of IEEE 802.11be D3.0 (EHT-SIG content channels):
68 * In non-OFDMA transmission, the Common field of the EHT-SIG content channel does not
69 * contain the RU Allocation subfield. For non-OFDMA transmission except for EHT
70 * sounding NDP, the Common field of the EHT-SIG content channel is encoded together
71 * with the first User field and this encoding block contains a CRC and Tail, referred
72 * to as a common encoding block. */
73 .m_ruAllocationA =
74 txVector.IsMu() ? std::optional{txVector.GetRuAllocation(p20Index)} : std::nullopt,
75 // TODO: RU Allocation-B not supported yet
76 .m_contentChannels = GetEhtSigContentChannels(txVector, p20Index)});
77 }
78 else if (ns3::IsUlMu(m_preamble))
79 {
82 .m_bssColor = bssColor,
83 .m_ppduType = txVector.GetEhtPpduType()});
84 }
85}
86
89{
90 if (m_psdus.count(SU_STA_ID) > 0)
91 {
92 return WIFI_PPDU_TYPE_SU;
93 }
94 switch (m_preamble)
95 {
100 default:
101 NS_ASSERT_MSG(false, "invalid preamble " << m_preamble);
102 return WIFI_PPDU_TYPE_SU;
103 }
104}
105
106bool
108{
109 return (m_preamble == WIFI_PREAMBLE_EHT_MU) && (m_psdus.count(SU_STA_ID) == 0);
110}
111
112bool
114{
115 return (m_preamble == WIFI_PREAMBLE_EHT_TB) && (m_psdus.count(SU_STA_ID) == 0);
116}
117
118void
120{
121 txVector.SetLength(m_lSig.GetLength());
122 txVector.SetAggregation(m_psdus.size() > 1 || m_psdus.begin()->second->IsAggregate());
124 {
125 auto ehtPhyHeader = std::get_if<EhtMuPhyHeader>(&m_ehtPhyHeader);
126 NS_ASSERT(ehtPhyHeader);
127 txVector.SetChannelWidth(GetChannelWidthMhzFromEncoding(ehtPhyHeader->m_bandwidth));
128 txVector.SetBssColor(ehtPhyHeader->m_bssColor);
129 txVector.SetEhtPpduType(ehtPhyHeader->m_ppduType);
130 txVector.SetSigBMode(HePhy::GetVhtMcs(ehtPhyHeader->m_ehtSigMcs));
131 txVector.SetGuardInterval(GetGuardIntervalFromEncoding(ehtPhyHeader->m_giLtfSize));
132 const auto ruAllocation = ehtPhyHeader->m_ruAllocationA; // RU Allocation-B not supported
133 // yet
134 if (const auto p20Index = m_operatingChannel.GetPrimaryChannelIndex(20);
135 ruAllocation.has_value())
136 {
137 txVector.SetRuAllocation(ruAllocation.value(), p20Index);
138 SetHeMuUserInfos(txVector, ruAllocation.value(), ehtPhyHeader->m_contentChannels);
139 }
140 if (ehtPhyHeader->m_ppduType == 1) // EHT SU
141 {
142 NS_ASSERT(ehtPhyHeader->m_contentChannels.size() == 1 &&
143 ehtPhyHeader->m_contentChannels.front().size() == 1);
144 txVector.SetMode(
145 EhtPhy::GetEhtMcs(ehtPhyHeader->m_contentChannels.front().front().mcs));
146 txVector.SetNss(ehtPhyHeader->m_contentChannels.front().front().nss);
147 }
148 }
149 else if (ns3::IsUlMu(m_preamble))
150 {
151 auto ehtPhyHeader = std::get_if<EhtTbPhyHeader>(&m_ehtPhyHeader);
152 NS_ASSERT(ehtPhyHeader);
153 txVector.SetChannelWidth(GetChannelWidthMhzFromEncoding(ehtPhyHeader->m_bandwidth));
154 txVector.SetBssColor(ehtPhyHeader->m_bssColor);
155 txVector.SetEhtPpduType(ehtPhyHeader->m_ppduType);
156 }
157}
158
159std::pair<std::size_t, std::size_t>
161 uint8_t ehtPpduType,
162 const RuAllocation& ruAllocation)
163{
164 if (ehtPpduType == 1)
165 {
166 return {1, 0};
167 }
168 return HePpdu::GetNumRusPerHeSigBContentChannel(channelWidth, ruAllocation);
169}
170
172EhtPpdu::GetEhtSigContentChannels(const WifiTxVector& txVector, uint8_t p20Index)
173{
174 if (txVector.GetEhtPpduType() == 1)
175 {
176 // according to spec the TXVECTOR shall have a correct STA-ID even for SU transmission,
177 // but this is not set by the MAC for simplification, so set to 0 for now.
178 return HeSigBContentChannels{{{0, txVector.GetNss(), txVector.GetMode().GetMcsValue()}}};
179 }
180 return HePpdu::GetHeSigBContentChannels(txVector, p20Index);
181}
182
184EhtPpdu::GetEhtSigFieldSize(uint16_t channelWidth,
185 const RuAllocation& ruAllocation,
186 uint8_t ehtPpduType)
187{
188 // FIXME: EHT-SIG is not implemented yet, hence this is a copy of HE-SIG-B
189 auto commonFieldSize = 4 /* CRC */ + 6 /* tail */;
190 if (channelWidth <= 40)
191 {
192 commonFieldSize += 8; // only one allocation subfield
193 }
194 else
195 {
196 commonFieldSize +=
197 8 * (channelWidth / 40) /* one allocation field per 40 MHz */ + 1 /* center RU */;
198 }
199
200 auto numRusPerContentChannel =
201 GetNumRusPerEhtSigBContentChannel(channelWidth, ehtPpduType, ruAllocation);
202 auto maxNumRusPerContentChannel =
203 std::max(numRusPerContentChannel.first, numRusPerContentChannel.second);
204 auto maxNumUserBlockFields = maxNumRusPerContentChannel /
205 2; // handle last user block with single user, if any, further down
206 std::size_t userSpecificFieldSize =
207 maxNumUserBlockFields * (2 * 21 /* user fields (2 users) */ + 4 /* tail */ + 6 /* CRC */);
208 if (maxNumRusPerContentChannel % 2 != 0)
209 {
210 userSpecificFieldSize += 21 /* last user field */ + 4 /* CRC */ + 6 /* tail */;
211 }
212
213 return commonFieldSize + userSpecificFieldSize;
214}
215
218{
219 return Ptr<WifiPpdu>(new EhtPpdu(*this), false);
220}
221
222} // namespace ns3
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
Definition: eht-phy.cc:238
EHT PPDU (11be)
Definition: eht-ppdu.h:43
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:172
bool IsDlMu() const override
Return true if the PPDU is a DL MU PPDU.
Definition: eht-ppdu.cc:107
static std::pair< std::size_t, std::size_t > GetNumRusPerEhtSigBContentChannel(uint16_t channelWidth, uint8_t ehtPpduType, const std::vector< uint8_t > &ruAllocation)
Get the number of RUs per EHT-SIG-B content channel.
Definition: eht-ppdu.cc:160
bool IsUlMu() const override
Return true if the PPDU is an UL MU PPDU.
Definition: eht-ppdu.cc:113
void SetEhtPhyHeader(const WifiTxVector &txVector)
Fill in the EHT PHY header.
Definition: eht-ppdu.cc:53
Ptr< WifiPpdu > Copy() const override
Copy this instance.
Definition: eht-ppdu.cc:217
void SetTxVectorFromPhyHeaders(WifiTxVector &txVector) const override
Fill in the TXVECTOR from PHY headers.
Definition: eht-ppdu.cc:119
void SetPhyHeaders(const WifiTxVector &txVector, Time ppduDuration)
Fill in the PHY headers.
Definition: eht-ppdu.cc:46
WifiPpduType GetType() const override
Return the PPDU type (.
Definition: eht-ppdu.cc:88
static uint32_t GetEhtSigFieldSize(uint16_t channelWidth, const std::vector< uint8_t > &ruAllocation, uint8_t ehtPpduType)
Get variable length EHT-SIG field size.
Definition: eht-ppdu.cc:184
EhtPhyHeader m_ehtPhyHeader
the EHT PHY header
Definition: eht-ppdu.h:163
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:33
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 std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(uint16_t channelWidth, const RuAllocation &ruAllocation)
Get the number of RUs per HE-SIG-B content channel.
Definition: he-ppdu.cc:449
static uint16_t GetGuardIntervalFromEncoding(uint8_t giAndNltfSize)
Convert guard interval (in ns) from its encoding in HE-SIG-A.
Definition: he-ppdu.cc:671
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:629
TxPsdFlag
The transmit power spectral density flag, namely used to correctly build PSDs for pre-HE and HE porti...
Definition: he-ppdu.h:113
void SetHeMuUserInfos(WifiTxVector &txVector, const RuAllocation &ruAllocation, const HeSigBContentChannels &contentChannels) const
Reconstruct HeMuUserInfoMap from HE-SIG-B header.
Definition: he-ppdu.cc:209
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:497
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:650
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:608
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:78
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:342
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