A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-phy-cca-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7 */
8
9#include "ns3/constant-obss-pd-algorithm.h"
10#include "ns3/he-phy.h"
11#include "ns3/he-ppdu.h"
12#include "ns3/ht-ppdu.h"
13#include "ns3/interference-helper.h"
14#include "ns3/log.h"
15#include "ns3/multi-model-spectrum-channel.h"
16#include "ns3/nist-error-rate-model.h"
17#include "ns3/non-communicating-net-device.h"
18#include "ns3/ofdm-ppdu.h"
19#include "ns3/pointer.h"
20#include "ns3/rng-seed-manager.h"
21#include "ns3/spectrum-wifi-helper.h"
22#include "ns3/spectrum-wifi-phy.h"
23#include "ns3/test.h"
24#include "ns3/threshold-preamble-detection-model.h"
25#include "ns3/vht-configuration.h"
26#include "ns3/vht-ppdu.h"
27#include "ns3/waveform-generator.h"
28#include "ns3/wifi-mac-header.h"
29#include "ns3/wifi-net-device.h"
30#include "ns3/wifi-phy-listener.h"
31#include "ns3/wifi-psdu.h"
32#include "ns3/wifi-spectrum-value-helper.h"
33#include "ns3/wifi-utils.h"
34
35#include <memory>
36#include <vector>
37
38using namespace ns3;
39
40NS_LOG_COMPONENT_DEFINE("WifiPhyCcaTest");
41
42constexpr MHz_u P20_CENTER_FREQUENCY = 5180;
50// add small delta to be right after aCCATime, since test checks are scheduled before wifi events
52const std::map<MHz_u, Time> PpduDurations = {
53 {20, NanoSeconds(1009600)},
54 {40, NanoSeconds(533600)},
55 {80, NanoSeconds(275200)},
56};
57
58/**
59 * \ingroup wifi-test
60 * \ingroup tests
61 *
62 * \brief PHY CCA thresholds test
63 */
65{
66 public:
68
69 private:
70 void DoSetup() override;
71 void DoTeardown() override;
72 void DoRun() override;
73
74 /**
75 * Run tests for given CCA attributes
76 */
77 void RunOne();
78
79 /**
80 * Create a dummy PSDU whose payload is 1000 bytes
81 * \return a dummy PSDU whose payload is 1000 bytes
82 */
84 /**
85 * Create a non-HT PPDU
86 * \param channel the operating channel of the PHY used for the transmission
87 * \return a non-HT PPDU
88 */
90 /**
91 * Create a HT PPDU
92 * \param bandwidth the bandwidth used for the transmission the PPDU
93 * \param channel the operating channel of the PHY used for the transmission
94 * \return a HT PPDU
95 */
97 /**
98 * Create a VHT PPDU
99 * \param bandwidth the bandwidth used for the transmission the PPDU
100 * \param channel the operating channel of the PHY used for the transmission
101 * \return a VHT PPDU
102 */
104 /**
105 * Create a HE PPDU
106 * \param bandwidth the bandwidth used for the transmission the PPDU
107 * \param channel the operating channel of the PHY used for the transmission
108 * \return a HE PPDU
109 */
111
112 /**
113 * Function to verify the CCA threshold that is being reported by a given PHY entity upon
114 * reception of a signal or a PPDU
115 * \param phy the PHY entity to verify
116 * \param ppdu the incoming PPDU or signal (if nullptr)
117 * \param channelType the channel list type that indicates which channel the PPDU or the
118 * signal occupies
119 * \param expectedCcaThreshold the CCA threshold that is expected to be reported
120 */
121 void VerifyCcaThreshold(const Ptr<PhyEntity> phy,
122 const Ptr<const WifiPpdu> ppdu,
123 WifiChannelListType channelType,
124 dBm_u expectedCcaThreshold);
125
126 Ptr<WifiNetDevice> m_device; ///< The WifiNetDevice
127 Ptr<SpectrumWifiPhy> m_phy; ///< The spectrum PHY
128 Ptr<ObssPdAlgorithm> m_obssPdAlgorithm; ///< The OBSS-PD algorithm
129 Ptr<VhtConfiguration> m_vhtConfiguration; ///< The VHT configuration
130
131 dBm_u m_CcaEdThreshold; ///< The current CCA-ED threshold for a 20 MHz subchannel
132 dBm_u m_CcaSensitivity; ///< The current CCA sensitivity threshold for signals that occupy the
133 ///< primary 20 MHz channel
134
136 m_secondaryCcaSensitivityThresholds; ///< The current CCA sensitivity thresholds for signals
137 ///< that do not occupy the primary 20 MHz channel
138
139 dBm_u m_obssPdLevel; ///< The current OBSS-PD level
140};
141
143 : TestCase("Wi-Fi PHY CCA thresholds test"),
144 m_CcaEdThreshold{-62.0},
145 m_CcaSensitivity{-82.0},
146 m_secondaryCcaSensitivityThresholds{-72.0, -72.0, -69.0},
147 m_obssPdLevel{-82.0}
148{
149}
150
153{
154 Ptr<Packet> pkt = Create<Packet>(1000);
155 WifiMacHeader hdr;
157 hdr.SetQosTid(0);
158 return Create<WifiPsdu>(pkt, hdr);
159}
160
163{
165 0,
167 NanoSeconds(800),
168 1,
169 1,
170 0,
171 20,
172 false);
174 return Create<OfdmPpdu>(psdu, txVector, channel, 0);
175}
176
179{
181 0,
183 NanoSeconds(800),
184 1,
185 1,
186 0,
187 bandwidth,
188 false);
190 return Create<HtPpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
191}
192
195 const WifiPhyOperatingChannel& channel)
196{
198 0,
200 NanoSeconds(800),
201 1,
202 1,
203 0,
204 bandwidth,
205 false);
207 return Create<VhtPpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
208}
209
212{
214 0,
216 NanoSeconds(800),
217 1,
218 1,
219 0,
220 bandwidth,
221 false);
223 return Create<HePpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
224}
225
226void
228 const Ptr<const WifiPpdu> ppdu,
229 WifiChannelListType channelType,
230 dBm_u expectedCcaThreshold)
231{
232 NS_LOG_FUNCTION(this << phy << channelType << expectedCcaThreshold);
233 const auto actualThreshold = phy->GetCcaThreshold(ppdu, channelType);
234 NS_LOG_INFO((ppdu == nullptr ? "any signal" : "a PPDU")
235 << " in " << channelType << " channel: " << actualThreshold << "dBm");
236 NS_TEST_EXPECT_MSG_EQ_TOL(actualThreshold,
237 expectedCcaThreshold,
238 1e-6,
239 "Actual CCA threshold for "
240 << (ppdu == nullptr ? "any signal" : "a PPDU") << " in "
241 << channelType << " channel " << actualThreshold
242 << "dBm does not match expected threshold "
243 << expectedCcaThreshold << "dBm");
244}
245
246void
248{
249 // WifiHelper::EnableLogComponents ();
250 // LogComponentEnable ("WifiPhyCcaTest", LOG_LEVEL_ALL);
251
253 m_device->SetStandard(WIFI_STANDARD_80211ax);
255 m_device->SetVhtConfiguration(m_vhtConfiguration);
256
258 m_phy->SetDevice(m_device);
259 m_device->SetPhy(m_phy);
260 m_phy->SetInterferenceHelper(CreateObject<InterferenceHelper>());
262
263 auto channelNum =
265 ->number;
266 m_phy->SetOperatingChannel(WifiPhy::ChannelTuple{channelNum, 160, WIFI_PHY_BAND_5GHZ, 0});
267 m_phy->ConfigureStandard(WIFI_STANDARD_80211ax);
268
270 m_device->AggregateObject(m_obssPdAlgorithm);
271 m_obssPdAlgorithm->ConnectWifiNetDevice(m_device);
272}
273
274void
276{
277 m_device->Dispose();
278 m_device = nullptr;
279}
280
281void
283{
284 m_phy->SetCcaEdThreshold(m_CcaEdThreshold);
285 m_phy->SetCcaSensitivityThreshold(m_CcaSensitivity);
286 m_vhtConfiguration->SetSecondaryCcaSensitivityThresholds(m_secondaryCcaSensitivityThresholds);
287 m_obssPdAlgorithm->SetObssPdLevel(m_obssPdLevel);
288
289 // OFDM PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
291 nullptr,
294
295 //-----------------------------------------------------------------------------------------------------------------------------------
296
297 // OFDM PHY: 20 MHz non-HT PPDU in primary channel (20 MHz) if power above CCA sensitivity
298 // threshold
300 CreateDummyNonHtPpdu(m_phy->GetOperatingChannel()),
303
304 //-----------------------------------------------------------------------------------------------------------------------------------
305
306 // HT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
308 nullptr,
311
312 // HT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
314 nullptr,
317
318 //-----------------------------------------------------------------------------------------------------------------------------------
319
320 // HT PHY: 20 MHz HT PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
321 // threshold
323 CreateDummyHtPpdu(20, m_phy->GetOperatingChannel()),
326
327 // HT PHY: 40 MHz HT PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
328 // threshold
330 CreateDummyHtPpdu(40, m_phy->GetOperatingChannel()),
333
334 //-----------------------------------------------------------------------------------------------------------------------------------
335
336 // VHT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
338 nullptr,
341
342 // VHT PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
344 nullptr,
347
348 // VHT PHY: any signal in secondary40 channel (40 MHz) if power above CCA-ED threshold + 3dB
350 nullptr,
352 m_CcaEdThreshold + static_cast<dB_u>(3.0));
353
354 // VHT PHY: any signal in secondary80 channel (80 MHz) if power above CCA-ED threshold + 6dB
356 nullptr,
358 m_CcaEdThreshold + static_cast<dB_u>(6.0));
359
360 //-----------------------------------------------------------------------------------------------------------------------------------
361
362 // VHT PHY: 20 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
363 // sensitivity threshold
365 CreateDummyVhtPpdu(20, m_phy->GetOperatingChannel()),
368
369 // VHT PHY: 40 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
370 // sensitivity threshold
372 CreateDummyVhtPpdu(40, m_phy->GetOperatingChannel()),
375
376 // VHT PHY: 80 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
377 // sensitivity threshold
379 CreateDummyVhtPpdu(80, m_phy->GetOperatingChannel()),
382
383 // VHT PHY: 160 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
384 // sensitivity threshold
386 CreateDummyVhtPpdu(160, m_phy->GetOperatingChannel()),
389
390 //-----------------------------------------------------------------------------------------------------------------------------------
391
392 // VHT PHY: 20 MHz VHT PPDU in secondary channel (20 MHz) if power above the CCA sensitivity
393 // threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
395 CreateDummyVhtPpdu(20, m_phy->GetOperatingChannel()),
398
399 // VHT PHY: 20 MHz VHT PPDU in secondary40 channel (40 MHz) if power above the CCA sensitivity
400 // threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
402 CreateDummyVhtPpdu(20, m_phy->GetOperatingChannel()),
405
406 // VHT PHY: 40 MHz VHT PPDU in secondary40 channel (40 MHz) if power above the CCA sensitivity
407 // threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20 MHz
409 CreateDummyVhtPpdu(40, m_phy->GetOperatingChannel()),
412
413 // VHT PHY: 20 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA sensitivity
414 // threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
416 CreateDummyVhtPpdu(20, m_phy->GetOperatingChannel()),
419
420 // VHT PHY: 40 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA sensitivity
421 // threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20 MHz
423 CreateDummyVhtPpdu(40, m_phy->GetOperatingChannel()),
426
427 // VHT PHY: 80 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA sensitivity
428 // threshold corresponding to a 80 MHz PPDU that does not occupy the primary 20 MHz
430 CreateDummyVhtPpdu(80, m_phy->GetOperatingChannel()),
433
434 //-----------------------------------------------------------------------------------------------------------------------------------
435
436 // HE PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
438 nullptr,
441
442 // HE PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
444 nullptr,
447
448 // HE PHY: any signal in secondary40 channel (40 MHz) if power above CCA-ED threshold + 3dB
450 nullptr,
452 m_CcaEdThreshold + static_cast<dB_u>(3.0));
453
454 // HE PHY: any signal in secondary80 channel (80 MHz) if power above CCA-ED threshold + 6dB
456 nullptr,
458 m_CcaEdThreshold + static_cast<dB_u>(6.0));
459
460 //-----------------------------------------------------------------------------------------------------------------------------------
461
462 // HE PHY: 20 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
463 // threshold
465 CreateDummyHePpdu(20, m_phy->GetOperatingChannel()),
468
469 // HE PHY: 40 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
470 // threshold
472 CreateDummyHePpdu(40, m_phy->GetOperatingChannel()),
475
476 // HE PHY: 80 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
477 // threshold
479 CreateDummyHePpdu(80, m_phy->GetOperatingChannel()),
482
483 // HE PHY: 160 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
484 // threshold
486 CreateDummyHePpdu(160, m_phy->GetOperatingChannel()),
489
490 //-----------------------------------------------------------------------------------------------------------------------------------
491
492 // HE PHY: 20 MHz HE PPDU in secondary channel (20 MHz) if power above the max between the CCA
493 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
494 // and the OBSS-PD level
496 CreateDummyHePpdu(20, m_phy->GetOperatingChannel()),
498 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
499
500 // HE PHY: 20 MHz HE PPDU in secondary40 channel (40 MHz) if power above the max between the CCA
501 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
502 // and the OBSS-PD level
504 CreateDummyHePpdu(20, m_phy->GetOperatingChannel()),
506 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
507
508 // HE PHY: 40 MHz HE PPDU in secondary40 channel (40 MHz) if power above the max between the CCA
509 // sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20 MHz
510 // and the OBSS-PD level plus 3 dB
512 CreateDummyHePpdu(40, m_phy->GetOperatingChannel()),
514 std::max(m_obssPdLevel + static_cast<dB_u>(3.0),
516
517 // HE PHY: 20 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the CCA
518 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
519 // and the OBSS-PD level
521 CreateDummyHePpdu(20, m_phy->GetOperatingChannel()),
523 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
524
525 // HE PHY: 40 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the CCA
526 // sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20 MHz
527 // and the OBSS-PD level plus 3 dB
529 CreateDummyHePpdu(40, m_phy->GetOperatingChannel()),
531 std::max(m_obssPdLevel + static_cast<dB_u>(3.0),
533
534 // HE PHY: 80 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the CCA
535 // sensitivity threshold corresponding to a 80 MHz PPDU that does not occupy the primary 20 MHz
536 // and the OBSS-PD level plus 6 dB
538 CreateDummyHePpdu(80, m_phy->GetOperatingChannel()),
540 std::max(m_obssPdLevel + static_cast<dB_u>(6.0),
542}
543
544void
546{
547 // default attributes
548 m_CcaEdThreshold = -62.0;
549 m_CcaSensitivity = -82.0;
550 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
551 m_obssPdLevel = -82.0;
552 RunOne();
553
554 // default attributes with OBSS-PD level set to -80 dBm
555 m_CcaEdThreshold = -62.0;
556 m_CcaSensitivity = -82.0;
557 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
558 m_obssPdLevel = -80.0;
559 RunOne();
560
561 // default attributes with OBSS-PD level set to -70 dBm
562 m_CcaEdThreshold = -62.0;
563 m_CcaSensitivity = -82.0;
564 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
565 m_obssPdLevel = -70.0;
566 RunOne();
567
568 // CCA-ED set to -65 dBm
569 m_CcaEdThreshold = -65.0;
570 m_CcaSensitivity = -82.0;
571 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
572 m_obssPdLevel = -82.0;
573 RunOne();
574
575 // CCA sensitivity for signals in primary set to -75 dBm
576 m_CcaEdThreshold = -62.0;
577 m_CcaSensitivity = -75.0;
578 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
579 m_obssPdLevel = -82.0;
580 RunOne();
581
582 // custom CCA sensitivities for signals not in primary
583 m_CcaEdThreshold = -62.0;
584 m_CcaSensitivity = -72.0;
585 m_secondaryCcaSensitivityThresholds = std::make_tuple(-70.0, -70.0, -70.0);
586 m_obssPdLevel = -82.0;
587 RunOne();
588
589 // custom CCA sensitivities for signals not in primary with OBSS-PD level set to -80 dBm
590 m_CcaEdThreshold = -62.0;
591 m_CcaSensitivity = -72.0;
592 m_secondaryCcaSensitivityThresholds = std::make_tuple(-70.0, -70.0, -70.0);
593 m_obssPdLevel = -80.0;
594 RunOne();
595
596 // custom CCA sensitivities for signals not in primary with OBSS-PD level set to -70 dBm
597 m_CcaEdThreshold = -62.0;
598 m_CcaSensitivity = -72.0;
599 m_secondaryCcaSensitivityThresholds = std::make_tuple(-70.0, -70.0, -70.0);
600 m_obssPdLevel = -70.0;
601 RunOne();
602
604}
605
606/**
607 * \ingroup wifi-test
608 * \ingroup tests
609 *
610 * \brief PHY listener for CCA tests
611 */
613{
614 public:
616
617 void NotifyRxStart(Time duration) override
618 {
619 NS_LOG_FUNCTION(this << duration);
620 }
621
622 void NotifyRxEndOk() override
623 {
624 NS_LOG_FUNCTION(this);
625 }
626
627 void NotifyRxEndError() override
628 {
629 NS_LOG_FUNCTION(this);
630 }
631
632 void NotifyTxStart(Time duration, dBm_u txPower) override
633 {
634 NS_LOG_FUNCTION(this << duration << txPower);
635 }
636
638 WifiChannelListType channelType,
639 const std::vector<Time>& per20MhzDurations) override
640 {
641 NS_LOG_FUNCTION(this << duration << channelType << per20MhzDurations.size());
642 m_endCcaBusy = Simulator::Now() + duration;
643 m_lastCcaBusyChannelType = channelType;
644 m_lastPer20MhzCcaBusyDurations = per20MhzDurations;
646 }
647
648 void NotifySwitchingStart(Time duration) override
649 {
650 }
651
652 void NotifySleep() override
653 {
654 }
655
656 void NotifyOff() override
657 {
658 }
659
660 void NotifyWakeup() override
661 {
662 }
663
664 void NotifyOn() override
665 {
666 }
667
668 /**
669 * Reset function
670 */
678
679 std::size_t m_notifications{0}; ///< Number of CCA notifications
680 Time m_endCcaBusy{Seconds(0)}; ///< End of the CCA-BUSY duration
682 WIFI_CHANLIST_PRIMARY}; ///< Channel type indication for the last CCA-BUSY notification
683 std::vector<Time>
684 m_lastPer20MhzCcaBusyDurations{}; ///< End of the CCA-BUSY durations per 20 MHz
685};
686
687/**
688 * \ingroup wifi-test
689 * \ingroup tests
690 *
691 * \brief Wifi Phy Threshold Test base class
692 */
694{
695 public:
697
698 private:
699 void DoSetup() override;
700 void DoRun() override;
701 void DoTeardown() override;
702
703 /**
704 * Send an HE SU PPDU
705 * \param txPower the transmit power
706 * \param frequency the center frequency the transmitter is operating on
707 * \param bandwidth the bandwidth to use for the transmission
708 */
709 void SendHeSuPpdu(dBm_u txPower, MHz_u frequency, MHz_u bandwidth);
710
711 /**
712 * Start to generate a signal
713 * \param signalGenerator the signal generator to use
714 * \param txPower the transmit power
715 * \param frequency the center frequency of the signal to send
716 * \param bandwidth the bandwidth of the signal to send
717 * \param duration the duration of the signal
718 */
719 void StartSignal(Ptr<WaveformGenerator> signalGenerator,
720 dBm_u txPower,
721 MHz_u frequency,
722 MHz_u bandwidth,
723 Time duration);
724 /**
725 * Stop to generate a signal
726 * \param signalGenerator the signal generator to use
727 */
728 void StopSignal(Ptr<WaveformGenerator> signalGenerator);
729
730 /**
731 * Check the PHY state
732 * \param expectedState the expected state of the PHY
733 */
734 void CheckPhyState(WifiPhyState expectedState);
735 /// \copydoc CheckPhyState
736 void DoCheckPhyState(WifiPhyState expectedState);
737
738 /**
739 * Check the last CCA-BUSY notification
740 * \param expectedEndTime the expected CCA-BUSY end time
741 * \param expectedChannelType the expected channel type
742 * \param expectedPer20MhzDurations the expected per-20 MHz CCA-BUSY durations
743 */
744 void CheckLastCcaBusyNotification(Time expectedEndTime,
745 WifiChannelListType expectedChannelType,
746 const std::vector<Time>& expectedPer20MhzDurations);
747
748 /**
749 * Log scenario description
750 *
751 * \param log the scenario description to add to log
752 */
753 void LogScenario(const std::string& log) const;
754
755 /**
756 * structure that holds information to generate signals
757 */
759 {
760 dBm_u power{0.0}; //!< transmit power to use
761 Time startTime{Seconds(0)}; //!< time at which transmission will be started
762 Time duration{Seconds(0)}; //!< the duration of the transmission
763 MHz_u centerFreq{0}; //!< center frequency to use
764 MHz_u bandwidth{0}; //!< bandwidth to use
765 };
766
767 /**
768 * structure that holds information to generate PPDUs
769 */
771 {
772 dBm_u power{0.0}; //!< transmit power to use
773 Time startTime{Seconds(0)}; //!< time at which transmission will be started
774 MHz_u centerFreq{0}; //!< center frequency to use
775 MHz_u bandwidth{0}; //!< bandwidth to use
776 };
777
778 /**
779 * structure that holds information to perform PHY state check
780 */
782 {
783 Time timePoint{Seconds(0)}; //!< time at which the check will performed
784 WifiPhyState expectedPhyState{WifiPhyState::IDLE}; //!< expected PHY state
785 };
786
787 /**
788 * structure that holds information to perform CCA check
789 */
791 {
792 Time timePoint{Seconds(0)}; //!< time at which the check will performed
793 Time expectedCcaEndTime{Seconds(0)}; //!< expected CCA_BUSY end time
796 std::vector<Time> expectedPer20MhzDurations{}; //!< expected per-20 MHz CCA duration
797 };
798
799 /**
800 * Schedule test to perform.
801 * \param delay the reference delay to schedule the events
802 * \param generatedSignals the vector of signals to be generated
803 * \param generatedPpdus the vector of PPDUs to be generated
804 * \param stateCheckpoints the vector of PHY state checks
805 * \param ccaCheckpoints the vector of PHY CCA checks
806 */
807 void ScheduleTest(Time delay,
808 const std::vector<TxSignalInfo>& generatedSignals,
809 const std::vector<TxPpduInfo>& generatedPpdus,
810 const std::vector<StateCheckPoint>& stateCheckpoints,
811 const std::vector<CcaCheckPoint>& ccaCheckpoints);
812
813 /**
814 * Reset function
815 */
816 void Reset();
817
818 /**
819 * Run one function
820 */
821 void RunOne();
822
823 Ptr<SpectrumWifiPhy> m_rxPhy; ///< PHY object of the receiver
824 Ptr<SpectrumWifiPhy> m_txPhy; ///< PHY object of the transmitter
825
826 std::vector<Ptr<WaveformGenerator>> m_signalGenerators; ///< Generators of non-wifi signals
827 std::size_t
828 m_numSignalGenerators; ///< The number of non-wifi signals generators needed for the test
829
830 std::shared_ptr<CcaTestPhyListener>
831 m_rxPhyStateListener; ///< Listener for PHY state transitions
832
833 MHz_u m_frequency; ///< Operating frequency
834 MHz_u m_channelWidth; ///< Operating channel width
835};
836
838 : TestCase("Wi-Fi PHY CCA indication test"),
839 m_numSignalGenerators(2),
840 m_frequency(P20_CENTER_FREQUENCY),
841 m_channelWidth(20)
842{
843}
844
845void
847 dBm_u txPower,
848 MHz_u frequency,
849 MHz_u bandwidth,
850 Time duration)
851{
852 NS_LOG_FUNCTION(this << signalGenerator << txPower << frequency << bandwidth << duration);
853
854 BandInfo bandInfo;
855 bandInfo.fc = frequency * 1e6;
856 bandInfo.fl = bandInfo.fc - ((bandwidth / 2) * 1e6);
857 bandInfo.fh = bandInfo.fc + ((bandwidth / 2) * 1e6);
858 Bands bands;
859 bands.push_back(bandInfo);
860
861 Ptr<SpectrumModel> spectrumSignal = Create<SpectrumModel>(bands);
862 Ptr<SpectrumValue> signalPsd = Create<SpectrumValue>(spectrumSignal);
863 *signalPsd = DbmToW(txPower) / (bandwidth * 1e6);
864
865 signalGenerator->SetTxPowerSpectralDensity(signalPsd);
866 signalGenerator->SetPeriod(duration);
867 signalGenerator->Start();
868 Simulator::Schedule(duration, &WifiPhyCcaIndicationTest::StopSignal, this, signalGenerator);
869}
870
871void
873{
874 NS_LOG_FUNCTION(this << signalGenerator);
875 signalGenerator->Stop();
876}
877
878void
880{
881 NS_LOG_FUNCTION(this << txPower);
882
883 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
884 frequency,
885 bandwidth,
888 ->number;
889 m_txPhy->SetOperatingChannel(
890 WifiPhy::ChannelTuple{channelNum, bandwidth, WIFI_PHY_BAND_5GHZ, 0});
891
893 0,
895 NanoSeconds(800),
896 1,
897 1,
898 0,
899 bandwidth,
900 false);
901
902 Ptr<Packet> pkt = Create<Packet>(1000);
903 WifiMacHeader hdr;
905 hdr.SetQosTid(0);
906 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
907
908 m_txPhy->SetTxPowerStart(txPower);
909 m_txPhy->SetTxPowerEnd(txPower);
910
911 m_txPhy->Send(psdu, txVector);
912}
913
914void
916{
917 // This is needed to make sure PHY state will be checked as the last event if a state change
918 // occurred at the exact same time as the check
920}
921
922void
924{
925 WifiPhyState currentState;
926 PointerValue ptr;
927 m_rxPhy->GetAttribute("State", ptr);
929 currentState = state->GetState();
930 NS_TEST_ASSERT_MSG_EQ(currentState,
931 expectedState,
932 "PHY State " << currentState << " does not match expected state "
933 << expectedState << " at " << Simulator::Now());
934}
935
936void
938 Time expectedEndTime,
939 WifiChannelListType expectedChannelType,
940 const std::vector<Time>& expectedPer20MhzDurations)
941{
943 expectedEndTime,
944 "PHY CCA end time " << m_rxPhyStateListener->m_endCcaBusy
945 << " does not match expected time " << expectedEndTime
946 << " at " << Simulator::Now());
948 expectedChannelType,
949 "PHY CCA-BUSY for " << m_rxPhyStateListener->m_lastCcaBusyChannelType
950 << " does not match expected channel type "
951 << expectedChannelType << " at " << Simulator::Now());
953 expectedPer20MhzDurations.size(),
954 "PHY CCA-BUSY per-20 MHz durations does not match expected vector"
955 << " at " << Simulator::Now());
956 for (std::size_t i = 0; i < expectedPer20MhzDurations.size(); ++i)
957 {
959 expectedPer20MhzDurations.at(i),
960 "PHY CCA-BUSY per-20 MHz duration at index "
961 << i << " does not match expected duration at "
962 << Simulator::Now());
963 }
964}
965
966void
967WifiPhyCcaIndicationTest::LogScenario(const std::string& log) const
968{
969 NS_LOG_INFO(log);
970}
971
972void
974 const std::vector<TxSignalInfo>& generatedSignals,
975 const std::vector<TxPpduInfo>& generatedPpdus,
976 const std::vector<StateCheckPoint>& stateCheckpoints,
977 const std::vector<CcaCheckPoint>& ccaCheckpoints)
978{
979 for (const auto& generatedPpdu : generatedPpdus)
980 {
981 Simulator::Schedule(delay + generatedPpdu.startTime,
983 this,
984 generatedPpdu.power,
985 generatedPpdu.centerFreq,
986 generatedPpdu.bandwidth);
987 }
988
989 std::size_t index = 0;
990 for (const auto& generatedSignal : generatedSignals)
991 {
992 Simulator::Schedule(delay + generatedSignal.startTime,
994 this,
995 m_signalGenerators.at(index++),
996 generatedSignal.power,
997 generatedSignal.centerFreq,
998 generatedSignal.bandwidth,
999 generatedSignal.duration);
1000 }
1001
1002 for (const auto& checkpoint : ccaCheckpoints)
1003 {
1004 Simulator::Schedule(delay + checkpoint.timePoint,
1006 this,
1007 Simulator::Now() + delay + checkpoint.expectedCcaEndTime,
1008 checkpoint.expectedChannelListType,
1009 checkpoint.expectedPer20MhzDurations);
1010 }
1011
1012 for (const auto& checkpoint : stateCheckpoints)
1013 {
1014 Simulator::Schedule(delay + checkpoint.timePoint,
1016 this,
1017 checkpoint.expectedPhyState);
1018 }
1019
1021}
1022
1023void
1028
1029void
1031{
1032 // WifiHelper::EnableLogComponents ();
1033 // LogComponentEnable ("WifiPhyCcaTest", LOG_LEVEL_ALL);
1034
1036
1037 Ptr<Node> rxNode = CreateObject<Node>();
1039 rxDev->SetStandard(WIFI_STANDARD_80211ax);
1041 rxDev->SetVhtConfiguration(vhtConfiguration);
1043 m_rxPhyStateListener = std::make_unique<CcaTestPhyListener>();
1044 m_rxPhy->RegisterListener(m_rxPhyStateListener);
1046 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
1048 m_rxPhy->SetErrorRateModel(rxErrorModel);
1049 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
1051 m_rxPhy->SetPreambleDetectionModel(preambleDetectionModel);
1052 m_rxPhy->AddChannel(spectrumChannel);
1053 m_rxPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
1054 m_rxPhy->SetDevice(rxDev);
1055 rxDev->SetPhy(m_rxPhy);
1056 rxNode->AddDevice(rxDev);
1057
1058 Ptr<Node> txNode = CreateObject<Node>();
1061 m_txPhy->SetAttribute("ChannelSwitchDelay", TimeValue(Seconds(0)));
1063 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
1065 m_txPhy->SetErrorRateModel(txErrorModel);
1066 m_txPhy->AddChannel(spectrumChannel);
1067 m_txPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
1068 m_txPhy->SetDevice(txDev);
1069 txDev->SetPhy(m_txPhy);
1070 txNode->AddDevice(txDev);
1071
1072 for (std::size_t i = 0; i < m_numSignalGenerators; ++i)
1073 {
1074 Ptr<Node> signalGeneratorNode = CreateObject<Node>();
1075 Ptr<NonCommunicatingNetDevice> signalGeneratorDev =
1078 signalGenerator->SetDevice(signalGeneratorDev);
1079 signalGenerator->SetChannel(spectrumChannel);
1080 signalGenerator->SetDutyCycle(1);
1081 signalGeneratorNode->AddDevice(signalGeneratorDev);
1082 m_signalGenerators.push_back(signalGenerator);
1083 }
1084}
1085
1086void
1088{
1091 int64_t streamNumber = 0;
1092 m_rxPhy->AssignStreams(streamNumber);
1093 m_txPhy->AssignStreams(streamNumber);
1094
1095 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
1100 ->number;
1101
1102 m_rxPhy->SetOperatingChannel(
1104 m_txPhy->SetOperatingChannel(
1106
1107 std::vector<Time> expectedPer20MhzCcaBusyDurations{};
1108 Time delay = Seconds(0.0);
1110 delay += Seconds(1.0);
1111
1112 //----------------------------------------------------------------------------------------------------------------------------------
1113 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal below the
1114 // energy detection threshold occupies P20
1115 Simulator::Schedule(delay,
1117 this,
1118 "Reception of a signal that occupies P20 below ED threshold");
1119 ScheduleTest(delay,
1120 {{-65.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
1121 {},
1122 {
1123 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1124 {MicroSeconds(100) - smallDelta,
1125 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1126 {MicroSeconds(100) + smallDelta,
1127 WifiPhyState::IDLE} // IDLE just after the transmission ends
1128 },
1129 {});
1130 delay += Seconds(1.0);
1131
1132 //----------------------------------------------------------------------------------------------------------------------------------
1133 // Verify PHY state is CCA-BUSY as long as a 20 MHz signal above the energy detection threshold
1134 // occupies P20
1135 Simulator::Schedule(delay,
1137 this,
1138 "Reception of signal that occupies P20 above ED threshold");
1139 ScheduleTest(delay,
1140 {{-60.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
1141 {},
1142 {
1143 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1144 {MicroSeconds(100) - smallDelta,
1145 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1146 {MicroSeconds(100) + smallDelta,
1147 WifiPhyState::IDLE} // IDLE just after the transmission ends
1148 },
1149 {{MicroSeconds(100) - smallDelta,
1150 MicroSeconds(100),
1152 ((m_channelWidth > 20)
1153 ? ((m_channelWidth > 40)
1154 ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1155 MicroSeconds(0),
1156 MicroSeconds(0),
1157 MicroSeconds(0),
1158 MicroSeconds(0),
1159 MicroSeconds(0),
1160 MicroSeconds(0),
1161 MicroSeconds(0)}
1162 : std::vector<Time>{MicroSeconds(100),
1163 MicroSeconds(0),
1164 MicroSeconds(0),
1165 MicroSeconds(0)})
1166 : std::vector<Time>{MicroSeconds(100), MicroSeconds(0)})
1167 : std::vector<Time>{})}});
1168 delay += Seconds(1.0);
1169
1170 //----------------------------------------------------------------------------------------------------------------------------------
1171 // Verify PHY state is CCA-BUSY as long as the sum of 20 MHz signals occupying P20 is above the
1172 // energy detection threshold
1173 Simulator::Schedule(delay,
1175 this,
1176 "Reception of two 20 MHz signals that occupies P20 below ED threshold with "
1177 "sum above ED threshold");
1179 delay,
1180 {{-64.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, 20},
1181 {-65.0, MicroSeconds(50), MicroSeconds(200), P20_CENTER_FREQUENCY, 20}},
1182 {},
1183 {
1184 {MicroSeconds(50) + aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1185 {MicroSeconds(100) - smallDelta,
1186 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1187 {MicroSeconds(100) + smallDelta,
1188 WifiPhyState::IDLE} // IDLE just after the transmission ends
1189 },
1190 {{MicroSeconds(100) - smallDelta,
1191 MicroSeconds(100),
1193 ((m_channelWidth > 20)
1194 ? ((m_channelWidth > 40)
1195 ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(50),
1196 MicroSeconds(0),
1197 MicroSeconds(0),
1198 MicroSeconds(0),
1199 MicroSeconds(0),
1200 MicroSeconds(0),
1201 MicroSeconds(0),
1202 MicroSeconds(0)}
1203 : std::vector<Time>{MicroSeconds(50),
1204 MicroSeconds(0),
1205 MicroSeconds(0),
1206 MicroSeconds(0)})
1207 : std::vector<Time>{MicroSeconds(50), MicroSeconds(0)})
1208 : std::vector<Time>{})}});
1209 delay += Seconds(1.0);
1210
1211 //----------------------------------------------------------------------------------------------------------------------------------
1212 // Verify PHY state stays IDLE when a 20 MHz HE SU PPDU with received power below the
1213 // corresponding CCA sensitivity threshold occupies P20
1215 delay,
1217 this,
1218 "Reception of a 20 MHz HE PPDU that occupies P20 below CCA sensitivity threshold");
1219 ScheduleTest(delay,
1220 {},
1221 {{-85.0, MicroSeconds(0), P20_CENTER_FREQUENCY, 20}},
1222 {
1223 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1224 {PpduDurations.at(20) - smallDelta,
1225 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1226 {PpduDurations.at(20) + smallDelta,
1227 WifiPhyState::IDLE} // IDLE just after the transmission ends
1228 },
1229 {});
1230 delay += Seconds(1.0);
1231
1232 //----------------------------------------------------------------------------------------------------------------------------------
1233 // Verify PHY state transitions to CCA-BUSY when an HE SU PPDU with received power above the CCA
1234 // sensitivity threshold occupies P20. The per20Bitmap should indicate idle on the primary 20
1235 // MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1237 delay,
1239 this,
1240 "Reception of a 20 MHz HE PPDU that occupies P20 above CCA sensitivity threshold");
1242 delay,
1243 {},
1244 {{-80.0, MicroSeconds(0), P20_CENTER_FREQUENCY, 20}},
1245 {
1246 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1247 {PpduDurations.at(20) - smallDelta,
1248 WifiPhyState::RX}, // RX just before the transmission ends
1249 {PpduDurations.at(20) + smallDelta,
1250 WifiPhyState::IDLE} // IDLE just after the transmission ends
1251 },
1252 {{aCcaTime,
1253 MicroSeconds(16),
1255 ((m_channelWidth > 20)
1256 ? ((m_channelWidth > 40)
1257 ? ((m_channelWidth > 80)
1258 ? std::vector<Time>{Seconds(0),
1259 Seconds(0),
1260 Seconds(0),
1261 Seconds(0),
1262 Seconds(0),
1263 Seconds(0),
1264 Seconds(0),
1265 Seconds(0)}
1266 : std::vector<Time>{Seconds(0), Seconds(0), Seconds(0), Seconds(0)})
1267 : std::vector<Time>{Seconds(0), Seconds(0)})
1268 : std::vector<Time>{})}});
1269 delay += Seconds(1.0);
1270
1271 //----------------------------------------------------------------------------------------------------------------------------------
1272 // Verify PHY state stays IDLE when a 40 MHz HE SU PPDU with received power below the CCA
1273 // sensitivity threshold occupies P40
1275 delay,
1277 this,
1278 "Reception of a 40 MHz HE PPDU that occupies P20 below CCA sensitivity threshold");
1279 ScheduleTest(delay,
1280 {},
1281 {{-80.0, MicroSeconds(0), P40_CENTER_FREQUENCY, 40}},
1282 {
1283 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1284 {PpduDurations.at(40) - smallDelta,
1285 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1286 {PpduDurations.at(40) + smallDelta,
1287 WifiPhyState::IDLE} // IDLE just after the transmission ends
1288 },
1289 {});
1290 delay += Seconds(1.0);
1291
1292 //----------------------------------------------------------------------------------------------------------------------------------
1293 // Verify PHY state transitions to CCA-BUSY when an HE SU PPDU with received power above the CCA
1294 // sensitivity threshold occupies P40. The per20Bitmap should indicate idle on the primary 20
1295 // MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1297 delay,
1299 this,
1300 "Reception of a 40 MHz HE PPDU that occupies P40 above CCA sensitivity threshold");
1302 delay,
1303 {},
1304 {{-75.0, MicroSeconds(0), P40_CENTER_FREQUENCY, 40}},
1305 {
1306 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1307 {PpduDurations.at(40) - smallDelta,
1308 (m_channelWidth > 20)
1309 ? WifiPhyState::RX
1310 : WifiPhyState::CCA_BUSY}, // RX or IDLE just before the transmission ends
1311 {PpduDurations.at(40) + smallDelta,
1312 WifiPhyState::IDLE} // IDLE just after the transmission ends
1313 },
1314 {{aCcaTime,
1315 MicroSeconds(16),
1317 ((m_channelWidth > 20)
1318 ? ((m_channelWidth > 40)
1319 ? ((m_channelWidth > 80)
1320 ? std::vector<Time>{Seconds(0),
1321 Seconds(0),
1322 Seconds(0),
1323 Seconds(0),
1324 Seconds(0),
1325 Seconds(0),
1326 Seconds(0),
1327 Seconds(0)}
1328 : std::vector<Time>{Seconds(0), Seconds(0), Seconds(0), Seconds(0)})
1329 : std::vector<Time>{Seconds(0), Seconds(0)})
1330 : std::vector<Time>{})}});
1331 delay += Seconds(1.0);
1332
1333 if (m_channelWidth > 20)
1334 {
1335 //----------------------------------------------------------------------------------------------------------------------------------
1336 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a 20 MHz signal
1337 // below the energy detection threshold occupies S20
1338 Simulator::Schedule(delay,
1340 this,
1341 "Reception of a 20 MHz signal that occupies S20 below ED threshold");
1342 ScheduleTest(delay,
1343 {{-65.0, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
1344 {},
1345 {
1346 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1347 {MicroSeconds(100) - smallDelta,
1348 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1349 {MicroSeconds(100) + smallDelta,
1350 WifiPhyState::IDLE} // IDLE just after the transmission ends
1351 },
1352 {});
1353 delay += Seconds(1.0);
1354
1355 //----------------------------------------------------------------------------------------------------------------------------------
1356 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz signal
1357 // above the energy detection threshold occupies S20
1358 Simulator::Schedule(delay,
1360 this,
1361 "Reception of a 20 MHz signal that occupies S20 above ED threshold");
1363 delay,
1364 {{-60.0, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
1365 {},
1366 {
1367 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1368 {MicroSeconds(100) - smallDelta,
1369 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1370 {MicroSeconds(100) + smallDelta,
1371 WifiPhyState::IDLE} // IDLE just after the transmission ends
1372 },
1373 {{MicroSeconds(100) - smallDelta,
1374 MicroSeconds(100),
1376 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1377 MicroSeconds(100),
1378 MicroSeconds(0),
1379 MicroSeconds(0),
1380 MicroSeconds(0),
1381 MicroSeconds(0),
1382 MicroSeconds(0),
1383 MicroSeconds(0)}
1384 : std::vector<Time>{MicroSeconds(0),
1385 MicroSeconds(100),
1386 MicroSeconds(0),
1387 MicroSeconds(0)})
1388 : std::vector<Time>{MicroSeconds(0), MicroSeconds(100)})}});
1389 delay += Seconds(1.0);
1390
1391 //----------------------------------------------------------------------------------------------------------------------------------
1392 // Verify PHY state is CCA-BUSY as long as a 40 MHz signal above the energy detection
1393 // threshold occupies P40
1394 Simulator::Schedule(delay,
1396 this,
1397 "Reception of a 40 MHz signal that occupies P40 above ED threshold");
1399 delay,
1400 {{-55.0, MicroSeconds(0), MicroSeconds(100), P40_CENTER_FREQUENCY, 40}},
1401 {},
1402 {
1403 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1404 {MicroSeconds(100) - smallDelta,
1405 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1406 {MicroSeconds(100) + smallDelta,
1407 WifiPhyState::IDLE} // IDLE just after the transmission ends
1408 },
1409 {{MicroSeconds(100) - smallDelta,
1410 MicroSeconds(100),
1412 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1413 MicroSeconds(100),
1414 MicroSeconds(0),
1415 MicroSeconds(0),
1416 MicroSeconds(0),
1417 MicroSeconds(0),
1418 MicroSeconds(0),
1419 MicroSeconds(0)}
1420 : std::vector<Time>{MicroSeconds(100),
1421 MicroSeconds(100),
1422 MicroSeconds(0),
1423 MicroSeconds(0)})
1424 : std::vector<Time>{MicroSeconds(100), MicroSeconds(100)})}});
1425 delay += Seconds(1.0);
1426
1427 //----------------------------------------------------------------------------------------------------------------------------------
1428 // Verify PHY notifies CCA-BUSY for the primary channel while the secondary channel was
1429 // already in CCA-BUSY state
1430 Simulator::Schedule(delay,
1432 this,
1433 "Reception of a signal that occupies S20 followed by the reception of "
1434 "another signal that occupies P20");
1436 delay,
1437 {{-60.0, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, 20},
1438 {-60.0, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
1439 {},
1440 {
1441 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
1442 {MicroSeconds(50) + aCcaTime,
1443 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after aCCATime that
1444 // followed the second transmission
1445 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
1446 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1447 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
1448 WifiPhyState::IDLE} // IDLE just after the transmission ends
1449 },
1450 {{aCcaTime, // notification upon reception of the first signal
1451 MicroSeconds(100),
1453 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1454 MicroSeconds(100),
1455 MicroSeconds(0),
1456 MicroSeconds(0),
1457 MicroSeconds(0),
1458 MicroSeconds(0),
1459 MicroSeconds(0),
1460 MicroSeconds(0)}
1461 : std::vector<Time>{MicroSeconds(0),
1462 MicroSeconds(100),
1463 MicroSeconds(0),
1464 MicroSeconds(0)})
1465 : std::vector<Time>{MicroSeconds(0), MicroSeconds(100)})},
1466 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
1467 MicroSeconds(50) + MicroSeconds(100),
1469 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1470 MicroSeconds(50),
1471 MicroSeconds(0),
1472 MicroSeconds(0),
1473 MicroSeconds(0),
1474 MicroSeconds(0),
1475 MicroSeconds(0),
1476 MicroSeconds(0)}
1477 : std::vector<Time>{MicroSeconds(100),
1478 MicroSeconds(50),
1479 MicroSeconds(0),
1480 MicroSeconds(0)})
1481 : std::vector<Time>{MicroSeconds(100), MicroSeconds(50)})}});
1482 delay += Seconds(1.0);
1483
1484 //----------------------------------------------------------------------------------------------------------------------------------
1485 // Verify PHY updates per-20 MHz CCA durations if a signal arrives on the secondary channel
1486 // while primary is CCA-BUSY
1487 Simulator::Schedule(delay,
1489 this,
1490 "Reception of a signal that occupies P20 followed by the reception of "
1491 "another signal that occupies S20");
1493 delay,
1494 {{-60.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, 20},
1495 {-60.0, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
1496 {},
1497 {
1498 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1499 {MicroSeconds(50) + aCcaTime,
1500 WifiPhyState::CCA_BUSY}, // state of primary is still CCA-BUSY after aCCATime that
1501 // followed the second transmission
1502 {MicroSeconds(100) - smallDelta,
1503 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the first transmission ends
1504 {MicroSeconds(100) + smallDelta,
1505 WifiPhyState::IDLE} // IDLE just after the first transmission ends
1506 },
1507 {{aCcaTime, // notification upon reception of the first signal
1508 MicroSeconds(100),
1510 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1511 MicroSeconds(0),
1512 MicroSeconds(0),
1513 MicroSeconds(0),
1514 MicroSeconds(0),
1515 MicroSeconds(0),
1516 MicroSeconds(0),
1517 MicroSeconds(0)}
1518 : std::vector<Time>{MicroSeconds(100),
1519 MicroSeconds(0),
1520 MicroSeconds(0),
1521 MicroSeconds(0)})
1522 : std::vector<Time>{MicroSeconds(100), MicroSeconds(0)})},
1523 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
1524 MicroSeconds(100),
1526 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(50),
1527 MicroSeconds(100),
1528 MicroSeconds(0),
1529 MicroSeconds(0),
1530 MicroSeconds(0),
1531 MicroSeconds(0),
1532 MicroSeconds(0),
1533 MicroSeconds(0)}
1534 : std::vector<Time>{MicroSeconds(50),
1535 MicroSeconds(100),
1536 MicroSeconds(0),
1537 MicroSeconds(0)})
1538 : std::vector<Time>{MicroSeconds(50), MicroSeconds(100)})}});
1539 delay += Seconds(1.0);
1540
1541 //----------------------------------------------------------------------------------------------------------------------------------
1542 // Verify PHY state stays IDLE when a 20 MHz HE SU PPDU with received power below the CCA
1543 // sensitivity threshold occupies S40
1545 delay,
1547 this,
1548 "Reception of a 20 MHz HE PPDU that occupies S20 below CCA sensitivity threshold");
1549 ScheduleTest(delay,
1550 {},
1551 {{-75.0, MicroSeconds(0), S20_CENTER_FREQUENCY, 20}},
1552 {
1553 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1554 {PpduDurations.at(20) - smallDelta,
1555 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1556 {PpduDurations.at(20) + smallDelta,
1557 WifiPhyState::IDLE} // IDLE just after the transmission ends
1558 },
1559 {});
1560 delay += Seconds(1.0);
1561
1562 //----------------------------------------------------------------------------------------------------------------------------------
1563 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz HE SU PPDU
1564 // with received power above the CCA sensitivity threshold occupies S20
1566 delay,
1568 this,
1569 "Reception of a 20 MHz HE PPDU that occupies S20 above CCA sensitivity threshold");
1570 ScheduleTest(delay,
1571 {},
1572 {{-70.0, MicroSeconds(0), S20_CENTER_FREQUENCY, 20}},
1573 {
1574 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1575 {PpduDurations.at(20) - smallDelta,
1576 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1577 {PpduDurations.at(20) + smallDelta,
1578 WifiPhyState::IDLE} // IDLE just after the transmission ends
1579 },
1580 {{aCcaTime,
1581 PpduDurations.at(20),
1583 ((m_channelWidth > 40)
1584 ? ((m_channelWidth > 80) ? std::vector<Time>{NanoSeconds(0),
1585 PpduDurations.at(20),
1586 NanoSeconds(0),
1587 NanoSeconds(0),
1588 NanoSeconds(0),
1589 NanoSeconds(0),
1590 NanoSeconds(0),
1591 NanoSeconds(0)}
1592 : std::vector<Time>{NanoSeconds(0),
1593 PpduDurations.at(20),
1594 NanoSeconds(0),
1595 NanoSeconds(0)})
1596 : std::vector<Time>{NanoSeconds(0), PpduDurations.at(20)})}});
1597 delay += Seconds(1.0);
1598
1599 //----------------------------------------------------------------------------------------------------------------------------------
1600 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a signal
1601 // above the energy detection threshold occupies the S20 while a 40 MHz PPDU below the CCA
1602 // sensitivity threshold is received on P40.
1604 delay,
1606 this,
1607 "Reception of a 20 MHz signal that occupies S20 above ED threshold followed by a 40 "
1608 "MHz HE PPDU that occupies P40 below CCA sensitivity threshold");
1610 delay,
1611 {{-60.0,
1612 MicroSeconds(0),
1613 MicroSeconds(100),
1615 20}}, // signal on S20 above threshold
1616 {{-80.0, MicroSeconds(50), P40_CENTER_FREQUENCY, 40}}, // PPDU on P40 below threshold
1617 {
1618 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // PHY state stays IDLE
1619 },
1620 {{MicroSeconds(50) - smallDelta,
1621 MicroSeconds(100),
1623 ((m_channelWidth > 20)
1624 ? ((m_channelWidth > 40)
1625 ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1626 MicroSeconds(100),
1627 MicroSeconds(0),
1628 MicroSeconds(0),
1629 MicroSeconds(0),
1630 MicroSeconds(0),
1631 MicroSeconds(0),
1632 MicroSeconds(0)}
1633 : std::vector<Time>{MicroSeconds(0),
1634 MicroSeconds(100),
1635 MicroSeconds(0),
1636 MicroSeconds(0)})
1637 : std::vector<Time>{MicroSeconds(0), MicroSeconds(100)})
1638 : std::vector<Time>{})},
1639 {MicroSeconds(100) - smallDelta,
1640 MicroSeconds(100),
1642 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1643 MicroSeconds(46),
1644 MicroSeconds(0),
1645 MicroSeconds(0),
1646 MicroSeconds(0),
1647 MicroSeconds(0),
1648 MicroSeconds(0),
1649 MicroSeconds(0)}
1650 : std::vector<Time>{MicroSeconds(0),
1651 MicroSeconds(46),
1652 MicroSeconds(0),
1653 MicroSeconds(0)})
1654 : std::vector<Time>{MicroSeconds(0), MicroSeconds(46)})}});
1655 delay += Seconds(1.0);
1656 }
1657
1658 if (m_channelWidth > 40)
1659 {
1660 //----------------------------------------------------------------------------------------------------------------------------------
1661 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal below
1662 // the energy detection threshold occupies S40
1663 Simulator::Schedule(delay,
1665 this,
1666 "Reception of a 20 MHz signal that occupies the first subchannel of "
1667 "S40 below ED threshold");
1668 ScheduleTest(delay,
1669 {{-65.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20}},
1670 {},
1671 {
1672 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1673 {MicroSeconds(100) - smallDelta,
1674 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1675 {MicroSeconds(100) + smallDelta,
1676 WifiPhyState::IDLE} // IDLE just after the transmission ends
1677 },
1678 {});
1679 delay += Seconds(1.0);
1680
1681 //----------------------------------------------------------------------------------------------------------------------------------
1682 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy detection
1683 // threshold occupies the first 20 MHz subchannel of the S40: 27.3.20.6.4: Any signal within
1684 // the secondary 40 MHz channel at or above a threshold of –59 dBm within a period of
1685 // aCCATime after the signal arrives at the receiver’s antenna(s).
1686 Simulator::Schedule(delay,
1688 this,
1689 "Reception of a 20 MHz signal that occupies the first subchannel of "
1690 "S40 above ED threshold");
1691 ScheduleTest(delay,
1692 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20}},
1693 {},
1694 {
1695 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1696 {MicroSeconds(100) - smallDelta,
1697 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1698 {MicroSeconds(100) + smallDelta,
1699 WifiPhyState::IDLE} // IDLE just after the transmission ends
1700 },
1701 {{MicroSeconds(100) - smallDelta,
1702 MicroSeconds(100),
1704 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1705 MicroSeconds(0),
1706 MicroSeconds(100),
1707 MicroSeconds(0),
1708 MicroSeconds(0),
1709 MicroSeconds(0),
1710 MicroSeconds(0),
1711 MicroSeconds(0)}
1712 : std::vector<Time>{MicroSeconds(0),
1713 MicroSeconds(0),
1714 MicroSeconds(100),
1715 MicroSeconds(0)})}});
1716 delay += Seconds(1.0);
1717
1718 //----------------------------------------------------------------------------------------------------------------------------------
1719 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection threshold
1720 // occupies the second 20 MHz subchannel of the S40
1721 Simulator::Schedule(delay,
1723 this,
1724 "Reception of a 20 MHz signal that occupies the second subchannel of "
1725 "S40 below ED threshold");
1726 ScheduleTest(delay,
1727 {{-65.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY + 10, 20}},
1728 {},
1729 {
1730 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1731 {MicroSeconds(100) - smallDelta,
1732 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1733 {MicroSeconds(100) + smallDelta,
1734 WifiPhyState::IDLE} // IDLE just after the transmission ends
1735 },
1736 {});
1737 delay += Seconds(1.0);
1738
1739 //----------------------------------------------------------------------------------------------------------------------------------
1740 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy detection
1741 // threshold occupies the second 20 MHz subchannel of the S40: 27.3.20.6.4: Any signal
1742 // within the secondary 40 MHz channel at or above a threshold of –59 dBm within a period of
1743 // aCCATime after the signal arrives at the receiver’s antenna(s).
1744 Simulator::Schedule(delay,
1746 this,
1747 "Reception of a 20 MHz signal that occupies the second subchannel of "
1748 "S40 above ED threshold");
1749 ScheduleTest(delay,
1750 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY + 10, 20}},
1751 {},
1752 {
1753 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1754 {MicroSeconds(100) - smallDelta,
1755 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1756 {MicroSeconds(100) + smallDelta,
1757 WifiPhyState::IDLE} // IDLE just after the transmission ends
1758 },
1759 {{MicroSeconds(100) - smallDelta,
1760 MicroSeconds(100),
1762 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1763 MicroSeconds(0),
1764 MicroSeconds(0),
1765 MicroSeconds(100),
1766 MicroSeconds(0),
1767 MicroSeconds(0),
1768 MicroSeconds(0),
1769 MicroSeconds(0)}
1770 : std::vector<Time>{MicroSeconds(0),
1771 MicroSeconds(0),
1772 MicroSeconds(0),
1773 MicroSeconds(100)})}});
1774 delay += Seconds(1.0);
1775
1776 //----------------------------------------------------------------------------------------------------------------------------------
1777 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection threshold
1778 // occupies S40
1779 Simulator::Schedule(delay,
1781 this,
1782 "Reception of a 40 MHz signal that occupies S40 below ED threshold");
1783 ScheduleTest(delay,
1784 {{-60.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY, 40}},
1785 {},
1786 {
1787 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1788 {MicroSeconds(100) - smallDelta,
1789 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1790 {MicroSeconds(100) + smallDelta,
1791 WifiPhyState::IDLE} // IDLE just after the transmission ends
1792 },
1793 {});
1794 delay += Seconds(1.0);
1795
1796 //----------------------------------------------------------------------------------------------------------------------------------
1797 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy detection
1798 // threshold occupies S40: 27.3.20.6.4: Any signal within the secondary 40 MHz channel at or
1799 // above a threshold of –59 dBm within a period of aCCATime after the signal arrives at the
1800 // receiver’s antenna(s).
1801 Simulator::Schedule(delay,
1803 this,
1804 "Reception of a 20 MHz signal that occupies the second subchannel of "
1805 "S40 above ED threshold");
1806 ScheduleTest(delay,
1807 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY, 40}},
1808 {},
1809 {
1810 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1811 {MicroSeconds(100) - smallDelta,
1812 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1813 {MicroSeconds(100) + smallDelta,
1814 WifiPhyState::IDLE} // IDLE just after the transmission ends
1815 },
1816 {{MicroSeconds(100) - smallDelta,
1817 MicroSeconds(100),
1819 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1820 MicroSeconds(0),
1821 MicroSeconds(100),
1822 MicroSeconds(100),
1823 MicroSeconds(0),
1824 MicroSeconds(0),
1825 MicroSeconds(0),
1826 MicroSeconds(0)}
1827 : std::vector<Time>{MicroSeconds(0),
1828 MicroSeconds(0),
1829 MicroSeconds(100),
1830 MicroSeconds(100)})}});
1831 delay += Seconds(1.0);
1832
1833 //----------------------------------------------------------------------------------------------------------------------------------
1834 // Verify PHY state is CCA-BUSY as long as a 80 MHz signal above the energy detection
1835 // threshold occupies P80
1836 Simulator::Schedule(delay,
1838 this,
1839 "Reception of a 80 MHz signal that occupies P80 above ED threshold");
1840 ScheduleTest(delay,
1841 {{-55.0, MicroSeconds(0), MicroSeconds(100), P80_CENTER_FREQUENCY, 80}},
1842 {},
1843 {
1844 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1845 {MicroSeconds(100) - smallDelta,
1846 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1847 {MicroSeconds(100) + smallDelta,
1848 WifiPhyState::IDLE} // IDLE just after the transmission ends
1849 },
1850 {{MicroSeconds(100) - smallDelta,
1851 MicroSeconds(100),
1853 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1854 MicroSeconds(100),
1855 MicroSeconds(100),
1856 MicroSeconds(100),
1857 MicroSeconds(0),
1858 MicroSeconds(0),
1859 MicroSeconds(0),
1860 MicroSeconds(0)}
1861 : std::vector<Time>{MicroSeconds(100),
1862 MicroSeconds(100),
1863 MicroSeconds(100),
1864 MicroSeconds(100)})}});
1865 delay += Seconds(1.0);
1866
1867 //----------------------------------------------------------------------------------------------------------------------------------
1868 // Verify PHY notifies CCA-BUSY for the P20 channel while the S40 channel was already in
1869 // CCA-BUSY state
1870 Simulator::Schedule(delay,
1872 this,
1873 "Reception of a 20 MHz signal that occupies S40 followed by the "
1874 "reception of another 20 MHz signal that occupies P20");
1876 delay,
1877 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20},
1878 {-55.0, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
1879 {},
1880 {
1881 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
1882 {MicroSeconds(50) + aCcaTime,
1883 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after aCCATime that
1884 // followed the second transmission
1885 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
1886 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1887 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
1888 WifiPhyState::IDLE} // IDLE just after the transmission ends
1889 },
1890 {{aCcaTime, // notification upon reception of the first signal
1891 MicroSeconds(100),
1893 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1894 MicroSeconds(0),
1895 MicroSeconds(100),
1896 MicroSeconds(0),
1897 MicroSeconds(0),
1898 MicroSeconds(0),
1899 MicroSeconds(0),
1900 MicroSeconds(0)}
1901 : std::vector<Time>{MicroSeconds(0),
1902 MicroSeconds(0),
1903 MicroSeconds(100),
1904 MicroSeconds(0)})},
1905 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
1906 MicroSeconds(50) + MicroSeconds(100),
1908 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1909 MicroSeconds(0),
1910 MicroSeconds(50),
1911 MicroSeconds(0),
1912 MicroSeconds(0),
1913 MicroSeconds(0),
1914 MicroSeconds(0),
1915 MicroSeconds(0)}
1916 : std::vector<Time>{MicroSeconds(100),
1917 MicroSeconds(0),
1918 MicroSeconds(50),
1919 MicroSeconds(0)})}});
1920 delay += Seconds(1.0);
1921
1922 //----------------------------------------------------------------------------------------------------------------------------------
1923 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S40
1924 // channel was already in CCA-BUSY state
1925 Simulator::Schedule(delay,
1927 this,
1928 "Reception of a signal that occupies S40 followed by the reception of "
1929 "another signal that occupies S20");
1931 delay,
1932 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20},
1933 {-55.0, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
1934 {},
1935 {
1936 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
1937 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // state of primary stays IDLE
1938 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
1939 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1940 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
1941 WifiPhyState::IDLE} // IDLE just after the transmission ends
1942 },
1943 {{aCcaTime, // notification upon reception of the first signal
1944 MicroSeconds(100),
1946 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1947 MicroSeconds(0),
1948 MicroSeconds(100),
1949 MicroSeconds(0),
1950 MicroSeconds(0),
1951 MicroSeconds(0),
1952 MicroSeconds(0),
1953 MicroSeconds(0)}
1954 : std::vector<Time>{MicroSeconds(0),
1955 MicroSeconds(0),
1956 MicroSeconds(100),
1957 MicroSeconds(0)})},
1958 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
1959 MicroSeconds(50) + MicroSeconds(100),
1961 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1962 MicroSeconds(100),
1963 MicroSeconds(50),
1964 MicroSeconds(0),
1965 MicroSeconds(0),
1966 MicroSeconds(0),
1967 MicroSeconds(0),
1968 MicroSeconds(0)}
1969 : std::vector<Time>{MicroSeconds(0),
1970 MicroSeconds(100),
1971 MicroSeconds(50),
1972 MicroSeconds(0)})}});
1973 delay += Seconds(1.0);
1974
1975 //----------------------------------------------------------------------------------------------------------------------------------
1976 // Verify PHY state stays IDLE when a 40 MHz HE SU PPDU with received power below the CCA
1977 // sensitivity threshold occupies S40
1979 delay,
1981 this,
1982 "Reception of a 40 MHz HE PPDU that occupies S40 below CCA sensitivity threshold");
1983 ScheduleTest(delay,
1984 {},
1985 {{-75.0, MicroSeconds(0), S40_CENTER_FREQUENCY, 40}},
1986 {
1987 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1988 {PpduDurations.at(20) - smallDelta,
1989 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1990 {PpduDurations.at(20) + smallDelta,
1991 WifiPhyState::IDLE} // IDLE just after the transmission ends
1992 },
1993 {});
1994 delay += Seconds(1.0);
1995
1996 //----------------------------------------------------------------------------------------------------------------------------------
1997 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 40 MHz HE SU PPDU
1998 // with received power above the CCA sensitivity threshold occupies S40
2000 delay,
2002 this,
2003 "Reception of a 40 MHz HE PPDU that occupies S40 above CCA sensitivity threshold");
2004 ScheduleTest(delay,
2005 {},
2006 {{-70.0, MicroSeconds(0), S40_CENTER_FREQUENCY, 40}},
2007 {
2008 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2009 {PpduDurations.at(40) - smallDelta,
2010 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2011 {PpduDurations.at(40) + smallDelta,
2012 WifiPhyState::IDLE} // IDLE just after the transmission ends
2013 },
2014 {{aCcaTime,
2015 PpduDurations.at(40),
2017 ((m_channelWidth > 80) ? std::vector<Time>{NanoSeconds(0),
2018 NanoSeconds(0),
2019 PpduDurations.at(40),
2020 PpduDurations.at(40),
2021 NanoSeconds(0),
2022 NanoSeconds(0),
2023 NanoSeconds(0),
2024 NanoSeconds(0)}
2025 : std::vector<Time>{NanoSeconds(0),
2026 NanoSeconds(0),
2027 PpduDurations.at(40),
2028 PpduDurations.at(40)})}});
2029 delay += Seconds(1.0);
2030
2031 //----------------------------------------------------------------------------------------------------------------------------------
2032 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a signal
2033 // above the energy detection threshold occupies the S40 while a 80 MHz PPDU below the CCA
2034 // sensitivity threshold is received on P80.
2036 delay,
2038 this,
2039 "Reception of a 40 MHz signal that occupies S40 above ED threshold followed by a 80 "
2040 "MHz HE PPDU that occupies P80 below CCA sensitivity threshold");
2042 delay,
2043 {{-55.0,
2044 MicroSeconds(0),
2045 MicroSeconds(100),
2047 40}}, // signal on S40 above threshold
2048 {{-80.0, MicroSeconds(50), P80_CENTER_FREQUENCY, 80}}, // PPDU on P80 below threshold
2049 {
2050 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // PHY state stays IDLE
2051 },
2052 {{MicroSeconds(50) - smallDelta,
2053 MicroSeconds(100),
2055 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
2056 MicroSeconds(0),
2057 MicroSeconds(100),
2058 MicroSeconds(100),
2059 MicroSeconds(0),
2060 MicroSeconds(0),
2061 MicroSeconds(0),
2062 MicroSeconds(0)}
2063 : std::vector<Time>{MicroSeconds(0),
2064 MicroSeconds(0),
2065 MicroSeconds(100),
2066 MicroSeconds(100)})},
2067 {MicroSeconds(100) - smallDelta,
2068 MicroSeconds(100),
2070 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
2071 MicroSeconds(0),
2072 MicroSeconds(46),
2073 MicroSeconds(46),
2074 MicroSeconds(0),
2075 MicroSeconds(0),
2076 MicroSeconds(0),
2077 MicroSeconds(0)}
2078 : std::vector<Time>{MicroSeconds(0),
2079 MicroSeconds(0),
2080 MicroSeconds(46),
2081 MicroSeconds(46)})}});
2082 delay += Seconds(1.0);
2083 }
2084 else // 20 or 40 MHz receiver
2085 {
2086 //----------------------------------------------------------------------------------------------------------------------------------
2087 // Verify PHY notifies CCA-BUSY when a 80 MHz HE SU PPDU with received power above the CCA
2088 // sensitivity threshold occupies P40 The per20Bitmap should indicate idle for all
2089 // subchannels because received power is below -62 dBm (27.3.20.6.5).
2090 Simulator::Schedule(delay,
2092 this,
2093 "Reception of a 80 MHz HE PPDU that occupies the 40 MHz band above CCA "
2094 "sensitivity threshold");
2095 ScheduleTest(delay,
2096 {},
2097 {{-70.0, MicroSeconds(0), P80_CENTER_FREQUENCY, 80}},
2098 {
2099 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCCATime
2100 {PpduDurations.at(80) - smallDelta,
2101 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2102 {PpduDurations.at(80) + smallDelta,
2103 WifiPhyState::IDLE} // IDLE just after the transmission ends
2104 },
2105 {{aCcaTime,
2106 MicroSeconds(16),
2108 ((m_channelWidth > 20)
2109 ? ((m_channelWidth > 40)
2110 ? ((m_channelWidth > 80) ? std::vector<Time>{Seconds(0),
2111 Seconds(0),
2112 Seconds(0),
2113 Seconds(0),
2114 Seconds(0),
2115 Seconds(0),
2116 Seconds(0),
2117 Seconds(0)}
2118 : std::vector<Time>{Seconds(0),
2119 Seconds(0),
2120 Seconds(0),
2121 Seconds(0)})
2122 : std::vector<Time>{Seconds(0), Seconds(0)})
2123 : std::vector<Time>{})},
2124 {PpduDurations.at(80) - smallDelta,
2125 PpduDurations.at(80),
2127 ((m_channelWidth > 20)
2128 ? ((m_channelWidth > 40)
2129 ? ((m_channelWidth > 80) ? std::vector<Time>{Seconds(0),
2130 Seconds(0),
2131 Seconds(0),
2132 Seconds(0),
2133 Seconds(0),
2134 Seconds(0),
2135 Seconds(0),
2136 Seconds(0)}
2137 : std::vector<Time>{Seconds(0),
2138 Seconds(0),
2139 Seconds(0),
2140 Seconds(0)})
2141 : std::vector<Time>{Seconds(0), Seconds(0)})
2142 : std::vector<Time>{})}});
2143 delay += Seconds(1.0);
2144
2145 //----------------------------------------------------------------------------------------------------------------------------------
2146 // Verify PHY notifies CCA-BUSY when a 80 MHz HE SU PPDU with received power above the CCA
2147 // sensitivity threshold occupies P40 The per20Bitmap should indicate CCA_BUSY for all
2148 // subchannels because received power is above -62 dBm (27.3.20.6.5).
2149 Simulator::Schedule(delay,
2151 this,
2152 "Reception of a 80 MHz HE PPDU that occupies the 40 MHz band above CCA "
2153 "sensitivity threshold");
2155 delay,
2156 {},
2157 {{-55.0, MicroSeconds(0), P80_CENTER_FREQUENCY, 80}},
2158 {
2159 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCCATime
2160 {PpduDurations.at(80) - smallDelta,
2161 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2162 {PpduDurations.at(80) + smallDelta,
2163 WifiPhyState::IDLE} // IDLE just after the transmission ends
2164 },
2165 {{aCcaTime,
2166 MicroSeconds(16),
2168 ((m_channelWidth > 20)
2169 ? ((m_channelWidth > 40)
2170 ? ((m_channelWidth > 80) ? std::vector<Time>{NanoSeconds(271200),
2171 NanoSeconds(271200),
2172 NanoSeconds(271200),
2173 NanoSeconds(271200),
2174 NanoSeconds(0),
2175 NanoSeconds(0),
2176 NanoSeconds(0),
2177 NanoSeconds(0)}
2178 : std::vector<Time>{NanoSeconds(271200),
2179 NanoSeconds(271200),
2180 NanoSeconds(271200),
2181 NanoSeconds(271200)})
2182 : std::vector<Time>{NanoSeconds(271200), NanoSeconds(271200)})
2183 : std::vector<Time>{})},
2184 {PpduDurations.at(80) - smallDelta,
2185 PpduDurations.at(80),
2187 ((m_channelWidth > 20)
2188 ? ((m_channelWidth > 40)
2189 ? ((m_channelWidth > 80) ? std::vector<Time>{NanoSeconds(243200),
2190 NanoSeconds(243200),
2191 NanoSeconds(243200),
2192 NanoSeconds(243200),
2193 NanoSeconds(0),
2194 NanoSeconds(0),
2195 NanoSeconds(0),
2196 NanoSeconds(0)}
2197 : std::vector<Time>{NanoSeconds(243200),
2198 NanoSeconds(243200),
2199 NanoSeconds(243200),
2200 NanoSeconds(243200)})
2201 : std::vector<Time>{NanoSeconds(243200), NanoSeconds(243200)})
2202 : std::vector<Time>{})}});
2203 delay += Seconds(1.0);
2204
2205 //----------------------------------------------------------------------------------------------------------------------------------
2206 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal not
2207 // occupying the operational channel is being received
2209 delay,
2211 this,
2212 "Reception of a 40 MHz HE PPDU that does not occupy the operational channel");
2213 ScheduleTest(delay,
2214 {},
2215 {{-50.0, MicroSeconds(0), S40_CENTER_FREQUENCY, 40}},
2216 {
2217 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2218 {PpduDurations.at(20) - smallDelta,
2219 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2220 {PpduDurations.at(20) + smallDelta,
2221 WifiPhyState::IDLE} // IDLE just after the transmission ends
2222 },
2223 {});
2224 delay += Seconds(1.0);
2225 }
2226
2227 if (m_channelWidth > 80)
2228 {
2229 //----------------------------------------------------------------------------------------------------------------------------------
2230 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2231 // energy detection threshold occupies the first 20 MHz subchannel of the S80
2232 Simulator::Schedule(delay,
2234 this,
2235 "Reception of a 20 MHz signal that occupies the first subchannel of "
2236 "S80 below ED threshold");
2237 ScheduleTest(delay,
2238 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 30, 20}},
2239 {},
2240 {
2241 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2242 {MicroSeconds(100) - smallDelta,
2243 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2244 {MicroSeconds(100) + smallDelta,
2245 WifiPhyState::IDLE} // IDLE just after the transmission ends
2246 },
2247 {});
2248 delay += Seconds(1.0);
2249
2250 //----------------------------------------------------------------------------------------------------------------------------------
2251 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2252 // energy detection threshold occupies the first 20 MHz subchannel of the S80 27.3.20.6.4:
2253 // Any signal within the secondary 80 MHz channel at or above –56 dBm.
2254 Simulator::Schedule(delay,
2256 this,
2257 "Reception of a 20 MHz signal that occupies the first subchannel of "
2258 "S80 above ED threshold");
2259 ScheduleTest(delay,
2260 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 30, 20}},
2261 {},
2262 {
2263 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2264 {MicroSeconds(100) - smallDelta,
2265 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2266 {MicroSeconds(100) + smallDelta,
2267 WifiPhyState::IDLE} // IDLE just after the transmission ends
2268 },
2269 {{MicroSeconds(100) - smallDelta,
2270 MicroSeconds(100),
2272 std::vector<Time>{MicroSeconds(0),
2273 MicroSeconds(0),
2274 MicroSeconds(0),
2275 MicroSeconds(0),
2276 MicroSeconds(100),
2277 MicroSeconds(0),
2278 MicroSeconds(0),
2279 MicroSeconds(0)}}});
2280 delay += Seconds(1.0);
2281
2282 //----------------------------------------------------------------------------------------------------------------------------------
2283 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2284 // energy detection threshold occupies the second 20 MHz subchannel of the S80
2285 Simulator::Schedule(delay,
2287 this,
2288 "Reception of a 20 MHz signal that occupies the second subchannel of "
2289 "S80 below ED threshold");
2290 ScheduleTest(delay,
2291 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 10, 20}},
2292 {},
2293 {
2294 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2295 {MicroSeconds(100) - smallDelta,
2296 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2297 {MicroSeconds(100) + smallDelta,
2298 WifiPhyState::IDLE} // IDLE just after the transmission ends
2299 },
2300 {});
2301 delay += Seconds(1.0);
2302
2303 //----------------------------------------------------------------------------------------------------------------------------------
2304 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2305 // energy detection threshold occupies the second 20 MHz subchannel of the S80 27.3.20.6.4:
2306 // Any signal within the secondary 80 MHz channel at or above –56 dBm.
2307 Simulator::Schedule(delay,
2309 this,
2310 "Reception of a 20 MHz signal that occupies the second subchannel of "
2311 "S80 above ED threshold");
2312 ScheduleTest(delay,
2313 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 10, 20}},
2314 {},
2315 {
2316 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2317 {MicroSeconds(100) - smallDelta,
2318 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2319 {MicroSeconds(100) + smallDelta,
2320 WifiPhyState::IDLE} // IDLE just after the transmission ends
2321 },
2322 {{MicroSeconds(100) - smallDelta,
2323 MicroSeconds(100),
2325 std::vector<Time>{MicroSeconds(0),
2326 MicroSeconds(0),
2327 MicroSeconds(0),
2328 MicroSeconds(0),
2329 MicroSeconds(0),
2330 MicroSeconds(100),
2331 MicroSeconds(0),
2332 MicroSeconds(0)}}});
2333 delay += Seconds(1.0);
2334
2335 //----------------------------------------------------------------------------------------------------------------------------------
2336 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2337 // energy detection threshold occupies the third 20 MHz subchannel of the S80
2338 Simulator::Schedule(delay,
2340 this,
2341 "Reception of a 20 MHz signal that occupies the third subchannel of "
2342 "S80 below ED threshold");
2343 ScheduleTest(delay,
2344 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 10, 20}},
2345 {},
2346 {
2347 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2348 {MicroSeconds(100) - smallDelta,
2349 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2350 {MicroSeconds(100) + smallDelta,
2351 WifiPhyState::IDLE} // IDLE just after the transmission ends
2352 },
2353 {});
2354 delay += Seconds(1.0);
2355
2356 //----------------------------------------------------------------------------------------------------------------------------------
2357 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2358 // energy detection threshold occupies the third 20 MHz subchannel of the S80 27.3.20.6.4:
2359 // Any signal within the secondary 80 MHz channel at or above –56 dBm.
2360 Simulator::Schedule(delay,
2362 this,
2363 "Reception of a 20 MHz signal that occupies the third subchannel of "
2364 "S80 above ED threshold");
2365 ScheduleTest(delay,
2366 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 10, 20}},
2367 {},
2368 {
2369 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2370 {MicroSeconds(100) - smallDelta,
2371 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2372 {MicroSeconds(100) + smallDelta,
2373 WifiPhyState::IDLE} // IDLE just after the transmission ends
2374 },
2375 {{MicroSeconds(100) - smallDelta,
2376 MicroSeconds(100),
2378 std::vector<Time>{MicroSeconds(0),
2379 MicroSeconds(0),
2380 MicroSeconds(0),
2381 MicroSeconds(0),
2382 MicroSeconds(0),
2383 MicroSeconds(0),
2384 MicroSeconds(100),
2385 MicroSeconds(0)}}});
2386 delay += Seconds(1.0);
2387
2388 //----------------------------------------------------------------------------------------------------------------------------------
2389 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2390 // energy detection threshold occupies the fourth 20 MHz subchannel of the S80
2391 Simulator::Schedule(delay,
2393 this,
2394 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
2395 "S80 below ED threshold");
2396 ScheduleTest(delay,
2397 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 30, 20}},
2398 {},
2399 {
2400 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2401 {MicroSeconds(100) - smallDelta,
2402 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2403 {MicroSeconds(100) + smallDelta,
2404 WifiPhyState::IDLE} // IDLE just after the transmission ends
2405 },
2406 {});
2407 delay += Seconds(1.0);
2408
2409 //----------------------------------------------------------------------------------------------------------------------------------
2410 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2411 // energy detection threshold occupies the fourth 20 MHz subchannel of the S80 27.3.20.6.4:
2412 // Any signal within the secondary 80 MHz channel at or above –56 dBm.
2413 Simulator::Schedule(delay,
2415 this,
2416 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
2417 "S80 above ED threshold");
2418 ScheduleTest(delay,
2419 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 30, 20}},
2420 {},
2421 {
2422 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2423 {MicroSeconds(100) - smallDelta,
2424 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2425 {MicroSeconds(100) + smallDelta,
2426 WifiPhyState::IDLE} // IDLE just after the transmission ends
2427 },
2428 {{MicroSeconds(100) - smallDelta,
2429 MicroSeconds(100),
2431 std::vector<Time>{MicroSeconds(0),
2432 MicroSeconds(0),
2433 MicroSeconds(0),
2434 MicroSeconds(0),
2435 MicroSeconds(0),
2436 MicroSeconds(0),
2437 MicroSeconds(0),
2438 MicroSeconds(100)}}});
2439 delay += Seconds(1.0);
2440
2441 //----------------------------------------------------------------------------------------------------------------------------------
2442 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2443 // energy detection threshold occupies the first and second 20 MHz subchannels of the S80
2444 Simulator::Schedule(delay,
2446 this,
2447 "Reception of a 40 MHz signal that occupies the first and second "
2448 "subchannels of S80 below ED threshold");
2449 ScheduleTest(delay,
2450 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 20, 40}},
2451 {},
2452 {
2453 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2454 {MicroSeconds(100) - smallDelta,
2455 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2456 {MicroSeconds(100) + smallDelta,
2457 WifiPhyState::IDLE} // IDLE just after the transmission ends
2458 },
2459 {});
2460 delay += Seconds(1.0);
2461
2462 //----------------------------------------------------------------------------------------------------------------------------------
2463 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2464 // energy detection threshold occupies the first and second 20 MHz subchannels of the S80
2465 // 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2466 Simulator::Schedule(delay,
2468 this,
2469 "Reception of a 40 MHz signal that occupies the first and second "
2470 "subchannels of S80 above ED threshold");
2471 ScheduleTest(delay,
2472 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 20, 40}},
2473 {},
2474 {
2475 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2476 {MicroSeconds(100) - smallDelta,
2477 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2478 {MicroSeconds(100) + smallDelta,
2479 WifiPhyState::IDLE} // IDLE just after the transmission ends
2480 },
2481 {{MicroSeconds(100) - smallDelta,
2482 MicroSeconds(100),
2484 std::vector<Time>{MicroSeconds(0),
2485 MicroSeconds(0),
2486 MicroSeconds(0),
2487 MicroSeconds(0),
2488 MicroSeconds(100),
2489 MicroSeconds(100),
2490 MicroSeconds(0),
2491 MicroSeconds(0)}}});
2492 delay += Seconds(1.0);
2493
2494 //----------------------------------------------------------------------------------------------------------------------------------
2495 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2496 // energy detection threshold occupies the third and fourth 20 MHz subchannels of the S80
2497 Simulator::Schedule(delay,
2499 this,
2500 "Reception of a 40 MHz signal that occupies the third and fourth "
2501 "subchannels of S80 below ED threshold");
2502 ScheduleTest(delay,
2503 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 20, 40}},
2504 {},
2505 {
2506 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2507 {MicroSeconds(100) - smallDelta,
2508 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2509 {MicroSeconds(100) + smallDelta,
2510 WifiPhyState::IDLE} // IDLE just after the transmission ends
2511 },
2512 {});
2513 delay += Seconds(1.0);
2514
2515 //----------------------------------------------------------------------------------------------------------------------------------
2516 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2517 // energy detection threshold occupies the third and fourth 20 MHz subchannels of the S80
2518 // 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2519 Simulator::Schedule(delay,
2521 this,
2522 "Reception of a 40 MHz signal that occupies the third and fourth "
2523 "subchannels of S80 above ED threshold");
2524 ScheduleTest(delay,
2525 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 20, 40}},
2526 {},
2527 {
2528 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2529 {MicroSeconds(100) - smallDelta,
2530 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2531 {MicroSeconds(100) + smallDelta,
2532 WifiPhyState::IDLE} // IDLE just after the transmission ends
2533 },
2534 {{MicroSeconds(100) - smallDelta,
2535 MicroSeconds(100),
2537 std::vector<Time>{MicroSeconds(0),
2538 MicroSeconds(0),
2539 MicroSeconds(0),
2540 MicroSeconds(0),
2541 MicroSeconds(0),
2542 MicroSeconds(0),
2543 MicroSeconds(100),
2544 MicroSeconds(100)}}});
2545 delay += Seconds(1.0);
2546
2547 //----------------------------------------------------------------------------------------------------------------------------------
2548 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2549 // energy detection threshold occupies the S80
2550 Simulator::Schedule(delay,
2552 this,
2553 "Reception of a 80 MHz signal that occupies S80 below ED threshold");
2554 ScheduleTest(delay,
2555 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY, 80}},
2556 {},
2557 {
2558 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2559 {MicroSeconds(100) - smallDelta,
2560 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2561 {MicroSeconds(100) + smallDelta,
2562 WifiPhyState::IDLE} // IDLE just after the transmission ends
2563 },
2564 {});
2565 delay += Seconds(1.0);
2566
2567 //----------------------------------------------------------------------------------------------------------------------------------
2568 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2569 // energy detection threshold occupies the S80 27.3.20.6.4: Any signal within the secondary
2570 // 80 MHz channel at or above –56 dBm.
2571 Simulator::Schedule(delay,
2573 this,
2574 "Reception of a 80 MHz signal that occupies S80 above ED threshold");
2575 ScheduleTest(delay,
2576 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY, 80}},
2577 {},
2578 {
2579 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2580 {MicroSeconds(100) - smallDelta,
2581 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2582 {MicroSeconds(100) + smallDelta,
2583 WifiPhyState::IDLE} // IDLE just after the transmission ends
2584 },
2585 {{MicroSeconds(100) - smallDelta,
2586 MicroSeconds(100),
2588 std::vector<Time>{MicroSeconds(0),
2589 MicroSeconds(0),
2590 MicroSeconds(0),
2591 MicroSeconds(0),
2592 MicroSeconds(100),
2593 MicroSeconds(100),
2594 MicroSeconds(100),
2595 MicroSeconds(100)}}});
2596 delay += Seconds(1.0);
2597
2598 //----------------------------------------------------------------------------------------------------------------------------------
2599 // Verify PHY state stays IDLE as long as a 160 MHz signal below the energy detection
2600 // threshold occupies the whole band
2602 delay,
2604 this,
2605 "Reception of a 160 MHz signal that occupies the whole band below ED threshold");
2606 ScheduleTest(delay,
2607 {{-55.0, MicroSeconds(0), MicroSeconds(100), P160_CENTER_FREQUENCY, 160}},
2608 {},
2609 {
2610 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2611 {MicroSeconds(100) - smallDelta,
2612 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2613 {MicroSeconds(100) + smallDelta,
2614 WifiPhyState::IDLE} // IDLE just after the transmission ends
2615 },
2616 {});
2617
2618 delay += Seconds(1.0);
2619
2620 //----------------------------------------------------------------------------------------------------------------------------------
2621 // Verify PHY state is CCA-BUSY as long as a 160 MHz signal above the energy detection
2622 // threshold occupies the whole band
2624 delay,
2626 this,
2627 "Reception of a 160 MHz signal that occupies the whole band above ED threshold");
2628 ScheduleTest(delay,
2629 {{-50.0, MicroSeconds(0), MicroSeconds(100), P160_CENTER_FREQUENCY, 160}},
2630 {},
2631 {
2632 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
2633 {MicroSeconds(100) - smallDelta,
2634 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2635 {MicroSeconds(100) + smallDelta,
2636 WifiPhyState::IDLE} // IDLE just after the transmission ends
2637 },
2638 {{MicroSeconds(100) - smallDelta,
2639 MicroSeconds(100),
2641 std::vector<Time>{MicroSeconds(100),
2642 MicroSeconds(100),
2643 MicroSeconds(100),
2644 MicroSeconds(100),
2645 MicroSeconds(100),
2646 MicroSeconds(100),
2647 MicroSeconds(100),
2648 MicroSeconds(100)}}});
2649 delay += Seconds(1.0);
2650
2651 //----------------------------------------------------------------------------------------------------------------------------------
2652 // Verify PHY notifies CCA-BUSY for the P20 channel while the S80 channel was already in
2653 // CCA-BUSY state
2654 Simulator::Schedule(delay,
2656 this,
2657 "Reception of a 20 MHz signal that occupies S80 followed by the "
2658 "reception of another 20 MHz signal that occupies P20");
2660 delay,
2661 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 10, 20},
2662 {-55.0, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
2663 {},
2664 {
2665 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
2666 {MicroSeconds(50) + aCcaTime,
2667 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after aCCATime that
2668 // followed the second transmission
2669 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2670 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2671 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2672 WifiPhyState::IDLE} // IDLE just after the transmission ends
2673 },
2674 {{aCcaTime, // notification upon reception of the first signal
2675 MicroSeconds(100),
2677 std::vector<Time>{MicroSeconds(0),
2678 MicroSeconds(0),
2679 MicroSeconds(0),
2680 MicroSeconds(0),
2681 MicroSeconds(0),
2682 MicroSeconds(0),
2683 MicroSeconds(100),
2684 MicroSeconds(0)}},
2685 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
2686 MicroSeconds(50) + MicroSeconds(100),
2688 std::vector<Time>{MicroSeconds(100),
2689 MicroSeconds(0),
2690 MicroSeconds(00),
2691 MicroSeconds(0),
2692 MicroSeconds(0),
2693 MicroSeconds(0),
2694 MicroSeconds(50),
2695 MicroSeconds(0)}}});
2696 delay += Seconds(1.0);
2697
2698 //----------------------------------------------------------------------------------------------------------------------------------
2699 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S40 channel while the S80
2700 // channel was already in CCA-BUSY state
2701 Simulator::Schedule(delay,
2703 this,
2704 "Reception of a signal that occupies S80 followed by the reception of "
2705 "another signal that occupies S40");
2707 delay,
2708 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 30, 20},
2709 {-55.0, MicroSeconds(50), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20}},
2710 {},
2711 {
2712 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
2713 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // state of primary stays IDLE
2714 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2715 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2716 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2717 WifiPhyState::IDLE} // IDLE just after the transmission ends
2718 },
2719 {{aCcaTime, // notification upon reception of the first signal
2720 MicroSeconds(100),
2722 std::vector<Time>{MicroSeconds(0),
2723 MicroSeconds(0),
2724 MicroSeconds(0),
2725 MicroSeconds(0),
2726 MicroSeconds(0),
2727 MicroSeconds(0),
2728 MicroSeconds(0),
2729 MicroSeconds(100)}},
2730 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
2731 MicroSeconds(50) + MicroSeconds(100),
2733 std::vector<Time>{MicroSeconds(0),
2734 MicroSeconds(0),
2735 MicroSeconds(100),
2736 MicroSeconds(0),
2737 MicroSeconds(0),
2738 MicroSeconds(0),
2739 MicroSeconds(0),
2740 MicroSeconds(50)}}});
2741 delay += Seconds(1.0);
2742
2743 //----------------------------------------------------------------------------------------------------------------------------------
2744 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S80
2745 // channel was already in CCA-BUSY state
2746 Simulator::Schedule(delay,
2748 this,
2749 "Reception of a signal that occupies S80 followed by the reception of "
2750 "another signal that occupies S20");
2752 delay,
2753 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 30, 20},
2754 {-55.0, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
2755 {},
2756 {
2757 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
2758 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // state of primary stays IDLE
2759 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2760 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2761 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2762 WifiPhyState::IDLE} // IDLE just after the transmission ends
2763 },
2764 {{aCcaTime, // notification upon reception of the first signal
2765 MicroSeconds(100),
2767 std::vector<Time>{MicroSeconds(0),
2768 MicroSeconds(0),
2769 MicroSeconds(0),
2770 MicroSeconds(0),
2771 MicroSeconds(100),
2772 MicroSeconds(0),
2773 MicroSeconds(0),
2774 MicroSeconds(0)}},
2775 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
2776 MicroSeconds(50) + MicroSeconds(100),
2778 std::vector<Time>{MicroSeconds(0),
2779 MicroSeconds(100),
2780 MicroSeconds(0),
2781 MicroSeconds(0),
2782 MicroSeconds(50),
2783 MicroSeconds(0),
2784 MicroSeconds(0),
2785 MicroSeconds(0)}}});
2786 delay += Seconds(1.0);
2787
2788 //----------------------------------------------------------------------------------------------------------------------------------
2789 // Verify PHY state stays IDLE when a 80 MHz HE SU PPDU with received power below the CCA
2790 // sensitivity threshold occupies S80
2792 delay,
2794 this,
2795 "Reception of a 40 MHz HE PPDU that occupies S40 below CCA sensitivity threshold");
2796 ScheduleTest(delay,
2797 {},
2798 {{-70.0, MicroSeconds(0), S80_CENTER_FREQUENCY, 80}},
2799 {
2800 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2801 {PpduDurations.at(20) - smallDelta,
2802 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2803 {PpduDurations.at(20) + smallDelta,
2804 WifiPhyState::IDLE} // IDLE just after the transmission ends
2805 },
2806 {});
2807 delay += Seconds(1.0);
2808
2809 //----------------------------------------------------------------------------------------------------------------------------------
2810 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 80 MHz HE SU PPDU
2811 // with received power above the CCA sensitivity threshold occupies S80
2813 delay,
2815 this,
2816 "Reception of a 80 MHz HE PPDU that occupies S80 above CCA sensitivity threshold");
2817 ScheduleTest(delay,
2818 {},
2819 {{-65.0, MicroSeconds(0), S80_CENTER_FREQUENCY, 80}},
2820 {
2821 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2822 {PpduDurations.at(80) - smallDelta,
2823 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2824 {PpduDurations.at(80) + smallDelta,
2825 WifiPhyState::IDLE} // IDLE just after the transmission ends
2826 },
2827 {{aCcaTime,
2828 PpduDurations.at(80),
2830 std::vector<Time>{NanoSeconds(0),
2831 NanoSeconds(0),
2832 NanoSeconds(0),
2833 NanoSeconds(0),
2834 PpduDurations.at(80),
2835 PpduDurations.at(80),
2836 PpduDurations.at(80),
2837 PpduDurations.at(80)}}});
2838 delay += Seconds(1.0);
2839
2840 //----------------------------------------------------------------------------------------------------------------------------------
2841 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if only the per20bitmap
2842 // parameter changes
2843 Simulator::Schedule(delay,
2845 this,
2846 "Reception of a 20 MHz signal that generates a per20bitmap parameter "
2847 "change when previous CCA indication reports IDLE");
2848 ScheduleTest(delay,
2849 {{-60.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 30, 20}},
2850 {},
2851 {
2852 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2853 {MicroSeconds(100) - smallDelta,
2854 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2855 {MicroSeconds(100) + smallDelta,
2856 WifiPhyState::IDLE} // IDLE just after the transmission ends
2857 },
2858 {{aCcaTime,
2859 Seconds(0),
2861 std::vector<Time>{MicroSeconds(0),
2862 MicroSeconds(0),
2863 MicroSeconds(0),
2864 MicroSeconds(0),
2865 MicroSeconds(0),
2866 MicroSeconds(0),
2867 MicroSeconds(0),
2868 MicroSeconds(100)}}});
2869 delay += Seconds(1.0);
2870
2871 //----------------------------------------------------------------------------------------------------------------------------------
2872 // Verify PHY state stays CCA_BUSY and CCA-BUSY indication is reported if only the
2873 // per20bitmap parameter changes
2875 delay,
2877 this,
2878 "Reception of a 20 MHz signal that generates a per20bitmap parameter change when "
2879 "previous CCA indication reports BUSY for the primary channel");
2881 delay,
2882 {{-50.0, MicroSeconds(0), MicroSeconds(100), P80_CENTER_FREQUENCY, 80},
2883 {-60.0, MicroSeconds(50), MicroSeconds(200), S80_CENTER_FREQUENCY + 30, 20}},
2884 {},
2885 {
2886 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
2887 {MicroSeconds(100) - smallDelta,
2888 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2889 {MicroSeconds(100) + smallDelta,
2890 WifiPhyState::IDLE} // IDLE just after the transmission ends
2891 },
2892 {{aCcaTime,
2893 MicroSeconds(100),
2895 std::vector<Time>{MicroSeconds(100),
2896 MicroSeconds(100),
2897 MicroSeconds(100),
2898 MicroSeconds(100),
2899 MicroSeconds(0),
2900 MicroSeconds(0),
2901 MicroSeconds(0),
2902 MicroSeconds(0)}},
2903 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
2904 MicroSeconds(100),
2906 std::vector<Time>{MicroSeconds(50),
2907 MicroSeconds(50),
2908 MicroSeconds(50),
2909 MicroSeconds(50),
2910 MicroSeconds(0),
2911 MicroSeconds(0),
2912 MicroSeconds(0),
2913 MicroSeconds(200)}}});
2914 delay += Seconds(1.0);
2915 }
2916
2918}
2919
2920void
2922{
2923 m_frequency = 5180;
2924 m_channelWidth = 20;
2925 RunOne();
2926
2927 m_frequency = 5190;
2928 m_channelWidth = 40;
2929 RunOne();
2930
2931 m_frequency = 5210;
2932 m_channelWidth = 80;
2933 RunOne();
2934
2935 m_frequency = 5250;
2936 m_channelWidth = 160;
2937 RunOne();
2938
2940}
2941
2942void
2944{
2945 m_rxPhy->Dispose();
2946 m_rxPhy = nullptr;
2947 m_txPhy->Dispose();
2948 m_txPhy = nullptr;
2949 for (auto& signalGenerator : m_signalGenerators)
2950 {
2951 signalGenerator->Dispose();
2952 signalGenerator = nullptr;
2953 }
2954}
2955
2956/**
2957 * \ingroup wifi-test
2958 * \ingroup tests
2959 *
2960 * \brief Wi-Fi PHY CCA Test Suite
2961 */
2963{
2964 public:
2966};
2967
2969 : TestSuite("wifi-phy-cca", Type::UNIT)
2970{
2971 AddTestCase(new WifiPhyCcaThresholdsTest, TestCase::Duration::QUICK);
2972 AddTestCase(new WifiPhyCcaIndicationTest, TestCase::Duration::QUICK);
2973}
2974
2975static WifiPhyCcaTestSuite WifiPhyCcaTestSuite; ///< the test suite
PHY listener for CCA tests.
void NotifyOn() override
Notify listeners that we went to switch on.
WifiChannelListType m_lastCcaBusyChannelType
Channel type indication for the last CCA-BUSY notification.
void NotifyRxEndError() override
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
void NotifyTxStart(Time duration, dBm_u txPower) override
void NotifyCcaBusyStart(Time duration, WifiChannelListType channelType, const std::vector< Time > &per20MhzDurations) override
void NotifySleep() override
Notify listeners that we went to sleep.
void NotifyRxEndOk() override
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
CcaTestPhyListener()=default
void NotifyOff() override
Notify listeners that we went to switch off.
std::size_t m_notifications
Number of CCA notifications.
void NotifyRxStart(Time duration) override
Time m_endCcaBusy
End of the CCA-BUSY duration.
void Reset()
Reset function.
void NotifyWakeup() override
Notify listeners that we woke up.
std::vector< Time > m_lastPer20MhzCcaBusyDurations
End of the CCA-BUSY durations per 20 MHz.
void NotifySwitchingStart(Time duration) override
Wifi Phy Threshold Test base class.
MHz_u m_channelWidth
Operating channel width.
std::size_t m_numSignalGenerators
The number of non-wifi signals generators needed for the test.
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void CheckLastCcaBusyNotification(Time expectedEndTime, WifiChannelListType expectedChannelType, const std::vector< Time > &expectedPer20MhzDurations)
Check the last CCA-BUSY notification.
MHz_u m_frequency
Operating frequency.
void StartSignal(Ptr< WaveformGenerator > signalGenerator, dBm_u txPower, MHz_u frequency, MHz_u bandwidth, Time duration)
Start to generate a signal.
void RunOne()
Run one function.
void SendHeSuPpdu(dBm_u txPower, MHz_u frequency, MHz_u bandwidth)
Send an HE SU PPDU.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state.
std::shared_ptr< CcaTestPhyListener > m_rxPhyStateListener
Listener for PHY state transitions.
std::vector< Ptr< WaveformGenerator > > m_signalGenerators
Generators of non-wifi signals.
void ScheduleTest(Time delay, const std::vector< TxSignalInfo > &generatedSignals, const std::vector< TxPpduInfo > &generatedPpdus, const std::vector< StateCheckPoint > &stateCheckpoints, const std::vector< CcaCheckPoint > &ccaCheckpoints)
Schedule test to perform.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
void LogScenario(const std::string &log) const
Log scenario description.
void Reset()
Reset function.
Ptr< SpectrumWifiPhy > m_rxPhy
PHY object of the receiver.
Ptr< SpectrumWifiPhy > m_txPhy
PHY object of the transmitter.
void StopSignal(Ptr< WaveformGenerator > signalGenerator)
Stop to generate a signal.
Wi-Fi PHY CCA Test Suite.
PHY CCA thresholds test.
void VerifyCcaThreshold(const Ptr< PhyEntity > phy, const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType, dBm_u expectedCcaThreshold)
Function to verify the CCA threshold that is being reported by a given PHY entity upon reception of a...
Ptr< WifiNetDevice > m_device
The WifiNetDevice.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Ptr< SpectrumWifiPhy > m_phy
The spectrum PHY.
Ptr< ObssPdAlgorithm > m_obssPdAlgorithm
The OBSS-PD algorithm.
dBm_u m_obssPdLevel
The current OBSS-PD level.
Ptr< WifiPsdu > CreateDummyPsdu()
Create a dummy PSDU whose payload is 1000 bytes.
VhtConfiguration::SecondaryCcaSensitivityThresholds m_secondaryCcaSensitivityThresholds
The current CCA sensitivity thresholds for signals that do not occupy the primary 20 MHz channel.
void RunOne()
Run tests for given CCA attributes.
Ptr< VhtConfiguration > m_vhtConfiguration
The VHT configuration.
void DoRun() override
Implementation to actually run this TestCase.
Ptr< VhtPpdu > CreateDummyVhtPpdu(MHz_u bandwidth, const WifiPhyOperatingChannel &channel)
Create a VHT PPDU.
Ptr< HtPpdu > CreateDummyHtPpdu(MHz_u bandwidth, const WifiPhyOperatingChannel &channel)
Create a HT PPDU.
Ptr< OfdmPpdu > CreateDummyNonHtPpdu(const WifiPhyOperatingChannel &channel)
Create a non-HT PPDU.
dBm_u m_CcaEdThreshold
The current CCA-ED threshold for a 20 MHz subchannel.
dBm_u m_CcaSensitivity
The current CCA sensitivity threshold for signals that occupy the primary 20 MHz channel.
Ptr< HePpdu > CreateDummyHePpdu(MHz_u bandwidth, const WifiPhyOperatingChannel &channel)
Create a HE PPDU.
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
static WifiMode GetHtMcs0()
Return MCS 0 from HT MCS values.
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6 Mbps.
AttributeValue implementation for Pointer.
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
std::tuple< dBm_u, dBm_u, dBm_u > SecondaryCcaSensitivityThresholds
Tuple identifying CCA sensitivity thresholds for secondary channels.
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
Implements the IEEE 802.11 MAC header.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:919
receive notifications about PHY events.
Class that keeps track of all information about the current PHY operating channel.
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first frequency segment matching the specified parameters.
This objects implements the PHY state machine of the Wifi device.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#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:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition test.h:500
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 Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
@ WIFI_STANDARD_80211ax
@ WIFI_PREAMBLE_LONG
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PREAMBLE_VHT_SU
@ WIFI_PREAMBLE_HT_MF
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_CHANLIST_PRIMARY
@ WIFI_CHANLIST_SECONDARY40
@ WIFI_CHANLIST_SECONDARY
@ WIFI_CHANLIST_SECONDARY80
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyState
The state of the PHY layer.
std::vector< BandInfo > Bands
Container of BandInfo.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
@ WIFI_MAC_QOSDATA
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:31
structure that holds information to perform CCA check
Time expectedCcaEndTime
expected CCA_BUSY end time
Time timePoint
time at which the check will performed
std::vector< Time > expectedPer20MhzDurations
expected per-20 MHz CCA duration
WifiChannelListType expectedChannelListType
expected channel list type
structure that holds information to perform PHY state check
WifiPhyState expectedPhyState
expected PHY state
Time timePoint
time at which the check will performed
structure that holds information to generate PPDUs
Time startTime
time at which transmission will be started
MHz_u centerFreq
center frequency to use
structure that holds information to generate signals
MHz_u centerFreq
center frequency to use
Time startTime
time at which transmission will be started
Time duration
the duration of the transmission
The building block of a SpectrumModel.
double fc
center frequency
double fl
lower limit of subband
double fh
upper limit of subband
const Time aCcaTime
constexpr MHz_u S80_CENTER_FREQUENCY
static WifiPhyCcaTestSuite WifiPhyCcaTestSuite
the test suite
constexpr MHz_u S20_CENTER_FREQUENCY
constexpr MHz_u P20_CENTER_FREQUENCY
constexpr MHz_u S40_CENTER_FREQUENCY
const Time smallDelta
constexpr MHz_u P160_CENTER_FREQUENCY
constexpr MHz_u P80_CENTER_FREQUENCY
constexpr MHz_u P40_CENTER_FREQUENCY
const std::map< MHz_u, Time > PpduDurations