A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ht-phy.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Orange Labs
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Rediet <getachew.redieteab@orange.com>
7 * Sébastien Deronne <sebastien.deronne@gmail.com> (for logic ported from wifi-phy)
8 */
9
10#include "ht-phy.h"
11
12#include "ht-ppdu.h"
13
14#include "ns3/assert.h"
15#include "ns3/interference-helper.h"
16#include "ns3/log.h"
17#include "ns3/wifi-phy.h"
18#include "ns3/wifi-psdu.h"
19#include "ns3/wifi-utils.h"
20
21#undef NS_LOG_APPEND_CONTEXT
22#define NS_LOG_APPEND_CONTEXT WIFI_PHY_NS_LOG_APPEND_CONTEXT(m_wifiPhy)
23
24namespace ns3
25{
26
28
29/*******************************************************
30 * HT PHY (IEEE 802.11-2016, clause 19)
31 *******************************************************/
32
33// clang-format off
34
38 WIFI_PPDU_FIELD_HT_SIG, // HT-SIG
39 WIFI_PPDU_FIELD_TRAINING, // HT-STF + HT-LTFs
41};
42
43// clang-format on
44
45HtPhy::HtPhy(uint8_t maxNss /* = 1 */, bool buildModeList /* = true */)
46 : OfdmPhy(OFDM_PHY_DEFAULT, false) // don't add OFDM modes to list
47{
48 NS_LOG_FUNCTION(this << +maxNss << buildModeList);
49 m_maxSupportedNss = maxNss;
53 if (buildModeList)
54 {
55 NS_ABORT_MSG_IF(maxNss == 0 || maxNss > HT_MAX_NSS,
56 "Unsupported max Nss " << +maxNss << " for HT PHY");
58 }
59}
60
62{
63 NS_LOG_FUNCTION(this);
64}
65
66void
68{
69 NS_LOG_FUNCTION(this);
70 NS_ASSERT(m_modeList.empty());
72
73 uint8_t index = 0;
74 for (uint8_t nss = 1; nss <= m_maxSupportedNss; ++nss)
75 {
76 for (uint8_t i = 0; i <= m_maxSupportedMcsIndexPerSs; ++i)
77 {
78 NS_LOG_LOGIC("Add HtMcs" << +index << " to list");
79 m_modeList.emplace_back(CreateHtMcs(index));
80 ++index;
81 }
82 index = 8 * nss;
83 }
84}
85
87HtPhy::GetMcs(uint8_t index) const
88{
89 for (const auto& mcs : m_modeList)
90 {
91 if (mcs.GetMcsValue() == index)
92 {
93 return mcs;
94 }
95 }
96
97 // Should have returned if MCS found
98 NS_ABORT_MSG("Unsupported MCS index " << +index << " for this PHY entity");
99 return WifiMode();
100}
101
102bool
103HtPhy::IsMcsSupported(uint8_t index) const
104{
105 for (const auto& mcs : m_modeList)
106 {
107 if (mcs.GetMcsValue() == index)
108 {
109 return true;
110 }
111 }
112 return false;
113}
114
115bool
117{
118 return true;
119}
120
123{
124 return m_htPpduFormats;
125}
126
128HtPhy::GetSigMode(WifiPpduField field, const WifiTxVector& txVector) const
129{
130 switch (field)
131 {
132 case WIFI_PPDU_FIELD_PREAMBLE: // consider non-HT header mode for preamble (useful for
133 // InterferenceHelper)
135 return GetLSigMode();
136 case WIFI_PPDU_FIELD_TRAINING: // consider HT-SIG mode for training (useful for
137 // InterferenceHelper)
139 return GetHtSigMode();
140 default:
141 return OfdmPhy::GetSigMode(field, txVector);
142 }
143}
144
147{
148 return GetOfdmRate6Mbps();
149}
150
153{
154 return GetLSigMode(); // same number of data tones as OFDM (i.e. 48)
155}
156
157uint8_t
162
163void
165{
166 NS_LOG_FUNCTION(this << +maxIndex);
168 "Provided max MCS index " << +maxIndex
169 << " per SS greater than max standard-defined value "
171 if (maxIndex != m_maxSupportedMcsIndexPerSs)
172 {
173 NS_LOG_LOGIC("Rebuild mode list since max MCS index per spatial stream has changed");
175 m_modeList.clear();
177 }
178}
179
180uint8_t
185
186void
188{
189 NS_LOG_FUNCTION(this << +maxNss);
191 maxNss = std::min(HT_MAX_NSS, maxNss);
192 if (maxNss != m_maxSupportedNss)
193 {
194 NS_LOG_LOGIC("Rebuild mode list since max number of spatial streams has changed");
195 m_maxSupportedNss = maxNss;
196 m_modeList.clear();
198 }
199}
200
201Time
202HtPhy::GetDuration(WifiPpduField field, const WifiTxVector& txVector) const
203{
204 switch (field)
205 {
207 return MicroSeconds(16); // L-STF + L-LTF or HT-GF-STF + HT-LTF1
209 return GetLSigDuration(txVector.GetPreambleType());
211 // We suppose here that STBC = 0.
212 // If STBC > 0, we need a different mapping between Nss and Nltf
213 // (see IEEE 802.11-2016 , section 19.3.9.4.6 "HT-LTF definition").
214 uint8_t nDataLtf = 8;
215 uint8_t nss = txVector.GetNssMax(); // so as to cover also HE MU case (see
216 // section 27.3.10.10 of IEEE P802.11ax/D4.0)
217 if (nss < 3)
218 {
219 nDataLtf = nss;
220 }
221 else if (nss < 5)
222 {
223 nDataLtf = 4;
224 }
225 else if (nss < 7)
226 {
227 nDataLtf = 6;
228 }
229
230 uint8_t nExtensionLtf = (txVector.GetNess() < 3) ? txVector.GetNess() : 4;
231
232 return GetTrainingDuration(txVector, nDataLtf, nExtensionLtf);
233 }
235 return GetHtSigDuration();
236 default:
237 return OfdmPhy::GetDuration(field, txVector);
238 }
239}
240
241Time
243{
244 return MicroSeconds(4);
245}
246
247Time
249 uint8_t nDataLtf,
250 uint8_t nExtensionLtf /* = 0 */) const
251{
252 NS_ABORT_MSG_IF(nDataLtf == 0 || nDataLtf > 4 || nExtensionLtf > 4 ||
253 (nDataLtf + nExtensionLtf) > 5,
254 "Unsupported combination of data ("
255 << +nDataLtf << ") and extension (" << +nExtensionLtf
256 << ") LTFs numbers for HT"); // see IEEE 802.11-2016, section 19.3.9.4.6
257 // "HT-LTF definition"
258 Time duration = MicroSeconds(4) * (nDataLtf + nExtensionLtf);
259 return MicroSeconds(4) * (1 /* HT-STF */ + nDataLtf + nExtensionLtf);
260}
261
262Time
264{
265 return MicroSeconds(8); // HT-SIG
266}
267
268Time
270 const WifiTxVector& txVector,
271 WifiPhyBand band,
272 MpduType mpdutype,
273 bool incFlag,
274 uint32_t& totalAmpduSize,
275 double& totalAmpduNumSymbols,
276 uint16_t staId) const
277{
278 WifiMode payloadMode = txVector.GetMode(staId);
279 uint8_t stbc = txVector.IsStbc() ? 2 : 1; // corresponding to m_STBC in Nsym computation (see
280 // IEEE 802.11-2016, equations (19-32) and (21-62))
281 uint8_t nes = GetNumberBccEncoders(txVector);
282 // TODO: Update station managers to consider GI capabilities
283 Time symbolDuration = GetSymbolDuration(txVector);
284
285 double numDataBitsPerSymbol =
286 payloadMode.GetDataRate(txVector, staId) * symbolDuration.GetNanoSeconds() / 1e9;
287 uint8_t service = GetNumberServiceBits();
288
289 double numSymbols = 0;
290 switch (mpdutype)
291 {
293 // First packet in an A-MPDU
294 numSymbols = (stbc * (service + size * 8.0 + 6 * nes) / (stbc * numDataBitsPerSymbol));
295 if (incFlag)
296 {
297 totalAmpduSize += size;
298 totalAmpduNumSymbols += numSymbols;
299 }
300 break;
301 }
303 // consecutive packets in an A-MPDU
304 numSymbols = (stbc * size * 8.0) / (stbc * numDataBitsPerSymbol);
305 if (incFlag)
306 {
307 totalAmpduSize += size;
308 totalAmpduNumSymbols += numSymbols;
309 }
310 break;
311 }
313 // last packet in an A-MPDU
314 uint32_t totalSize = totalAmpduSize + size;
315 numSymbols = lrint(
316 stbc * ceil((service + totalSize * 8.0 + 6 * nes) / (stbc * numDataBitsPerSymbol)));
317 NS_ASSERT(totalAmpduNumSymbols <= numSymbols);
318 numSymbols -= totalAmpduNumSymbols;
319 if (incFlag)
320 {
321 totalAmpduSize = 0;
322 totalAmpduNumSymbols = 0;
323 }
324 break;
325 }
326 case NORMAL_MPDU:
327 case SINGLE_MPDU: {
328 // Not an A-MPDU or single MPDU (i.e. the current payload contains both service and padding)
329 // The number of OFDM symbols in the data field when BCC encoding
330 // is used is given in equation 19-32 of the IEEE 802.11-2016 standard.
331 numSymbols =
332 lrint(stbc * ceil((service + size * 8.0 + 6.0 * nes) / (stbc * numDataBitsPerSymbol)));
333 break;
334 }
335 default:
336 NS_FATAL_ERROR("Unknown MPDU type");
337 }
338
339 Time payloadDuration =
340 FemtoSeconds(static_cast<uint64_t>(numSymbols * symbolDuration.GetFemtoSeconds()));
341 if (mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU || mpdutype == LAST_MPDU_IN_AGGREGATE)
342 {
343 payloadDuration += GetSignalExtension(band);
344 }
345 return payloadDuration;
346}
347
348uint8_t
350{
351 /**
352 * Add an encoder when crossing maxRatePerCoder frontier.
353 *
354 * The value of 320 Mbps and 350 Mbps for normal GI and short GI (resp.)
355 * were obtained by observing the rates for which Nes was incremented in tables
356 * 19-27 to 19-41 of IEEE 802.11-2016.
357 */
358 double maxRatePerCoder = (txVector.GetGuardInterval().GetNanoSeconds() == 800) ? 320e6 : 350e6;
359 return ceil(txVector.GetMode().GetDataRate(txVector) / maxRatePerCoder);
360}
361
362Time
364{
365 const auto guardInterval = txVector.GetGuardInterval();
366 [[maybe_unused]] const auto gi = guardInterval.GetNanoSeconds();
367 NS_ASSERT(gi == 400 || gi == 800);
368 return GetSymbolDuration(guardInterval);
369}
370
372HtPhy::BuildPpdu(const WifiConstPsduMap& psdus, const WifiTxVector& txVector, Time ppduDuration)
373{
374 NS_LOG_FUNCTION(this << psdus << txVector << ppduDuration);
375 return Create<HtPpdu>(psdus.begin()->second,
376 txVector,
378 ppduDuration,
379 ObtainNextUid(txVector));
380}
381
384{
385 NS_LOG_FUNCTION(this << field << *event);
386 switch (field)
387 {
389 return EndReceiveHtSig(event);
391 return PhyFieldRxStatus(true); // always consider that training has been correctly received
393 // no break so as to go to OfdmPhy for processing
394 default:
395 return OfdmPhy::DoEndReceiveField(field, event);
396 }
397}
398
401{
402 NS_LOG_FUNCTION(this << *event);
403 NS_ASSERT(event->GetPpdu()->GetTxVector().GetPreambleType() == WIFI_PREAMBLE_HT_MF);
405 NS_LOG_DEBUG("HT-SIG: SNR(dB)=" << RatioToDb(snrPer.snr) << ", PER=" << snrPer.per);
406 PhyFieldRxStatus status(GetRandomValue() > snrPer.per);
407 if (status.isSuccess)
408 {
409 NS_LOG_DEBUG("Received HT-SIG");
410 if (!IsAllConfigSupported(WIFI_PPDU_FIELD_HT_SIG, event->GetPpdu()))
411 {
413 }
414 }
415 else
416 {
417 NS_LOG_DEBUG("Drop packet because HT-SIG reception failed");
418 status.reason = HT_SIG_FAILURE;
419 status.actionIfFailure = DROP;
420 }
421 return status;
422}
423
424bool
426{
428 {
429 return true; // wait till reception of HT-SIG (or SIG-A) to make decision
430 }
431 return OfdmPhy::IsAllConfigSupported(field, ppdu);
432}
433
434bool
436{
437 const auto& txVector = ppdu->GetTxVector();
438 if (txVector.GetNss() > m_wifiPhy->GetMaxSupportedRxSpatialStreams())
439 {
440 NS_LOG_DEBUG("Packet reception could not be started because not enough RX antennas");
441 return false;
442 }
443 if (!IsModeSupported(txVector.GetMode()))
444 {
445 NS_LOG_DEBUG("Drop packet because it was sent using an unsupported mode ("
446 << txVector.GetMode() << ")");
447 return false;
448 }
449 return true;
450}
451
454{
455 const auto& centerFrequencies = ppdu->GetTxCenterFreqs();
456 NS_ASSERT(centerFrequencies.size() == 1);
457 const auto& txVector = ppdu->GetTxVector();
458 const auto channelWidth = txVector.GetChannelWidth();
459 NS_LOG_FUNCTION(this << centerFrequencies.front() << channelWidth << txPower);
460 const auto& txMaskRejectionParams = GetTxMaskRejectionParams();
462 centerFrequencies,
463 channelWidth,
464 txPower,
465 GetGuardBandwidth(channelWidth),
466 std::get<0>(txMaskRejectionParams),
467 std::get<1>(txMaskRejectionParams),
468 std::get<2>(txMaskRejectionParams));
469 return v;
470}
471
472void
474{
475 for (uint8_t i = 0; i < 32; ++i)
476 {
477 GetHtMcs(i);
478 }
479}
480
482HtPhy::GetHtMcs(uint8_t index)
483{
484#define CASE(x) \
485 case x: \
486 return GetHtMcs##x();
487
488 switch (index)
489 {
490 CASE(0)
491 CASE(1)
492 CASE(2)
493 CASE(3)
494 CASE(4)
495 CASE(5)
496 CASE(6)
497 CASE(7)
498 CASE(8)
499 CASE(9)
500 CASE(10)
501 CASE(11)
502 CASE(12)
503 CASE(13)
504 CASE(14)
505 CASE(15)
506 CASE(16)
507 CASE(17)
508 CASE(18)
509 CASE(19)
510 CASE(20)
511 CASE(21)
512 CASE(22)
513 CASE(23)
514 CASE(24)
515 CASE(25)
516 CASE(26)
517 CASE(27)
518 CASE(28)
519 CASE(29)
520 CASE(30)
521 CASE(31)
522 default:
523 NS_ABORT_MSG("Inexistent (or not supported) index (" << +index << ") requested for HT");
524 return WifiMode();
525 }
526#undef CASE
527}
528
529#define GET_HT_MCS(x) \
530 WifiMode HtPhy::GetHtMcs##x() \
531 { \
532 static WifiMode mcs = CreateHtMcs(x); \
533 return mcs; \
534 }
535
536GET_HT_MCS(0)
537GET_HT_MCS(1)
538GET_HT_MCS(2)
539GET_HT_MCS(3)
540GET_HT_MCS(4)
541GET_HT_MCS(5)
542GET_HT_MCS(6)
543GET_HT_MCS(7)
544GET_HT_MCS(8)
545GET_HT_MCS(9)
546GET_HT_MCS(10)
547GET_HT_MCS(11)
548GET_HT_MCS(12)
549GET_HT_MCS(13)
550GET_HT_MCS(14)
551GET_HT_MCS(15)
552GET_HT_MCS(16)
553GET_HT_MCS(17)
554GET_HT_MCS(18)
555GET_HT_MCS(19)
556GET_HT_MCS(20)
557GET_HT_MCS(21)
558GET_HT_MCS(22)
559GET_HT_MCS(23)
560GET_HT_MCS(24)
561GET_HT_MCS(25)
562GET_HT_MCS(26)
563GET_HT_MCS(27)
564GET_HT_MCS(28)
565GET_HT_MCS(29)
566GET_HT_MCS(30)
567GET_HT_MCS(31)
568#undef GET_HT_MCS
569
570WifiMode
571HtPhy::CreateHtMcs(uint8_t index)
572{
573 NS_ASSERT_MSG(index <= 31, "HtMcs index must be <= 31!");
574 return WifiModeFactory::CreateWifiMcs("HtMcs" + std::to_string(index),
575 index,
577 false,
584}
585
587HtPhy::GetHtCodeRate(uint8_t mcsValue)
588{
589 return GetCodeRate(mcsValue % 8);
590}
591
593HtPhy::GetCodeRate(uint8_t mcsValue)
594{
595 switch (mcsValue)
596 {
597 case 0:
598 case 1:
599 case 3:
600 return WIFI_CODE_RATE_1_2;
601 case 2:
602 case 4:
603 case 6:
604 return WIFI_CODE_RATE_3_4;
605 case 5:
606 return WIFI_CODE_RATE_2_3;
607 case 7:
608 return WIFI_CODE_RATE_5_6;
609 default:
611 }
612}
613
614uint16_t
616{
617 return GetConstellationSize(mcsValue % 8);
618}
619
620uint16_t
622{
623 switch (mcsValue)
624 {
625 case 0:
626 return 2;
627 case 1:
628 case 2:
629 return 4;
630 case 3:
631 case 4:
632 return 16;
633 case 5:
634 case 6:
635 case 7:
636 return 64;
637 default:
638 return 0;
639 }
640}
641
642uint64_t
643HtPhy::GetPhyRate(uint8_t mcsValue, MHz_u channelWidth, Time guardInterval, uint8_t nss)
644{
645 const auto codeRate = GetHtCodeRate(mcsValue);
646 const auto dataRate = GetDataRate(mcsValue, channelWidth, guardInterval, nss);
647 return CalculatePhyRate(codeRate, dataRate);
648}
649
650uint64_t
651HtPhy::CalculatePhyRate(WifiCodeRate codeRate, uint64_t dataRate)
652{
653 return (dataRate / GetCodeRatio(codeRate));
654}
655
656uint64_t
657HtPhy::GetPhyRateFromTxVector(const WifiTxVector& txVector, uint16_t /* staId */)
658{
659 return GetPhyRate(txVector.GetMode().GetMcsValue(),
660 txVector.GetChannelWidth(),
661 txVector.GetGuardInterval(),
662 txVector.GetNss());
663}
664
665double
667{
668 switch (codeRate)
669 {
671 return (5.0 / 6.0);
672 default:
673 return OfdmPhy::GetCodeRatio(codeRate);
674 }
675}
676
677uint64_t
678HtPhy::GetDataRateFromTxVector(const WifiTxVector& txVector, uint16_t /* staId */)
679{
680 return GetDataRate(txVector.GetMode().GetMcsValue(),
681 txVector.GetChannelWidth(),
682 txVector.GetGuardInterval(),
683 txVector.GetNss());
684}
685
686uint64_t
687HtPhy::GetDataRate(uint8_t mcsValue, MHz_u channelWidth, Time guardInterval, uint8_t nss)
688{
689 [[maybe_unused]] const auto gi = guardInterval.GetNanoSeconds();
690 NS_ASSERT((gi == 800) || (gi == 400));
691 NS_ASSERT(nss <= 4);
692 return CalculateDataRate(GetSymbolDuration(guardInterval),
693 GetUsableSubcarriers(channelWidth),
694 static_cast<uint16_t>(log2(GetHtConstellationSize(mcsValue))),
695 GetCodeRatio(GetHtCodeRate(mcsValue)),
696 nss);
697}
698
699uint64_t
701 uint16_t usableSubCarriers,
702 uint16_t numberOfBitsPerSubcarrier,
703 double codingRate,
704 uint8_t nss)
705{
706 return nss * OfdmPhy::CalculateDataRate(symbolDuration,
707 usableSubCarriers,
708 numberOfBitsPerSubcarrier,
709 codingRate);
710}
711
712uint16_t
714{
715 return (channelWidth == 40) ? 108 : 52;
716}
717
718Time
720{
721 return NanoSeconds(3200) + guardInterval;
722}
723
724uint64_t
726{
727 const auto codeRate = GetHtCodeRate(mcsValue);
728 const auto constellationSize = GetHtConstellationSize(mcsValue);
729 return CalculateNonHtReferenceRate(codeRate, constellationSize);
730}
731
732uint64_t
733HtPhy::CalculateNonHtReferenceRate(WifiCodeRate codeRate, uint16_t constellationSize)
734{
735 uint64_t dataRate;
736 switch (constellationSize)
737 {
738 case 2:
739 if (codeRate == WIFI_CODE_RATE_1_2)
740 {
741 dataRate = 6000000;
742 }
743 else if (codeRate == WIFI_CODE_RATE_3_4)
744 {
745 dataRate = 9000000;
746 }
747 else
748 {
749 NS_FATAL_ERROR("Trying to get reference rate for a MCS with wrong combination of "
750 "coding rate and modulation");
751 }
752 break;
753 case 4:
754 if (codeRate == WIFI_CODE_RATE_1_2)
755 {
756 dataRate = 12000000;
757 }
758 else if (codeRate == WIFI_CODE_RATE_3_4)
759 {
760 dataRate = 18000000;
761 }
762 else
763 {
764 NS_FATAL_ERROR("Trying to get reference rate for a MCS with wrong combination of "
765 "coding rate and modulation");
766 }
767 break;
768 case 16:
769 if (codeRate == WIFI_CODE_RATE_1_2)
770 {
771 dataRate = 24000000;
772 }
773 else if (codeRate == WIFI_CODE_RATE_3_4)
774 {
775 dataRate = 36000000;
776 }
777 else
778 {
779 NS_FATAL_ERROR("Trying to get reference rate for a MCS with wrong combination of "
780 "coding rate and modulation");
781 }
782 break;
783 case 64:
784 if (codeRate == WIFI_CODE_RATE_1_2 || codeRate == WIFI_CODE_RATE_2_3)
785 {
786 dataRate = 48000000;
787 }
788 else if (codeRate == WIFI_CODE_RATE_3_4 || codeRate == WIFI_CODE_RATE_5_6)
789 {
790 dataRate = 54000000;
791 }
792 else
793 {
794 NS_FATAL_ERROR("Trying to get reference rate for a MCS with wrong combination of "
795 "coding rate and modulation");
796 }
797 break;
798 default:
799 NS_FATAL_ERROR("Wrong constellation size");
800 }
801 return dataRate;
802}
803
804bool
805HtPhy::IsAllowed(const WifiTxVector& /*txVector*/)
806{
807 return true;
808}
809
812{
813 return 65535;
814}
815
818{
819 if (m_wifiPhy->GetChannelWidth() < 40)
820 {
821 return OfdmPhy::GetCcaIndication(ppdu);
822 }
823 auto ccaThreshold = GetCcaThreshold(ppdu, WIFI_CHANLIST_PRIMARY);
824 auto delayUntilCcaEnd = GetDelayUntilCcaEnd(ccaThreshold, GetPrimaryBand(20));
825 if (delayUntilCcaEnd.IsStrictlyPositive())
826 {
827 return std::make_pair(
828 delayUntilCcaEnd,
829 WIFI_CHANLIST_PRIMARY); // if Primary is busy, ignore CCA for Secondary
830 }
831 if (ppdu)
832 {
833 const MHz_u primaryWidth = 20;
834 const MHz_u p20MinFreq =
836 (primaryWidth / 2);
837 const MHz_u p20MaxFreq =
839 (primaryWidth / 2);
840 if (ppdu->DoesOverlapChannel(p20MinFreq, p20MaxFreq))
841 {
842 /*
843 * PPDU occupies primary 20 MHz channel, hence we skip CCA sensitivity rules
844 * for signals not occupying the primary 20 MHz channel.
845 */
846 return std::nullopt;
847 }
848 }
849
850 const MHz_u secondaryWidth = 20;
851 const MHz_u s20MinFreq =
853 (secondaryWidth / 2);
854 const MHz_u s20MaxFreq =
856 (secondaryWidth / 2);
857 if (!ppdu || ppdu->DoesOverlapChannel(s20MinFreq, s20MaxFreq))
858 {
859 ccaThreshold = GetCcaThreshold(ppdu, WIFI_CHANLIST_SECONDARY);
860 delayUntilCcaEnd = GetDelayUntilCcaEnd(ccaThreshold, GetSecondaryBand(20));
861 if (delayUntilCcaEnd.IsStrictlyPositive())
862 {
863 return std::make_pair(delayUntilCcaEnd, WIFI_CHANLIST_SECONDARY);
864 }
865 }
866
867 return std::nullopt;
868}
869
870} // namespace ns3
871
872namespace
873{
874
875/**
876 * Constructor class for HT modes
877 */
879{
880 public:
887} g_constructor_ht; ///< the constructor for HT modes
888
889} // namespace
Constructor class for HT modes.
Definition ht-phy.cc:879
static uint64_t CalculatePhyRate(WifiCodeRate codeRate, uint64_t dataRate)
Return the PHY rate corresponding to the supplied code rate and data rate.
Definition ht-phy.cc:651
CcaIndication GetCcaIndication(const Ptr< const WifiPpdu > ppdu) override
Get CCA end time and its corresponding channel list type when a new signal has been received by the P...
Definition ht-phy.cc:817
static uint16_t GetConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied HT MCS index between 0 and 7,...
Definition ht-phy.cc:621
uint8_t m_bssMembershipSelector
the BSS membership selector
Definition ht-phy.h:544
PhyFieldRxStatus DoEndReceiveField(WifiPpduField field, Ptr< Event > event) override
End receiving a given field, perform amendment-specific actions, and provide the status of the recept...
Definition ht-phy.cc:383
Ptr< SpectrumValue > GetTxPowerSpectralDensity(Watt_u txPower, Ptr< const WifiPpdu > ppdu) const override
Definition ht-phy.cc:453
~HtPhy() override
Destructor for HT PHY.
Definition ht-phy.cc:61
static WifiMode GetLSigMode()
Definition ht-phy.cc:146
static uint16_t GetHtConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied HT MCS index.
Definition ht-phy.cc:615
uint8_t m_maxMcsIndexPerSs
the maximum MCS index per spatial stream as defined by the standard
Definition ht-phy.h:542
bool IsAllConfigSupported(WifiPpduField field, Ptr< const WifiPpdu > ppdu) const override
Checks if the signaled configuration (including bandwidth) is supported by the PHY.
Definition ht-phy.cc:425
HtPhy(uint8_t maxNss=1, bool buildModeList=true)
Constructor for HT PHY.
Definition ht-phy.cc:45
static uint64_t GetDataRateFromTxVector(const WifiTxVector &txVector, uint16_t staId)
Return the data rate corresponding to the supplied TXVECTOR.
Definition ht-phy.cc:678
static void InitializeModes()
Initialize all HT modes.
Definition ht-phy.cc:473
static WifiCodeRate GetHtCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied HT MCS index.
Definition ht-phy.cc:587
static uint64_t CalculateNonHtReferenceRate(WifiCodeRate codeRate, uint16_t constellationSize)
Return the rate (in bps) of the non-HT Reference Rate which corresponds to the supplied code rate and...
Definition ht-phy.cc:733
virtual Time GetTrainingDuration(const WifiTxVector &txVector, uint8_t nDataLtf, uint8_t nExtensionLtf=0) const
Definition ht-phy.cc:248
bool IsMcsSupported(uint8_t index) const override
Check if the WifiMode corresponding to the given MCS index is supported.
Definition ht-phy.cc:103
Time GetDuration(WifiPpduField field, const WifiTxVector &txVector) const override
Get the duration of the PPDU field (or group of fields) used by this entity for the given transmissio...
Definition ht-phy.cc:202
Time GetPayloadDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, MpduType mpdutype, bool incFlag, uint32_t &totalAmpduSize, double &totalAmpduNumSymbols, uint16_t staId) const override
Definition ht-phy.cc:269
uint8_t GetBssMembershipSelector() const
Definition ht-phy.cc:158
static bool IsAllowed(const WifiTxVector &txVector)
Check whether the combination in TXVECTOR is allowed.
Definition ht-phy.cc:805
static uint64_t GetPhyRateFromTxVector(const WifiTxVector &txVector, uint16_t staId)
Return the PHY rate corresponding to the supplied TXVECTOR.
Definition ht-phy.cc:657
WifiMode GetMcs(uint8_t index) const override
Get the WifiMode corresponding to the given MCS index.
Definition ht-phy.cc:87
virtual uint8_t GetNumberBccEncoders(const WifiTxVector &txVector) const
Definition ht-phy.cc:349
static uint64_t GetNonHtReferenceRate(uint8_t mcsValue)
Calculate the rate in bps of the non-HT Reference Rate corresponding to the supplied HT MCS index.
Definition ht-phy.cc:725
virtual Time GetLSigDuration(WifiPreamble preamble) const
Definition ht-phy.cc:242
static uint64_t GetPhyRate(uint8_t mcsValue, MHz_u channelWidth, Time guardInterval, uint8_t nss)
Return the PHY rate corresponding to the supplied HT MCS index, channel width, guard interval,...
Definition ht-phy.cc:643
void SetMaxSupportedMcsIndexPerSs(uint8_t maxIndex)
Set the maximum supported MCS index per spatial stream.
Definition ht-phy.cc:164
static WifiMode GetHtMcs(uint8_t index)
Return the HT MCS corresponding to the provided index.
Definition ht-phy.cc:482
static WifiMode CreateHtMcs(uint8_t index)
Return the HT MCS corresponding to the provided index.
Definition ht-phy.cc:571
uint32_t GetMaxPsduSize() const override
Get the maximum PSDU size in bytes.
Definition ht-phy.cc:811
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied HT MCS index between 0 and 7,...
Definition ht-phy.cc:593
virtual WifiMode GetHtSigMode() const
Definition ht-phy.cc:152
WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const override
Get the WifiMode for the SIG field specified by the PPDU field.
Definition ht-phy.cc:128
static uint64_t CalculateDataRate(Time symbolDuration, uint16_t usableSubCarriers, uint16_t numberOfBitsPerSubcarrier, double codingRate, uint8_t nss)
Calculates data rate from the supplied parameters.
Definition ht-phy.cc:700
uint8_t GetMaxSupportedMcsIndexPerSs() const
Set the maximum supported MCS index per spatial stream.
Definition ht-phy.cc:181
bool IsConfigSupported(Ptr< const WifiPpdu > ppdu) const override
Checks if the signaled configuration (excluding bandwidth) is supported by the PHY.
Definition ht-phy.cc:435
Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration) override
Build amendment-specific PPDU.
Definition ht-phy.cc:372
uint8_t m_maxSupportedNss
Maximum supported number of spatial streams (used to build HT MCS indices)
Definition ht-phy.h:566
virtual void BuildModeList()
Build mode list.
Definition ht-phy.cc:67
static double GetCodeRatio(WifiCodeRate codeRate)
Convert WifiCodeRate to a ratio, e.g., code ratio of WIFI_CODE_RATE_1_2 is 0.5.
Definition ht-phy.cc:666
bool HandlesMcsModes() const override
Check if the WifiModes handled by this PHY are MCSs.
Definition ht-phy.cc:116
static const PpduFormats m_htPpduFormats
HT PPDU formats.
Definition ht-phy.h:569
void SetMaxSupportedNss(uint8_t maxNss)
Configure the maximum number of spatial streams supported by this HT PHY.
Definition ht-phy.cc:187
PhyFieldRxStatus EndReceiveHtSig(Ptr< Event > event)
End receiving the HT-SIG, perform HT-specific actions, and provide the status of the reception.
Definition ht-phy.cc:400
virtual Time GetHtSigDuration() const
Definition ht-phy.cc:263
uint8_t m_maxSupportedMcsIndexPerSs
the maximum supported MCS index per spatial stream
Definition ht-phy.h:543
const PpduFormats & GetPpduFormats() const override
Return the PPDU formats of the PHY.
Definition ht-phy.cc:122
virtual Time GetSymbolDuration(const WifiTxVector &txVector) const
Definition ht-phy.cc:363
static uint64_t GetDataRate(uint8_t mcsValue, MHz_u channelWidth, Time guardInterval, uint8_t nss)
Return the data rate corresponding to the supplied HT MCS index, channel width, guard interval,...
Definition ht-phy.cc:687
PHY entity for OFDM (11a)
Definition ofdm-phy.h:50
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6 Mbps.
dBm_u GetCcaThreshold(const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType) const override
Return the CCA threshold for a given channel type.
Definition ofdm-phy.cc:668
uint8_t GetNumberServiceBits() const
Definition ofdm-phy.cc:273
virtual bool IsAllConfigSupported(WifiPpduField field, Ptr< const WifiPpdu > ppdu) const
Checks if the signaled configuration (including bandwidth) is supported by the PHY.
Definition ofdm-phy.cc:347
static uint16_t GetUsableSubcarriers()
Definition ofdm-phy.cc:624
Time GetDuration(WifiPpduField field, const WifiTxVector &txVector) const override
Get the duration of the PPDU field (or group of fields) used by this entity for the given transmissio...
Definition ofdm-phy.cc:183
PhyFieldRxStatus DoEndReceiveField(WifiPpduField field, Ptr< Event > event) override
End receiving a given field, perform amendment-specific actions, and provide the status of the recept...
Definition ofdm-phy.cc:299
static uint64_t CalculateDataRate(WifiCodeRate codeRate, uint16_t constellationSize, MHz_u channelWidth)
Calculates data rate from the supplied parameters.
Definition ofdm-phy.cc:605
WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const override
Get the WifiMode for the SIG field specified by the PPDU field.
Definition ofdm-phy.cc:144
static double GetCodeRatio(WifiCodeRate codeRate)
Convert WifiCodeRate to a ratio, e.g., code ratio of WIFI_CODE_RATE_1_2 is 0.5.
Definition ofdm-phy.cc:573
Time GetSignalExtension(WifiPhyBand band) const
Definition ofdm-phy.cc:279
MHz_u GetGuardBandwidth(MHz_u currentChannelWidth) const
virtual uint64_t ObtainNextUid(const WifiTxVector &txVector)
Obtain the next UID for the PPDU to transmit.
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
Definition phy-entity.h:939
std::optional< std::pair< Time, WifiChannelListType > > CcaIndication
CCA end time and its corresponding channel list type (can be std::nullopt if IDLE)
Definition phy-entity.h:924
std::map< WifiPreamble, std::vector< WifiPpduField > > PpduFormats
A map of PPDU field elements per preamble type.
Definition phy-entity.h:529
WifiSpectrumBandInfo GetPrimaryBand(MHz_u bandWidth) const
If the operating channel width is a multiple of 20 MHz, return the info corresponding to the primary ...
Time GetDelayUntilCcaEnd(dBm_u threshold, const WifiSpectrumBandInfo &band)
Return the delay until CCA busy is ended for a given sensitivity threshold and a given band.
virtual bool IsModeSupported(WifiMode mode) const
Check if the WifiMode is supported.
Definition phy-entity.cc:90
virtual CcaIndication GetCcaIndication(const Ptr< const WifiPpdu > ppdu)
Get CCA end time and its corresponding channel list type when a new signal has been received by the P...
std::list< WifiMode > m_modeList
the list of supported modes
Definition phy-entity.h:943
double GetRandomValue() const
Obtain a random value from the WifiPhy's generator.
SnrPer GetPhyHeaderSnrPer(WifiPpduField field, Ptr< Event > event) const
Obtain the SNR and PER of the PPDU field from the WifiPhy's InterferenceHelper class.
std::tuple< dBr_u, dBr_u, dBr_u > GetTxMaskRejectionParams() const
@ DROP
drop PPDU and set CCA_BUSY
Definition phy-entity.h:71
WifiSpectrumBandInfo GetSecondaryBand(MHz_u bandWidth) const
If the channel bonding is used, return the info corresponding to the secondary channel of the given b...
Smart pointer class similar to boost::intrusive_ptr.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:407
int64_t GetFemtoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:417
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, NonHtReferenceRateCallback nonHtReferenceRateCallback, AllowedCallback isAllowedCallback)
Definition wifi-mode.cc:307
represent a single transmission mode
Definition wifi-mode.h:40
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:111
uint8_t GetMcsValue() const
Definition wifi-mode.cc:152
uint8_t GetMaxSupportedRxSpatialStreams() const
Definition wifi-phy.cc:1390
static void AddStaticPhyEntity(WifiModulationClass modulation, Ptr< PhyEntity > phyEntity)
Add the PHY entity to the map of implemented PHY entities for the given modulation class.
Definition wifi-phy.cc:795
MHz_u GetChannelWidth() const
Definition wifi-phy.cc:1093
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition wifi-phy.cc:1075
MHz_u GetSecondaryChannelCenterFrequency(MHz_u secondaryChannelWidth) const
Get the center frequency of the secondary channel of the given width.
MHz_u GetPrimaryChannelCenterFrequency(MHz_u primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
static Ptr< SpectrumValue > CreateHtOfdmTxPowerSpectralDensity(const std::vector< MHz_u > &centerFrequencies, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=-20, dBr_u minOuterband=-28, dBr_u lowestPoint=-40)
Create a transmit power spectral density corresponding to OFDM High Throughput (HT) (802....
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
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.
bool IsStbc() const
Check if STBC is used or not.
WifiPreamble GetPreambleType() const
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.
uint8_t GetNssMax() const
MHz_u GetChannelWidth() const
Time GetGuardInterval() const
uint8_t GetNess() const
#define CASE(x)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition callback.h:745
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1368
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPhyBand
Identifies the PHY band.
WifiPpduField
The type of PPDU field (grouped for convenience)
MpduType
The type of an MPDU.
Definition wifi-types.h:41
@ UNSUPPORTED_SETTINGS
@ HT_SIG_FAILURE
@ WIFI_PREAMBLE_HT_MF
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ OFDM_PHY_DEFAULT
Definition ofdm-phy.h:34
@ WIFI_CHANLIST_PRIMARY
@ WIFI_CHANLIST_SECONDARY
@ WIFI_PPDU_FIELD_TRAINING
STF + LTF fields (excluding those in preamble for HT-GF)
@ WIFI_PPDU_FIELD_NON_HT_HEADER
PHY header field for DSSS or ERP, short PHY header field for HR/DSSS or ERP, field not present for HT...
@ WIFI_PPDU_FIELD_HT_SIG
HT-SIG field.
@ WIFI_PPDU_FIELD_PREAMBLE
SYNC + SFD fields for DSSS or ERP, shortSYNC + shortSFD fields for HR/DSSS or ERP,...
@ WIFI_PPDU_FIELD_DATA
data field
@ LAST_MPDU_IN_AGGREGATE
The MPDU is the last aggregate in an A-MPDU with multiple MPDUs.
Definition wifi-types.h:53
@ NORMAL_MPDU
The MPDU is not part of an A-MPDU.
Definition wifi-types.h:43
@ FIRST_MPDU_IN_AGGREGATE
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate.
Definition wifi-types.h:48
@ SINGLE_MPDU
The MPDU is a single MPDU.
Definition wifi-types.h:45
@ MIDDLE_MPDU_IN_AGGREGATE
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate.
Definition wifi-types.h:51
#define GET_HT_MCS(x)
Definition ht-phy.cc:529
Declaration of ns3::HtPhy class.
#define HT_PHY
This defines the BSS membership value for HT PHY.
Definition ht-phy.h:27
Declaration of ns3::HtPpdu class.
class anonymous_namespace{ht-phy.cc}::ConstructorHt g_constructor_ht
the constructor for HT modes
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.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
dB_u RatioToDb(double ratio)
Convert from ratio to dB.
Definition wifi-utils.cc:44
constexpr uint8_t HT_MAX_NSS
Maximum number of supported NSS by HT PHY.
Definition ht-phy.h:30
WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
@ WIFI_CODE_RATE_2_3
2/3 coding rate
@ WIFI_CODE_RATE_1_2
1/2 coding rate
@ WIFI_CODE_RATE_3_4
3/4 coding rate
@ WIFI_CODE_RATE_UNDEFINED
undefined coding rate
@ WIFI_CODE_RATE_5_6
5/6 coding rate
Status of the reception of the PPDU field.
Definition phy-entity.h:80
WifiPhyRxfailureReason reason
failure reason
Definition phy-entity.h:82
PhyRxFailureAction actionIfFailure
action to perform in case of failure
Definition phy-entity.h:83
bool isSuccess
outcome (true if success) of the reception
Definition phy-entity.h:81
A struct for both SNR and PER.
Definition phy-entity.h:115
double snr
SNR in linear scale.
Definition phy-entity.h:116