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