A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
vht-ppdu.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 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> (VhtSigHeader)
20 */
21
22#include "vht-ppdu.h"
23
24#include "vht-phy.h"
25
26#include "ns3/log.h"
27#include "ns3/wifi-phy.h"
28#include "ns3/wifi-psdu.h"
29
30namespace ns3
31{
32
34
36 const WifiTxVector& txVector,
37 uint16_t txCenterFreq,
38 Time ppduDuration,
39 WifiPhyBand band,
40 uint64_t uid)
41 : OfdmPpdu(psdu,
42 txVector,
43 txCenterFreq,
44 band,
45 uid,
46 false) // don't instantiate LSigHeader of OfdmPpdu
47{
48 NS_LOG_FUNCTION(this << psdu << txVector << txCenterFreq << ppduDuration << band << uid);
49 SetPhyHeaders(txVector, ppduDuration);
50}
51
52void
53VhtPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
54{
55 NS_LOG_FUNCTION(this << txVector << ppduDuration);
56
57#ifdef NS3_BUILD_PROFILE_DEBUG
58 LSigHeader lSig;
59 SetLSigHeader(lSig, ppduDuration);
60
61 VhtSigHeader vhtSig;
62 SetVhtSigHeader(vhtSig, txVector, ppduDuration);
63
64 m_phyHeaders->AddHeader(vhtSig);
66#else
67 SetLSigHeader(m_lSig, ppduDuration);
68 SetVhtSigHeader(m_vhtSig, txVector, ppduDuration);
69#endif
70}
71
72void
73VhtPpdu::SetLSigHeader(LSigHeader& lSig, Time ppduDuration) const
74{
75 uint16_t length =
76 ((ceil((static_cast<double>(ppduDuration.GetNanoSeconds() - (20 * 1000)) / 1000) / 4.0) *
77 3) -
78 3);
79 lSig.SetLength(length);
80}
81
82void
84 const WifiTxVector& txVector,
85 Time ppduDuration) const
86{
88 vhtSig.SetChannelWidth(txVector.GetChannelWidth());
89 vhtSig.SetShortGuardInterval(txVector.GetGuardInterval() == 400);
90 uint32_t nSymbols =
91 (static_cast<double>(
92 (ppduDuration - WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector))
93 .GetNanoSeconds()) /
94 (3200 + txVector.GetGuardInterval()));
95 if (txVector.GetGuardInterval() == 400)
96 {
97 vhtSig.SetShortGuardIntervalDisambiguation((nSymbols % 10) == 9);
98 }
99 vhtSig.SetSuMcs(txVector.GetMode().GetMcsValue());
100 vhtSig.SetNStreams(txVector.GetNss());
101}
102
105{
106 WifiTxVector txVector;
107 txVector.SetPreambleType(m_preamble);
108
109#ifdef NS3_BUILD_PROFILE_DEBUG
110 auto phyHeaders = m_phyHeaders->Copy();
111
112 LSigHeader lSig;
113 if (phyHeaders->RemoveHeader(lSig) == 0)
114 {
115 NS_FATAL_ERROR("Missing L-SIG header in VHT PPDU");
116 }
117
118 VhtSigHeader vhtSig;
119 if (phyHeaders->RemoveHeader(vhtSig) == 0)
120 {
121 NS_FATAL_ERROR("Missing VHT-SIG header in VHT PPDU");
122 }
123
124 SetTxVectorFromPhyHeaders(txVector, lSig, vhtSig);
125#else
126 SetTxVectorFromPhyHeaders(txVector, m_lSig, m_vhtSig);
127#endif
128
129 return txVector;
130}
131
132void
134 const LSigHeader& lSig,
135 const VhtSigHeader& vhtSig) const
136{
137 txVector.SetMode(VhtPhy::GetVhtMcs(vhtSig.GetSuMcs()));
138 txVector.SetChannelWidth(vhtSig.GetChannelWidth());
139 txVector.SetNss(vhtSig.GetNStreams());
140 txVector.SetGuardInterval(vhtSig.GetShortGuardInterval() ? 400 : 800);
141 txVector.SetAggregation(GetPsdu()->IsAggregate());
142}
143
144Time
146{
147 Time ppduDuration = Seconds(0);
148 const WifiTxVector& txVector = GetTxVector();
149
150 uint16_t length = 0;
151 bool sgi = false;
152 bool sgiDisambiguation = false;
153#ifdef NS3_BUILD_PROFILE_DEBUG
154 auto phyHeaders = m_phyHeaders->Copy();
155
156 LSigHeader lSig;
157 phyHeaders->RemoveHeader(lSig);
158 VhtSigHeader vhtSig;
159 phyHeaders->RemoveHeader(vhtSig);
160
161 length = lSig.GetLength();
162 sgi = vhtSig.GetShortGuardInterval();
163 sgiDisambiguation = vhtSig.GetShortGuardIntervalDisambiguation();
164#else
165 length = m_lSig.GetLength();
166 sgi = m_vhtSig.GetShortGuardInterval();
167 sgiDisambiguation = m_vhtSig.GetShortGuardIntervalDisambiguation();
168#endif
169
170 Time tSymbol = NanoSeconds(3200 + txVector.GetGuardInterval());
171 Time preambleDuration = WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector);
172 Time calculatedDuration = MicroSeconds(((ceil(static_cast<double>(length + 3) / 3)) * 4) + 20);
173 uint32_t nSymbols =
174 floor(static_cast<double>((calculatedDuration - preambleDuration).GetNanoSeconds()) /
175 tSymbol.GetNanoSeconds());
176 if (sgi && sgiDisambiguation)
177 {
178 nSymbols--;
179 }
180 ppduDuration = preambleDuration + (nSymbols * tSymbol);
181 return ppduDuration;
182}
183
186{
187 return Ptr<WifiPpdu>(new VhtPpdu(*this), false);
188}
189
192{
194}
195
197 : m_bw(0),
198 m_nsts(0),
199 m_sgi(0),
200 m_sgi_disambiguation(0),
201 m_suMcs(0),
202 m_mu(false)
203{
204}
205
206TypeId
208{
209 static TypeId tid = TypeId("ns3::VhtSigHeader")
210 .SetParent<Header>()
211 .SetGroupName("Wifi")
212 .AddConstructor<VhtSigHeader>();
213 return tid;
214}
215
216TypeId
218{
219 return GetTypeId();
220}
221
222void
223VhtPpdu::VhtSigHeader::Print(std::ostream& os) const
224{
225 os << "SU_MCS=" << +m_suMcs << " CHANNEL_WIDTH=" << GetChannelWidth() << " SGI=" << +m_sgi
226 << " NSTS=" << +m_nsts << " MU=" << +m_mu;
227}
228
231{
232 uint32_t size = 0;
233 size += 3; // VHT-SIG-A1
234 size += 3; // VHT-SIG-A2
235 if (m_mu)
236 {
237 size += 4; // VHT-SIG-B
238 }
239 return size;
240}
241
242void
244{
245 m_mu = mu;
246}
247
248void
250{
251 if (channelWidth == 160)
252 {
253 m_bw = 3;
254 }
255 else if (channelWidth == 80)
256 {
257 m_bw = 2;
258 }
259 else if (channelWidth == 40)
260 {
261 m_bw = 1;
262 }
263 else
264 {
265 m_bw = 0;
266 }
267}
268
269uint16_t
271{
272 if (m_bw == 3)
273 {
274 return 160;
275 }
276 else if (m_bw == 2)
277 {
278 return 80;
279 }
280 else if (m_bw == 1)
281 {
282 return 40;
283 }
284 else
285 {
286 return 20;
287 }
288}
289
290void
292{
293 NS_ASSERT(nStreams <= 8);
294 m_nsts = (nStreams - 1);
295}
296
297uint8_t
299{
300 return (m_nsts + 1);
301}
302
303void
305{
306 m_sgi = sgi ? 1 : 0;
307}
308
309bool
311{
312 return m_sgi;
313}
314
315void
317{
318 m_sgi_disambiguation = disambiguation ? 1 : 0;
319}
320
321bool
323{
324 return m_sgi_disambiguation;
325}
326
327void
329{
330 NS_ASSERT(mcs <= 9);
331 m_suMcs = mcs;
332}
333
334uint8_t
336{
337 return m_suMcs;
338}
339
340void
342{
343 // VHT-SIG-A1
344 uint8_t byte = m_bw;
345 byte |= (0x01 << 2); // Set Reserved bit #2 to 1
346 start.WriteU8(byte);
347 uint16_t bytes = (m_nsts & 0x07) << 2;
348 bytes |= (0x01 << (23 - 8)); // Set Reserved bit #23 to 1
349 start.WriteU16(bytes);
350
351 // VHT-SIG-A2
352 byte = m_sgi & 0x01;
353 byte |= ((m_sgi_disambiguation & 0x01) << 1);
354 byte |= ((m_suMcs & 0x0f) << 4);
355 start.WriteU8(byte);
356 bytes = (0x01 << (9 - 8)); // Set Reserved bit #9 to 1
357 start.WriteU16(bytes);
358
359 if (m_mu)
360 {
361 // VHT-SIG-B
362 start.WriteU32(0);
363 }
364}
365
368{
369 Buffer::Iterator i = start;
370
371 // VHT-SIG-A1
372 uint8_t byte = i.ReadU8();
373 m_bw = byte & 0x03;
374 uint16_t bytes = i.ReadU16();
375 m_nsts = ((bytes >> 2) & 0x07);
376
377 // VHT-SIG-A2
378 byte = i.ReadU8();
379 m_sgi = byte & 0x01;
380 m_sgi_disambiguation = ((byte >> 1) & 0x01);
381 m_suMcs = ((byte >> 4) & 0x0f);
382 i.ReadU16();
383
384 if (m_mu)
385 {
386 // VHT-SIG-B
387 i.ReadU32();
388 }
389
390 return i.GetDistanceFrom(start);
391}
392
393} // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
uint32_t ReadU32()
Definition: buffer.cc:969
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
OFDM and ERP OFDM L-SIG PHY header.
Definition: ofdm-ppdu.h:55
uint16_t GetLength() const
Return the LENGTH field of L-SIG (in bytes).
Definition: ofdm-ppdu.cc:264
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
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
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
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:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
static WifiMode GetVhtMcs(uint8_t index)
Return the VHT MCS corresponding to the provided index.
Definition: vht-phy.cc:344
VHT PHY header (VHT-SIG-A1/A2/B).
Definition: vht-ppdu.h:52
static TypeId GetTypeId()
Get the type ID.
Definition: vht-ppdu.cc:207
void SetNStreams(uint8_t nStreams)
Fill the number of streams field of VHT-SIG-A1.
Definition: vht-ppdu.cc:291
void SetChannelWidth(uint16_t channelWidth)
Fill the channel width field of VHT-SIG-A1 (in MHz).
Definition: vht-ppdu.cc:249
uint16_t GetChannelWidth() const
Return the channel width (in MHz).
Definition: vht-ppdu.cc:270
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: vht-ppdu.cc:217
uint32_t Deserialize(Buffer::Iterator start) override
Definition: vht-ppdu.cc:367
uint8_t GetSuMcs() const
Return the SU VHT MCS field of VHT-SIG-A2.
Definition: vht-ppdu.cc:335
uint8_t GetNStreams() const
Return the number of streams.
Definition: vht-ppdu.cc:298
bool GetShortGuardInterval() const
Return the short GI field of VHT-SIG-A2.
Definition: vht-ppdu.cc:310
void Serialize(Buffer::Iterator start) const override
Definition: vht-ppdu.cc:341
void SetMuFlag(bool mu)
Set the Multi-User (MU) flag.
Definition: vht-ppdu.cc:243
void SetSuMcs(uint8_t mcs)
Fill the SU VHT MCS field of VHT-SIG-A2.
Definition: vht-ppdu.cc:328
void SetShortGuardIntervalDisambiguation(bool disambiguation)
Fill the short GI NSYM disambiguation field of VHT-SIG-A2.
Definition: vht-ppdu.cc:316
bool GetShortGuardIntervalDisambiguation() const
Return the short GI NSYM disambiguation field of VHT-SIG-A2.
Definition: vht-ppdu.cc:322
uint32_t GetSerializedSize() const override
Definition: vht-ppdu.cc:230
void SetShortGuardInterval(bool sgi)
Fill the short guard interval field of VHT-SIG-A2.
Definition: vht-ppdu.cc:304
void Print(std::ostream &os) const override
Definition: vht-ppdu.cc:223
VHT PPDU (11ac)
Definition: vht-ppdu.h:45
virtual void SetPhyHeaders(const WifiTxVector &txVector, Time ppduDuration)
Fill in the PHY headers.
Definition: vht-ppdu.cc:53
VhtPpdu(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector, uint16_t txCenterFreq, Time ppduDuration, WifiPhyBand band, uint64_t uid)
Create a VHT PPDU.
Definition: vht-ppdu.cc:35
WifiPpduType GetType() const override
Return the PPDU type (.
Definition: vht-ppdu.cc:191
WifiTxVector DoGetTxVector() const override
Get the TXVECTOR used to send the PPDU.
Definition: vht-ppdu.cc:104
void SetTxVectorFromPhyHeaders(WifiTxVector &txVector, const LSigHeader &lSig, const VhtSigHeader &vhtSig) const
Fill in the TXVECTOR from PHY headers.
Definition: vht-ppdu.cc:133
void SetVhtSigHeader(VhtSigHeader &vhtSig, const WifiTxVector &txVector, Time ppduDuration) const
Fill in the VHT-SIG header.
Definition: vht-ppdu.cc:83
Time GetTxDuration() const override
Get the total transmission duration of the PPDU.
Definition: vht-ppdu.cc:145
Ptr< WifiPpdu > Copy() const override
Copy this instance.
Definition: vht-ppdu.cc:185
virtual void SetLSigHeader(LSigHeader &lSig, Time ppduDuration) const
Fill in the L-SIG header.
Definition: vht-ppdu.cc:73
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1473
WifiPreamble m_preamble
the PHY preamble
Definition: wifi-ppdu.h:201
Ptr< const WifiPsdu > GetPsdu() const
Get the payload of the PPDU.
Definition: wifi-ppdu.cc:117
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
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.
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.
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 MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1372
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
WifiPpduType
The type of PPDU (SU, DL MU, or UL MU)
@ WIFI_PREAMBLE_VHT_MU
@ WIFI_PPDU_TYPE_DL_MU
@ WIFI_PPDU_TYPE_SU
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Declaration of ns3::VhtPhy class.
Declaration of ns3::VhtPpdu class.