A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
he-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> (HeSigHeader)
20 */
21
22#include "he-ppdu.h"
23
24#include "he-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
36std::ostream&
37operator<<(std::ostream& os, const HePpdu::TxPsdFlag& flag)
38{
39 switch (flag)
40 {
42 return (os << "PSD_NON_HE_PORTION");
44 return (os << "PSD_HE_PORTION");
45 default:
46 NS_FATAL_ERROR("Invalid PSD flag");
47 return (os << "INVALID");
48 }
49}
50
52 const WifiTxVector& txVector,
53 uint16_t txCenterFreq,
54 Time ppduDuration,
55 WifiPhyBand band,
56 uint64_t uid,
57 TxPsdFlag flag)
58 : OfdmPpdu(psdus.begin()->second,
59 txVector,
60 txCenterFreq,
61 band,
62 uid,
63 false) // don't instantiate LSigHeader of OfdmPpdu
64{
65 NS_LOG_FUNCTION(this << psdus << txVector << txCenterFreq << ppduDuration << band << uid
66 << flag);
67
68 // overwrite with map (since only first element used by OfdmPpdu)
69 m_psdus.begin()->second = nullptr;
70 m_psdus.clear();
71 m_psdus = psdus;
72 if (txVector.IsMu())
73 {
74 for (const auto& heMuUserInfo : txVector.GetHeMuUserInfoMap())
75 {
76 auto [it, ret] = m_muUserInfos.emplace(heMuUserInfo);
77 NS_ABORT_MSG_IF(!ret, "STA-ID " << heMuUserInfo.first << " already present");
78 }
81 }
82 SetPhyHeaders(txVector, ppduDuration);
83 SetTxPsdFlag(flag);
84}
85
87 const WifiTxVector& txVector,
88 uint16_t txCenterFreq,
89 Time ppduDuration,
90 WifiPhyBand band,
91 uint64_t uid)
92 : OfdmPpdu(psdu,
93 txVector,
94 txCenterFreq,
95 band,
96 uid,
97 false) // don't instantiate LSigHeader of OfdmPpdu
98{
99 NS_LOG_FUNCTION(this << psdu << txVector << txCenterFreq << ppduDuration << band << uid);
100 NS_ASSERT(!IsMu());
101 SetPhyHeaders(txVector, ppduDuration);
103}
104
105void
106HePpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
107{
108 NS_LOG_FUNCTION(this << txVector << ppduDuration);
109
110#ifdef NS3_BUILD_PROFILE_DEBUG
111 LSigHeader lSig;
112 SetLSigHeader(lSig, ppduDuration);
113
114 HeSigHeader heSig;
115 SetHeSigHeader(heSig, txVector);
116
117 m_phyHeaders->AddHeader(heSig);
118 m_phyHeaders->AddHeader(lSig);
119#else
120 SetLSigHeader(m_lSig, ppduDuration);
121 SetHeSigHeader(m_heSig, txVector);
122#endif
123}
124
125void
126HePpdu::SetLSigHeader(LSigHeader& lSig, Time ppduDuration) const
127{
128 uint8_t sigExtension = 0;
130 {
131 sigExtension = 6;
132 }
133 uint8_t m = IsDlMu() ? 1 : 2;
134 uint16_t length = ((ceil((static_cast<double>(ppduDuration.GetNanoSeconds() - (20 * 1000) -
135 (sigExtension * 1000)) /
136 1000) /
137 4.0) *
138 3) -
139 3 - m);
140 lSig.SetLength(length);
141}
142
143void
144HePpdu::SetHeSigHeader(HeSigHeader& heSig, const WifiTxVector& txVector) const
145{
147 {
148 heSig.SetMuFlag(true);
149 heSig.SetMcs(txVector.GetSigBMode().GetMcsValue());
150 }
151 else if (!ns3::IsUlMu(m_preamble))
152 {
153 heSig.SetMcs(txVector.GetMode().GetMcsValue());
154 heSig.SetNStreams(txVector.GetNss());
155 }
156 heSig.SetBssColor(txVector.GetBssColor());
157 heSig.SetChannelWidth(txVector.GetChannelWidth());
158 if (!txVector.IsUlMu())
159 {
160 heSig.SetGuardIntervalAndLtfSize(txVector.GetGuardInterval(), 2 /*NLTF currently unused*/);
161 }
162}
163
166{
167 WifiTxVector txVector;
168 txVector.SetPreambleType(m_preamble);
169
170#ifdef NS3_BUILD_PROFILE_DEBUG
171 auto phyHeaders = m_phyHeaders->Copy();
172
173 LSigHeader lSig;
174 if (phyHeaders->RemoveHeader(lSig) == 0)
175 {
176 NS_FATAL_ERROR("Missing L-SIG header in HE PPDU");
177 }
178
179 HeSigHeader heSig;
180 if (phyHeaders->PeekHeader(heSig) == 0)
181 {
182 NS_FATAL_ERROR("Missing HE-SIG header in HE PPDU");
183 }
184
185 SetTxVectorFromPhyHeaders(txVector, lSig, heSig);
186#else
187 SetTxVectorFromPhyHeaders(txVector, m_lSig, m_heSig);
188#endif
189
190 return txVector;
191}
192
193void
195 const LSigHeader& lSig,
196 const HeSigHeader& heSig) const
197{
198 txVector.SetChannelWidth(heSig.GetChannelWidth());
199 txVector.SetBssColor(heSig.GetBssColor());
200 txVector.SetLength(lSig.GetLength());
201 txVector.SetAggregation(m_psdus.size() > 1 || m_psdus.begin()->second->IsAggregate());
202 if (!IsMu())
203 {
204 txVector.SetMode(HePhy::GetHeMcs(heSig.GetMcs()));
205 txVector.SetNss(heSig.GetNStreams());
206 }
207 if (!IsUlMu())
208 {
209 txVector.SetGuardInterval(heSig.GetGuardInterval());
210 }
211 if (IsDlMu())
212 {
213 for (const auto& muUserInfo : m_muUserInfos)
214 {
215 txVector.SetHeMuUserInfo(muUserInfo.first, muUserInfo.second);
216 }
217 }
218 if (txVector.IsDlMu())
219 {
220 txVector.SetSigBMode(HePhy::GetVhtMcs(heSig.GetMcs()));
222 }
223}
224
225Time
227{
228 Time ppduDuration = Seconds(0);
229 const WifiTxVector& txVector = GetTxVector();
230
231 uint16_t length = 0;
232#ifdef NS3_BUILD_PROFILE_DEBUG
233 LSigHeader lSig;
235 length = lSig.GetLength();
236#else
237 length = m_lSig.GetLength();
238#endif
239
240 Time tSymbol = NanoSeconds(12800 + txVector.GetGuardInterval());
241 Time preambleDuration = WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector);
242 uint8_t sigExtension = 0;
244 {
245 sigExtension = 6;
246 }
247 uint8_t m = IsDlMu() ? 1 : 2;
248 // Equation 27-11 of IEEE P802.11ax/D4.0
249 Time calculatedDuration =
250 MicroSeconds(((ceil(static_cast<double>(length + 3 + m) / 3)) * 4) + 20 + sigExtension);
251 NS_ASSERT(calculatedDuration > preambleDuration);
252 uint32_t nSymbols =
253 floor(static_cast<double>((calculatedDuration - preambleDuration).GetNanoSeconds() -
254 (sigExtension * 1000)) /
255 tSymbol.GetNanoSeconds());
256 ppduDuration = preambleDuration + (nSymbols * tSymbol) + MicroSeconds(sigExtension);
257 return ppduDuration;
258}
259
262{
263 return Ptr<WifiPpdu>(new HePpdu(*this), false);
264}
265
268{
269 switch (m_preamble)
270 {
275 default:
276 return WIFI_PPDU_TYPE_SU;
277 }
278}
279
280bool
282{
283 return (IsDlMu() || IsUlMu());
284}
285
286bool
288{
290}
291
292bool
294{
296}
297
299HePpdu::GetPsdu(uint8_t bssColor, uint16_t staId /* = SU_STA_ID */) const
300{
301 if (!IsMu())
302 {
303 NS_ASSERT(m_psdus.size() == 1);
304 return m_psdus.at(SU_STA_ID);
305 }
306
307 uint8_t ppduBssColor = 0;
308#ifdef NS3_BUILD_PROFILE_DEBUG
309 auto phyHeaders = m_phyHeaders->Copy();
310 LSigHeader lSig;
311 phyHeaders->RemoveHeader(lSig);
312 HeSigHeader heSig;
313 phyHeaders->RemoveHeader(heSig);
314 ppduBssColor = heSig.GetBssColor();
315#else
316 ppduBssColor = m_heSig.GetBssColor();
317#endif
318
319 if (IsUlMu())
320 {
321 NS_ASSERT(m_psdus.size() == 1);
322 if (bssColor == 0 || ppduBssColor == 0 || (bssColor == ppduBssColor))
323 {
324 return m_psdus.cbegin()->second;
325 }
326 }
327 else
328 {
329 if (bssColor == 0 || ppduBssColor == 0 || (bssColor == ppduBssColor))
330 {
331 const auto it = m_psdus.find(staId);
332 if (it != m_psdus.cend())
333 {
334 return it->second;
335 }
336 }
337 }
338 return nullptr;
339}
340
341uint16_t
343{
344 NS_ASSERT(IsUlMu());
345 return m_psdus.begin()->first;
346}
347
348uint16_t
350{
351 const WifiTxVector& txVector = GetTxVector();
352 if (txVector.IsUlMu() && GetStaId() != SU_STA_ID)
353 {
354 TxPsdFlag flag = GetTxPsdFlag();
355 uint16_t ruWidth = HeRu::GetBandwidth(txVector.GetRu(GetStaId()).GetRuType());
356 uint16_t channelWidth = (flag == PSD_NON_HE_PORTION && ruWidth < 20) ? 20 : ruWidth;
357 NS_LOG_INFO("Use channelWidth=" << channelWidth << " MHz for HE TB from " << GetStaId()
358 << " for " << flag);
359 return channelWidth;
360 }
361 else
362 {
364 }
365}
366
369{
370 return m_txPsdFlag;
371}
372
373void
375{
376 NS_LOG_FUNCTION(this << flag);
377 m_txPsdFlag = flag;
378}
379
380void
381HePpdu::UpdateTxVectorForUlMu(const std::optional<WifiTxVector>& trigVector) const
382{
383 if (trigVector.has_value())
384 {
385 NS_LOG_FUNCTION(this << trigVector.value());
386 }
387 else
388 {
389 NS_LOG_FUNCTION(this);
390 }
391 if (!m_txVector.has_value())
392 {
394 }
397 // HE TB PPDU reception needs information from the TRIGVECTOR to be able to receive the PPDU
398 const auto staId = GetStaId();
399 if (trigVector.has_value() && trigVector->IsUlMu() &&
400 (trigVector->GetHeMuUserInfoMap().count(staId) > 0))
401 {
402 // These information are not carried in HE-SIG-A for a HE TB PPDU,
403 // but they are carried in the Trigger frame soliciting the HE TB PPDU
404 m_txVector->SetGuardInterval(trigVector->GetGuardInterval());
405 m_txVector->SetHeMuUserInfo(staId, trigVector->GetHeMuUserInfo(staId));
406 }
407 else
408 {
409 // Set dummy user info, PPDU will be dropped later after decoding PHY headers.
410 m_txVector->SetHeMuUserInfo(
411 staId,
412 {{HeRu::GetRuType(m_txVector->GetChannelWidth()), 1, true}, 0, 1});
413 }
414}
415
416bool
417HePpdu::IsAllocated(uint16_t staId) const
418{
419 return (m_muUserInfos.find(staId) != m_muUserInfos.cend());
420}
421
422bool
423HePpdu::IsStaInContentChannel(uint16_t staId, std::size_t channelId) const
424{
425 NS_ASSERT_MSG(channelId < m_contentChannelAlloc.size(),
426 "Invalid content channel ID " << channelId);
427 const auto& channelAlloc = m_contentChannelAlloc.at(channelId);
428 return (std::find(channelAlloc.cbegin(), channelAlloc.cend(), staId) != channelAlloc.cend());
429}
430
431std::string
433{
434 std::ostringstream ss;
435 if (IsMu())
436 {
437 ss << m_psdus;
438 ss << ", " << m_txPsdFlag;
439 }
440 else
441 {
442 ss << "PSDU=" << m_psdus.at(SU_STA_ID) << " ";
443 }
444 return ss.str();
445}
446
448 : m_format(1),
449 m_bssColor(0),
450 m_ul_dl(0),
451 m_mcs(0),
452 m_spatialReuse(0),
453 m_bandwidth(0),
454 m_gi_ltf_size(0),
455 m_nsts(0),
456 m_mu(false)
457{
458}
459
460TypeId
462{
463 static TypeId tid = TypeId("ns3::HeSigHeader")
464 .SetParent<Header>()
465 .SetGroupName("Wifi")
466 .AddConstructor<HeSigHeader>();
467 return tid;
468}
469
470TypeId
472{
473 return GetTypeId();
474}
475
476void
477HePpdu::HeSigHeader::Print(std::ostream& os) const
478{
479 os << "MCS=" << +m_mcs << " CHANNEL_WIDTH=" << GetChannelWidth() << " GI=" << GetGuardInterval()
480 << " NSTS=" << +m_nsts << " BSSColor=" << +m_bssColor << " MU=" << +m_mu;
481}
482
485{
486 uint32_t size = 0;
487 size += 4; // HE-SIG-A1
488 size += 4; // HE-SIG-A2
489 if (m_mu)
490 {
491 size += 1; // HE-SIG-B
492 }
493 return size;
494}
495
496void
498{
499 m_mu = mu;
500}
501
502void
504{
505 // NS_ASSERT (mcs <= 11); // TODO: reactivate once EHT PHY headers are implemented
506 m_mcs = mcs;
507}
508
509uint8_t
511{
512 return m_mcs;
513}
514
515void
517{
518 NS_ASSERT(bssColor < 64);
519 m_bssColor = bssColor;
520}
521
522uint8_t
524{
525 return m_bssColor;
526}
527
528void
530{
531 if (channelWidth == 160)
532 {
533 m_bandwidth = 3;
534 }
535 else if (channelWidth == 80)
536 {
537 m_bandwidth = 2;
538 }
539 else if (channelWidth == 40)
540 {
541 m_bandwidth = 1;
542 }
543 else
544 {
545 m_bandwidth = 0;
546 }
547}
548
549uint16_t
551{
552 if (m_bandwidth == 3)
553 {
554 return 160;
555 }
556 else if (m_bandwidth == 2)
557 {
558 return 80;
559 }
560 else if (m_bandwidth == 1)
561 {
562 return 40;
563 }
564 else
565 {
566 return 20;
567 }
568}
569
570void
572{
573 if (gi == 800 && ltf == 1)
574 {
575 m_gi_ltf_size = 0;
576 }
577 else if (gi == 800 && ltf == 2)
578 {
579 m_gi_ltf_size = 1;
580 }
581 else if (gi == 1600 && ltf == 2)
582 {
583 m_gi_ltf_size = 2;
584 }
585 else
586 {
587 m_gi_ltf_size = 3;
588 }
589}
590
591uint16_t
593{
594 if (m_gi_ltf_size == 3)
595 {
596 // we currently do not consider DCM nor STBC fields
597 return 3200;
598 }
599 else if (m_gi_ltf_size == 2)
600 {
601 return 1600;
602 }
603 else
604 {
605 return 800;
606 }
607}
608
609void
611{
612 NS_ASSERT(nStreams <= 8);
613 m_nsts = (nStreams - 1);
614}
615
616uint8_t
618{
619 return (m_nsts + 1);
620}
621
622void
624{
625 // HE-SIG-A1
626 uint8_t byte = m_format & 0x01;
627 byte |= ((m_ul_dl & 0x01) << 2);
628 byte |= ((m_mcs & 0x0f) << 3);
629 start.WriteU8(byte);
630 uint16_t bytes = (m_bssColor & 0x3f);
631 bytes |= (0x01 << 6); // Reserved set to 1
632 bytes |= ((m_spatialReuse & 0x0f) << 7);
633 bytes |= ((m_bandwidth & 0x03) << 11);
634 bytes |= ((m_gi_ltf_size & 0x03) << 13);
635 bytes |= ((m_nsts & 0x01) << 15);
636 start.WriteU16(bytes);
637 start.WriteU8((m_nsts >> 1) & 0x03);
638
639 // HE-SIG-A2
640 uint32_t sigA2 = 0;
641 sigA2 |= (0x01 << 14); // Set Reserved bit #14 to 1
642 start.WriteU32(sigA2);
643
644 if (m_mu)
645 {
646 // HE-SIG-B
647 start.WriteU8(0);
648 }
649}
650
653{
654 Buffer::Iterator i = start;
655
656 // HE-SIG-A1
657 uint8_t byte = i.ReadU8();
658 m_format = (byte & 0x01);
659 m_ul_dl = ((byte >> 2) & 0x01);
660 m_mcs = ((byte >> 3) & 0x0f);
661 uint16_t bytes = i.ReadU16();
662 m_bssColor = (bytes & 0x3f);
663 m_spatialReuse = ((bytes >> 7) & 0x0f);
664 m_bandwidth = ((bytes >> 11) & 0x03);
665 m_gi_ltf_size = ((bytes >> 13) & 0x03);
666 m_nsts = ((bytes >> 15) & 0x01);
667 byte = i.ReadU8();
668 m_nsts |= (byte & 0x03) << 1;
669
670 // HE-SIG-A2
671 i.ReadU32();
672
673 if (m_mu)
674 {
675 // HE-SIG-B
676 i.ReadU8();
677 }
678
679 return i.GetDistanceFrom(start);
680}
681
682} // 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
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1559
HE-SIG PHY header (HE-SIG-A1/A2/B)
Definition: he-ppdu.h:51
static TypeId GetTypeId()
Get the type ID.
Definition: he-ppdu.cc:461
void SetChannelWidth(uint16_t channelWidth)
Fill the channel width field of HE-SIG-A1 (in MHz).
Definition: he-ppdu.cc:529
uint16_t GetGuardInterval() const
Return the guard interval (in nanoseconds).
Definition: he-ppdu.cc:592
void SetBssColor(uint8_t bssColor)
Fill the BSS Color field of HE-SIG-A1.
Definition: he-ppdu.cc:516
uint8_t GetBssColor() const
Return the BSS Color field in the HE-SIG-A1.
Definition: he-ppdu.cc:523
uint32_t Deserialize(Buffer::Iterator start) override
Definition: he-ppdu.cc:652
uint8_t GetMcs() const
Return the MCS field of HE-SIG-A1.
Definition: he-ppdu.cc:510
uint32_t GetSerializedSize() const override
Definition: he-ppdu.cc:484
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: he-ppdu.cc:471
void SetMuFlag(bool mu)
Set the Multi-User (MU) flag.
Definition: he-ppdu.cc:497
uint16_t GetChannelWidth() const
Return the channel width (in MHz).
Definition: he-ppdu.cc:550
void Print(std::ostream &os) const override
Definition: he-ppdu.cc:477
void Serialize(Buffer::Iterator start) const override
Definition: he-ppdu.cc:623
void SetGuardIntervalAndLtfSize(uint16_t gi, uint8_t ltf)
Fill the GI + LTF size field of HE-SIG-A1.
Definition: he-ppdu.cc:571
void SetMcs(uint8_t mcs)
Fill the MCS field of HE-SIG-A1.
Definition: he-ppdu.cc:503
uint8_t GetNStreams() const
Return the number of streams.
Definition: he-ppdu.cc:617
void SetNStreams(uint8_t nStreams)
Fill the number of streams field of HE-SIG-A1.
Definition: he-ppdu.cc:610
HE PPDU (11ax)
Definition: he-ppdu.h:45
void SetTxPsdFlag(TxPsdFlag flag) const
Definition: he-ppdu.cc:374
WifiTxVector DoGetTxVector() const override
Get the TXVECTOR used to send the PPDU.
Definition: he-ppdu.cc:165
void UpdateTxVectorForUlMu(const std::optional< WifiTxVector > &trigVector) const
Update the TXVECTOR for HE TB PPDUs, since the information to decode HE TB PPDUs is not available fro...
Definition: he-ppdu.cc:381
Ptr< WifiPpdu > Copy() const override
Copy this instance.
Definition: he-ppdu.cc:261
virtual void SetTxVectorFromPhyHeaders(WifiTxVector &txVector, const LSigHeader &lSig, const HeSigHeader &heSig) const
Fill in the TXVECTOR from PHY headers.
Definition: he-ppdu.cc:194
TxPsdFlag
The transmit power spectral density flag, namely used to correctly build PSDs for pre-HE and HE porti...
Definition: he-ppdu.h:156
@ PSD_HE_PORTION
HE portion of an HE PPDU.
Definition: he-ppdu.h:158
@ PSD_NON_HE_PORTION
Non-HE portion of an HE PPDU.
Definition: he-ppdu.h:157
virtual bool IsDlMu() const
Return true if the PPDU is a DL MU PPDU.
Definition: he-ppdu.cc:287
Time GetTxDuration() const override
Get the total transmission duration of the PPDU.
Definition: he-ppdu.cc:226
virtual bool IsUlMu() const
Return true if the PPDU is an UL MU PPDU.
Definition: he-ppdu.cc:293
ContentChannelAllocation m_contentChannelAlloc
HE SIG-B Content Channel allocation (to be removed once HE-SIG-B headers are implemented)
Definition: he-ppdu.h:271
WifiTxVector::HeMuUserInfoMap m_muUserInfos
HE MU specific per-user information (to be removed once HE-SIG-B headers are implemented)
Definition: he-ppdu.h:268
virtual void SetPhyHeaders(const WifiTxVector &txVector, Time ppduDuration)
Fill in the PHY headers.
Definition: he-ppdu.cc:106
bool IsAllocated(uint16_t staId) const
Check if STA ID is allocated.
Definition: he-ppdu.cc:417
std::string PrintPayload() const override
Print the payload of the PPDU.
Definition: he-ppdu.cc:432
uint16_t GetStaId() const override
Get the ID of the STA that transmitted the PPDU for UL MU, SU_STA_ID otherwise.
Definition: he-ppdu.cc:342
WifiPpduType GetType() const override
Return the PPDU type (.
Definition: he-ppdu.cc:267
TxPsdFlag GetTxPsdFlag() const
Definition: he-ppdu.cc:368
HePpdu(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector, uint16_t txCenterFreq, Time ppduDuration, WifiPhyBand band, uint64_t uid)
Create an SU HE PPDU, storing a PSDU.
Definition: he-ppdu.cc:86
virtual bool IsMu() const
Return true if the PPDU is a MU PPDU.
Definition: he-ppdu.cc:281
RuAllocation m_ruAllocation
RU_ALLOCATION in SIG-B common field (to be removed once HE-SIG-B headers are implemented)
Definition: he-ppdu.h:273
virtual void SetLSigHeader(LSigHeader &lSig, Time ppduDuration) const
Fill in the L-SIG header.
Definition: he-ppdu.cc:126
bool IsStaInContentChannel(uint16_t staId, size_t channelId) const
Check if STA ID is in HE SIG-B Content Channel ID.
Definition: he-ppdu.cc:423
TxPsdFlag m_txPsdFlag
the transmit power spectral density flag
Definition: he-ppdu.h:266
void SetHeSigHeader(HeSigHeader &heSig, const WifiTxVector &txVector) const
Fill in the HE-SIG header.
Definition: he-ppdu.cc:144
uint16_t GetTransmissionChannelWidth() const override
Get the channel width over which the PPDU will effectively be transmitted.
Definition: he-ppdu.cc:349
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:744
static RuType GetRuType(uint16_t bandwidth)
Get the RU corresponding to the approximate bandwidth.
Definition: he-ru.cc:769
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
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
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
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
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1473
std::optional< WifiTxVector > m_txVector
the TXVECTOR at TX PHY or the reconstructed TXVECTOR at RX PHY (or std::nullopt if TXVECTOR has not b...
Definition: wifi-ppdu.h:207
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
WifiModulationClass GetModulation() const
Get the modulation used for the PPDU.
Definition: wifi-ppdu.cc:136
virtual uint16_t GetTransmissionChannelWidth() const
Get the channel width over which the PPDU will effectively be transmitted.
Definition: wifi-ppdu.cc:142
WifiConstPsduMap m_psdus
the PSDUs contained in this PPDU
Definition: wifi-ppdu.h:203
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...
const RuAllocation & GetRuAllocation() const
Get RU Allocation of SIG-B.
uint16_t GetGuardInterval() const
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
uint8_t GetBssColor() const
Get the BSS color.
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 SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
HeRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
bool IsDlMu() const
void SetRuAllocation(const RuAllocation &ruAlloc)
Set RU Allocation of SIG-B common field.
const HeMuUserInfoMap & GetHeMuUserInfoMap() const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
ContentChannelAllocation GetContentChannelAllocation() const
Get the HE SIG-B content channel STA ID allocation IEEE 802.11ax-2021 27.3.11.8.2 HE-SIG-B content ch...
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.
bool IsUlMu() const
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.
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_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_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#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 ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
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_HE_TB
@ WIFI_PREAMBLE_HE_MU
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PPDU_TYPE_DL_MU
@ WIFI_PPDU_TYPE_UL_MU
@ WIFI_PPDU_TYPE_SU
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Declaration of ns3::HePhy class and ns3::HeSigAParameters struct.
Declaration of ns3::HePpdu class.
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::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
bool IsDlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a downlink multi-user transmission.
bool IsUlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a uplink multi-user transmission.
Definition: second.py:1
#define SU_STA_ID
Definition: wifi-mode.h:34