A Discrete-Event Network Simulator
API
ht-ppdu.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Orange Labs
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: Rediet <getachew.redieteab@orange.com>
18 * Muhammad Iqbal Rochman <muhiqbalcr@uchicago.edu>
19 * Sébastien Deronne <sebastien.deronne@gmail.com> (HtSigHeader)
20 */
21
22#include "ht-ppdu.h"
23
24#include "ht-phy.h"
25
26#include "ns3/log.h"
27#include "ns3/wifi-phy.h"
28#include "ns3/wifi-psdu.h"
29#include "ns3/wifi-utils.h"
30
31namespace ns3
32{
33
35
37 const WifiTxVector& txVector,
38 uint16_t txCenterFreq,
39 Time ppduDuration,
40 WifiPhyBand band,
41 uint64_t uid)
42 : OfdmPpdu(psdu,
43 txVector,
44 txCenterFreq,
45 band,
46 uid,
47 false) // don't instantiate LSigHeader of OfdmPpdu
48{
49 NS_LOG_FUNCTION(this << psdu << txVector << txCenterFreq << ppduDuration << band << uid);
50 SetPhyHeaders(txVector, ppduDuration, psdu->GetSize());
51}
52
53void
54HtPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration, std::size_t psduSize)
55{
56 NS_LOG_FUNCTION(this << txVector << ppduDuration << psduSize);
57
58#ifdef NS3_BUILD_PROFILE_DEBUG
59 LSigHeader lSig;
60 SetLSigHeader(lSig, ppduDuration);
61
62 HtSigHeader htSig;
63 SetHtSigHeader(htSig, txVector, psduSize);
64
65 m_phyHeaders->AddHeader(htSig);
67#else
68 SetLSigHeader(m_lSig, ppduDuration);
69 SetHtSigHeader(m_htSig, txVector, psduSize);
70#endif
71}
72
73void
74HtPpdu::SetLSigHeader(LSigHeader& lSig, Time ppduDuration) const
75{
76 uint8_t sigExtension = 0;
78 {
79 sigExtension = 6;
80 }
81 uint16_t length = ((ceil((static_cast<double>(ppduDuration.GetNanoSeconds() - (20 * 1000) -
82 (sigExtension * 1000)) /
83 1000) /
84 4.0) *
85 3) -
86 3);
87 lSig.SetLength(length);
88}
89
90void
91HtPpdu::SetHtSigHeader(HtSigHeader& htSig, const WifiTxVector& txVector, std::size_t psduSize) const
92{
93 htSig.SetMcs(txVector.GetMode().GetMcsValue());
94 htSig.SetChannelWidth(txVector.GetChannelWidth());
95 htSig.SetHtLength(psduSize);
96 htSig.SetAggregation(txVector.IsAggregation());
97 htSig.SetShortGuardInterval(txVector.GetGuardInterval() == 400);
98}
99
102{
103 WifiTxVector txVector;
104 txVector.SetPreambleType(m_preamble);
105
106#ifdef NS3_BUILD_PROFILE_DEBUG
107 auto phyHeaders = m_phyHeaders->Copy();
108
109 LSigHeader lSig;
110 if (phyHeaders->RemoveHeader(lSig) == 0)
111 {
112 NS_FATAL_ERROR("Missing L-SIG header in HT PPDU");
113 }
114
115 HtSigHeader htSig;
116 if (phyHeaders->RemoveHeader(htSig) == 0)
117 {
118 NS_FATAL_ERROR("Missing HT-SIG header in HT PPDU");
119 }
120
121 SetTxVectorFromPhyHeaders(txVector, lSig, htSig);
122#else
123 SetTxVectorFromPhyHeaders(txVector, m_lSig, m_htSig);
124#endif
125
126 return txVector;
127}
128
129void
131 const LSigHeader& lSig,
132 const HtSigHeader& htSig) const
133{
134 txVector.SetMode(HtPhy::GetHtMcs(htSig.GetMcs()));
135 txVector.SetChannelWidth(htSig.GetChannelWidth());
136 txVector.SetNss(1 + (htSig.GetMcs() / 8));
137 txVector.SetGuardInterval(htSig.GetShortGuardInterval() ? 400 : 800);
138 txVector.SetAggregation(htSig.GetAggregation());
139}
140
141Time
143{
144 Time ppduDuration = Seconds(0);
145 const WifiTxVector& txVector = GetTxVector();
146
147 uint16_t htLength = 0;
148#ifdef NS3_BUILD_PROFILE_DEBUG
149 auto phyHeaders = m_phyHeaders->Copy();
150
151 LSigHeader lSig;
152 phyHeaders->RemoveHeader(lSig);
153 HtSigHeader htSig;
154 phyHeaders->RemoveHeader(htSig);
155
156 htLength = htSig.GetHtLength();
157#else
158 htLength = m_htSig.GetHtLength();
159#endif
160
161 ppduDuration = WifiPhy::CalculateTxDuration(htLength, txVector, m_band);
162 return ppduDuration;
163}
164
167{
168 return Ptr<WifiPpdu>(new HtPpdu(*this), false);
169}
170
172 : m_mcs(0),
173 m_cbw20_40(0),
174 m_htLength(0),
175 m_aggregation(0),
176 m_sgi(0)
177{
178}
179
180TypeId
182{
183 static TypeId tid = TypeId("ns3::HtSigHeader")
184 .SetParent<Header>()
185 .SetGroupName("Wifi")
186 .AddConstructor<HtSigHeader>();
187 return tid;
188}
189
190TypeId
192{
193 return GetTypeId();
194}
195
196void
197HtPpdu::HtSigHeader::Print(std::ostream& os) const
198{
199 os << "MCS=" << +m_mcs << " HT_LENGTH=" << m_htLength << " CHANNEL_WIDTH=" << GetChannelWidth()
200 << " SGI=" << +m_sgi << " AGGREGATION=" << +m_aggregation;
201}
202
205{
206 return 6;
207}
208
209void
211{
212 NS_ASSERT(mcs <= 31);
213 m_mcs = mcs;
214}
215
216uint8_t
218{
219 return m_mcs;
220}
221
222void
224{
225 m_cbw20_40 = (channelWidth > 20) ? 1 : 0;
226}
227
228uint16_t
230{
231 return m_cbw20_40 ? 40 : 20;
232}
233
234void
236{
237 m_htLength = length;
238}
239
240uint16_t
242{
243 return m_htLength;
244}
245
246void
248{
249 m_aggregation = aggregation ? 1 : 0;
250}
251
252bool
254{
255 return m_aggregation;
256}
257
258void
260{
261 m_sgi = sgi ? 1 : 0;
262}
263
264bool
266{
267 return m_sgi;
268}
269
270void
272{
273 uint8_t byte = m_mcs;
274 byte |= ((m_cbw20_40 & 0x01) << 7);
275 start.WriteU8(byte);
276 start.WriteU16(m_htLength);
277 byte = (0x01 << 2); // Set Reserved bit #2 to 1
278 byte |= ((m_aggregation & 0x01) << 3);
279 byte |= ((m_sgi & 0x01) << 7);
280 start.WriteU8(byte);
281 start.WriteU16(0);
282}
283
286{
288 uint8_t byte = i.ReadU8();
289 m_mcs = byte & 0x7f;
290 m_cbw20_40 = ((byte >> 7) & 0x01);
291 m_htLength = i.ReadU16();
292 byte = i.ReadU8();
293 m_aggregation = ((byte >> 3) & 0x01);
294 m_sgi = ((byte >> 7) & 0x01);
295 i.ReadU16();
296 return i.GetDistanceFrom(start);
297}
298
299} // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
uint32_t GetDistanceFrom(const Iterator &o) const
Definition: buffer.cc:783
uint16_t ReadU16()
Definition: buffer.h:1035
Protocol header serialization and deserialization.
Definition: header.h:44
static WifiMode GetHtMcs(uint8_t index)
Return the HT MCS corresponding to the provided index.
Definition: ht-phy.cc:490
HT PHY header (HT-SIG1/2).
Definition: ht-ppdu.h:52
void Print(std::ostream &os) const override
Definition: ht-ppdu.cc:197
uint16_t GetHtLength() const
Return the HT length field of HT-SIG (in bytes).
Definition: ht-ppdu.cc:241
uint8_t GetMcs() const
Return the MCS field of HT-SIG.
Definition: ht-ppdu.cc:217
void SetHtLength(uint16_t length)
Fill the HT length field of HT-SIG (in bytes).
Definition: ht-ppdu.cc:235
bool GetAggregation() const
Return the aggregation field of HT-SIG.
Definition: ht-ppdu.cc:253
void SetMcs(uint8_t mcs)
Fill the MCS field of HT-SIG.
Definition: ht-ppdu.cc:210
bool GetShortGuardInterval() const
Return the short guard interval field of HT-SIG.
Definition: ht-ppdu.cc:265
uint32_t Deserialize(Buffer::Iterator start) override
Definition: ht-ppdu.cc:285
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: ht-ppdu.cc:191
uint16_t GetChannelWidth() const
Return the channel width (in MHz).
Definition: ht-ppdu.cc:229
void SetAggregation(bool aggregation)
Fill the aggregation field of HT-SIG.
Definition: ht-ppdu.cc:247
uint32_t GetSerializedSize() const override
Definition: ht-ppdu.cc:204
void SetChannelWidth(uint16_t channelWidth)
Fill the channel width field of HT-SIG (in MHz).
Definition: ht-ppdu.cc:223
void SetShortGuardInterval(bool sgi)
Fill the short guard interval field of HT-SIG.
Definition: ht-ppdu.cc:259
static TypeId GetTypeId()
Get the type ID.
Definition: ht-ppdu.cc:181
void Serialize(Buffer::Iterator start) const override
Definition: ht-ppdu.cc:271
WifiTxVector DoGetTxVector() const override
Get the TXVECTOR used to send the PPDU.
Definition: ht-ppdu.cc:101
Ptr< WifiPpdu > Copy() const override
Copy this instance.
Definition: ht-ppdu.cc:166
void SetHtSigHeader(HtSigHeader &htSig, const WifiTxVector &txVector, std::size_t psduSize) const
Fill in the HT-SIG header.
Definition: ht-ppdu.cc:91
virtual void SetLSigHeader(LSigHeader &lSig, Time ppduDuration) const
Fill in the L-SIG header.
Definition: ht-ppdu.cc:74
void SetPhyHeaders(const WifiTxVector &txVector, Time ppduDuration, std::size_t psduSize)
Fill in the PHY headers.
Definition: ht-ppdu.cc:54
void SetTxVectorFromPhyHeaders(WifiTxVector &txVector, const LSigHeader &lSig, const HtSigHeader &htSig) const
Fill in the TXVECTOR from PHY headers.
Definition: ht-ppdu.cc:130
Time GetTxDuration() const override
Get the total transmission duration of the PPDU.
Definition: ht-ppdu.cc:142
HtPpdu(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector, uint16_t txCenterFreq, Time ppduDuration, WifiPhyBand band, uint64_t uid)
Create an HT PPDU.
Definition: ht-ppdu.cc:36
OFDM and ERP OFDM L-SIG PHY header.
Definition: ofdm-ppdu.h:55
void SetLength(uint16_t length)
Fill the LENGTH field of L-SIG (in bytes).
Definition: ofdm-ppdu.cc:257
OFDM PPDU (11a)
Definition: ofdm-ppdu.h:48
WifiPhyBand m_band
the WifiPhyBand used to transmit that PPDU
Definition: ofdm-ppdu.h:125
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:417
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1480
WifiPreamble m_preamble
the PHY preamble
Definition: wifi-ppdu.h:201
const WifiTxVector & GetTxVector() const
Get the TXVECTOR used to send the PPDU.
Definition: wifi-ppdu.cc:82
Ptr< Packet > m_phyHeaders
the PHY headers contained in this PPDU
Definition: wifi-ppdu.h:211
uint32_t GetSize() const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:273
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint16_t GetGuardInterval() const
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
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.
bool IsAggregation() const
Checks whether the PSDU contains A-MPDU.
uint16_t GetChannelWidth() const
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetNss(uint8_t nss)
Sets the number of Nss.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
#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_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#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 ",...
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
Declaration of ns3::HtPhy class.
Declaration of ns3::HtPpdu class.
Every class exported by the ns3 library is enclosed in the ns3 namespace.