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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
18 */
19
20#include "ns3/constant-obss-pd-algorithm.h"
21#include "ns3/he-phy.h"
22#include "ns3/he-ppdu.h"
23#include "ns3/ht-ppdu.h"
24#include "ns3/interference-helper.h"
25#include "ns3/log.h"
26#include "ns3/multi-model-spectrum-channel.h"
27#include "ns3/nist-error-rate-model.h"
28#include "ns3/non-communicating-net-device.h"
29#include "ns3/ofdm-ppdu.h"
30#include "ns3/pointer.h"
31#include "ns3/rng-seed-manager.h"
32#include "ns3/spectrum-wifi-helper.h"
33#include "ns3/spectrum-wifi-phy.h"
34#include "ns3/test.h"
35#include "ns3/threshold-preamble-detection-model.h"
36#include "ns3/vht-configuration.h"
37#include "ns3/vht-ppdu.h"
38#include "ns3/waveform-generator.h"
39#include "ns3/wifi-mac-header.h"
40#include "ns3/wifi-net-device.h"
41#include "ns3/wifi-phy-listener.h"
42#include "ns3/wifi-psdu.h"
43#include "ns3/wifi-spectrum-value-helper.h"
44#include "ns3/wifi-utils.h"
45
46#include <memory>
47#include <vector>
48
49using namespace ns3;
50
51NS_LOG_COMPONENT_DEFINE("WifiPhyCcaTest");
52
53constexpr uint32_t P20_CENTER_FREQUENCY = 5180; // MHz
61// add small delta to be right after aCCATime, since test checks are scheduled before wifi events
63const std::map<uint16_t, Time> PpduDurations = {
64 {20, NanoSeconds(1009600)},
65 {40, NanoSeconds(533600)},
66 {80, NanoSeconds(275200)},
67};
68
69/**
70 * \ingroup wifi-test
71 * \ingroup tests
72 *
73 * \brief PHY CCA thresholds test
74 */
76{
77 public:
79
80 private:
81 void DoSetup() override;
82 void DoTeardown() override;
83 void DoRun() override;
84
85 /**
86 * Run tests for given CCA attributes
87 */
88 void RunOne();
89
90 /**
91 * Create a dummy PSDU whose payload is 1000 bytes
92 * \return a dummy PSDU whose payload is 1000 bytes
93 */
95 /**
96 * Create a non-HT PPDU
97 * \param channel the operating channel of the PHY used for the transmission
98 * \return a non-HT PPDU
99 */
101 /**
102 * Create a HT PPDU
103 * \param bandwidth the bandwidth used for the transmission the PPDU in MHz
104 * \param channel the operating channel of the PHY used for the transmission
105 * \return a HT PPDU
106 */
107 Ptr<HtPpdu> CreateDummyHtPpdu(uint16_t bandwidth, const WifiPhyOperatingChannel& channel);
108 /**
109 * Create a VHT PPDU
110 * \param bandwidth the bandwidth used for the transmission the PPDU in MHz
111 * \param channel the operating channel of the PHY used for the transmission
112 * \return a VHT PPDU
113 */
114 Ptr<VhtPpdu> CreateDummyVhtPpdu(uint16_t bandwidth, const WifiPhyOperatingChannel& channel);
115 /**
116 * Create a HE PPDU
117 * \param bandwidth the bandwidth used for the transmission the PPDU in MHz
118 * \param channel the operating channel of the PHY used for the transmission
119 * \return a HE PPDU
120 */
121 Ptr<HePpdu> CreateDummyHePpdu(uint16_t bandwidth, const WifiPhyOperatingChannel& channel);
122
123 /**
124 * Function to verify the CCA threshold that is being reported by a given PHY entity upon
125 * reception of a signal or a PPDU
126 * \param phy the PHY entity to verify
127 * \param ppdu the incoming PPDU or signal (if nullptr)
128 * \param channelType the channel list type that indicates which channel the PPDU or the
129 * signal occupies
130 * \param expectedCcaThresholdDbm the CCA threshold in dBm that is expected to be reported
131 */
132 void VerifyCcaThreshold(const Ptr<PhyEntity> phy,
133 const Ptr<const WifiPpdu> ppdu,
134 WifiChannelListType channelType,
135 double expectedCcaThresholdDbm);
136
137 Ptr<WifiNetDevice> m_device; ///< The WifiNetDevice
138 Ptr<SpectrumWifiPhy> m_phy; ///< The spectrum PHY
139 Ptr<ObssPdAlgorithm> m_obssPdAlgorithm; ///< The OBSS-PD algorithm
140 Ptr<VhtConfiguration> m_vhtConfiguration; ///< The VHT configuration
141
142 double m_CcaEdThresholdDbm; ///< The current CCA-ED threshold for a 20 MHz subchannel (in dBm)
143 double m_CcaSensitivityDbm; ///< The current CCA sensitivity threshold for signals that occupy
144 ///< the primary 20 MHz channel (in dBm)
145
147 m_secondaryCcaSensitivityThresholds; ///< The current CCA sensitivity thresholds for signals
148 ///< that do not occupy the primary 20 MHz channel (in
149 ///< dBm)
150
151 double m_obssPdLevel; ///< The current OBSS-PD level (in dBm)
152};
153
155 : TestCase("Wi-Fi PHY CCA thresholds test"),
156 m_CcaEdThresholdDbm{-62.0},
157 m_CcaSensitivityDbm{-82.0},
158 m_secondaryCcaSensitivityThresholds{-72.0, -72.0, -69.0},
159 m_obssPdLevel{-82.0}
160{
161}
162
165{
166 Ptr<Packet> pkt = Create<Packet>(1000);
167 WifiMacHeader hdr;
169 hdr.SetQosTid(0);
170 return Create<WifiPsdu>(pkt, hdr);
171}
172
175{
176 WifiTxVector txVector =
177 WifiTxVector(OfdmPhy::GetOfdmRate6Mbps(), 0, WIFI_PREAMBLE_LONG, 800, 1, 1, 0, 20, false);
179 return Create<OfdmPpdu>(psdu, txVector, channel, 0);
180}
181
184 const WifiPhyOperatingChannel& channel)
185{
186 WifiTxVector txVector =
187 WifiTxVector(HtPhy::GetHtMcs0(), 0, WIFI_PREAMBLE_HT_MF, 800, 1, 1, 0, bandwidth, false);
189 return Create<HtPpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
190}
191
194 const WifiPhyOperatingChannel& channel)
195{
196 WifiTxVector txVector =
197 WifiTxVector(VhtPhy::GetVhtMcs0(), 0, WIFI_PREAMBLE_VHT_SU, 800, 1, 1, 0, bandwidth, false);
199 return Create<VhtPpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
200}
201
204 const WifiPhyOperatingChannel& channel)
205{
206 WifiTxVector txVector =
207 WifiTxVector(HePhy::GetHeMcs0(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, bandwidth, false);
209 return Create<HePpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
210}
211
212void
214 const Ptr<const WifiPpdu> ppdu,
215 WifiChannelListType channelType,
216 double expectedCcaThresholdDbm)
217{
218 NS_LOG_FUNCTION(this << phy << channelType << expectedCcaThresholdDbm);
219 double actualThresholdDbm = phy->GetCcaThreshold(ppdu, channelType);
220 NS_LOG_INFO((ppdu == nullptr ? "any signal" : "a PPDU")
221 << " in " << channelType << " channel: " << actualThresholdDbm << "dBm");
222 NS_TEST_EXPECT_MSG_EQ_TOL(actualThresholdDbm,
223 expectedCcaThresholdDbm,
224 1e-6,
225 "Actual CCA threshold for "
226 << (ppdu == nullptr ? "any signal" : "a PPDU") << " in "
227 << channelType << " channel " << actualThresholdDbm
228 << "dBm does not match expected threshold "
229 << expectedCcaThresholdDbm << "dBm");
230}
231
232void
234{
235 // WifiHelper::EnableLogComponents ();
236 // LogComponentEnable ("WifiPhyCcaTest", LOG_LEVEL_ALL);
237
238 m_device = CreateObject<WifiNetDevice>();
240 m_vhtConfiguration = CreateObject<VhtConfiguration>();
242
243 m_phy = CreateObject<SpectrumWifiPhy>();
246 m_phy->SetInterferenceHelper(CreateObject<InterferenceHelper>());
247 m_phy->AddChannel(CreateObject<MultiModelSpectrumChannel>());
248
249 auto channelNum = std::get<0>(
253
254 m_obssPdAlgorithm = CreateObject<ConstantObssPdAlgorithm>();
257}
258
259void
261{
262 m_device->Dispose();
263 m_device = nullptr;
264}
265
266void
268{
273
274 // OFDM PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
276 nullptr,
279
280 //-----------------------------------------------------------------------------------------------------------------------------------
281
282 // OFDM PHY: 20 MHz non-HT PPDU in primary channel (20 MHz) if power above CCA sensitivity
283 // threshold
288
289 //-----------------------------------------------------------------------------------------------------------------------------------
290
291 // HT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
293 nullptr,
296
297 // HT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
299 nullptr,
302
303 //-----------------------------------------------------------------------------------------------------------------------------------
304
305 // HT PHY: 20 MHz HT PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
306 // threshold
311
312 // HT PHY: 40 MHz HT PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
313 // threshold
318
319 //-----------------------------------------------------------------------------------------------------------------------------------
320
321 // VHT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
323 nullptr,
326
327 // VHT PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
329 nullptr,
332
333 // VHT PHY: any signal in secondary40 channel (40 MHz) if power above CCA-ED threshold + 3dB
335 nullptr,
338
339 // VHT PHY: any signal in secondary80 channel (80 MHz) if power above CCA-ED threshold + 6dB
341 nullptr,
344
345 //-----------------------------------------------------------------------------------------------------------------------------------
346
347 // VHT PHY: 20 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
348 // sensitivity threshold
353
354 // VHT PHY: 40 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
355 // sensitivity threshold
360
361 // VHT PHY: 80 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
362 // sensitivity threshold
367
368 // VHT PHY: 160 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
369 // sensitivity threshold
374
375 //-----------------------------------------------------------------------------------------------------------------------------------
376
377 // VHT PHY: 20 MHz VHT PPDU in secondary channel (20 MHz) if power above the CCA sensitivity
378 // threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
383
384 // VHT PHY: 20 MHz VHT PPDU in secondary40 channel (40 MHz) if power above the CCA sensitivity
385 // threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
390
391 // VHT PHY: 40 MHz VHT PPDU in secondary40 channel (40 MHz) if power above the CCA sensitivity
392 // threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20 MHz
397
398 // VHT PHY: 20 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA sensitivity
399 // threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
404
405 // VHT PHY: 40 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA sensitivity
406 // threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20 MHz
411
412 // VHT PHY: 80 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA sensitivity
413 // threshold corresponding to a 80 MHz PPDU that does not occupy the primary 20 MHz
418
419 //-----------------------------------------------------------------------------------------------------------------------------------
420
421 // HE PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
423 nullptr,
426
427 // HE PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
429 nullptr,
432
433 // HE PHY: any signal in secondary40 channel (40 MHz) if power above CCA-ED threshold + 3dB
435 nullptr,
438
439 // HE PHY: any signal in secondary80 channel (80 MHz) if power above CCA-ED threshold + 6dB
441 nullptr,
444
445 //-----------------------------------------------------------------------------------------------------------------------------------
446
447 // HE PHY: 20 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
448 // threshold
453
454 // HE PHY: 40 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
455 // threshold
460
461 // HE PHY: 80 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
462 // threshold
467
468 // HE PHY: 160 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA sensitivity
469 // threshold
474
475 //-----------------------------------------------------------------------------------------------------------------------------------
476
477 // HE PHY: 20 MHz HE PPDU in secondary channel (20 MHz) if power above the max between the CCA
478 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
479 // and the OBSS-PD level
483 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
484
485 // HE PHY: 20 MHz HE PPDU in secondary40 channel (40 MHz) if power above the max between the CCA
486 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
487 // and the OBSS-PD level
491 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
492
493 // HE PHY: 40 MHz HE PPDU in secondary40 channel (40 MHz) if power above the max between the CCA
494 // sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20 MHz
495 // and the OBSS-PD level plus 3 dB
500 std::max(m_obssPdLevel + 3.0, std::get<1>(m_secondaryCcaSensitivityThresholds)));
501
502 // HE PHY: 20 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the CCA
503 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
504 // and the OBSS-PD level
508 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
509
510 // HE PHY: 40 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the CCA
511 // sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20 MHz
512 // and the OBSS-PD level plus 3 dB
517 std::max(m_obssPdLevel + 3.0, std::get<1>(m_secondaryCcaSensitivityThresholds)));
518
519 // HE PHY: 80 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the CCA
520 // sensitivity threshold corresponding to a 80 MHz PPDU that does not occupy the primary 20 MHz
521 // and the OBSS-PD level plus 6 dB
526 std::max(m_obssPdLevel + 6.0, std::get<2>(m_secondaryCcaSensitivityThresholds)));
527}
528
529void
531{
532 // default attributes
533 m_CcaEdThresholdDbm = -62.0;
534 m_CcaSensitivityDbm = -82.0;
535 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
536 m_obssPdLevel = -82.0;
537 RunOne();
538
539 // default attributes with OBSS-PD level set to -80 dBm
540 m_CcaEdThresholdDbm = -62.0;
541 m_CcaSensitivityDbm = -82.0;
542 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
543 m_obssPdLevel = -80.0;
544 RunOne();
545
546 // default attributes with OBSS-PD level set to -70 dBm
547 m_CcaEdThresholdDbm = -62.0;
548 m_CcaSensitivityDbm = -82.0;
549 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
550 m_obssPdLevel = -70.0;
551 RunOne();
552
553 // CCA-ED set to -65 dBm
554 m_CcaEdThresholdDbm = -65.0;
555 m_CcaSensitivityDbm = -82.0;
556 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
557 m_obssPdLevel = -82.0;
558 RunOne();
559
560 // CCA sensitivity for signals in primary set to -75 dBm
561 m_CcaEdThresholdDbm = -62.0;
562 m_CcaSensitivityDbm = -75.0;
563 m_secondaryCcaSensitivityThresholds = std::make_tuple(-72.0, -72.0, -69.0);
564 m_obssPdLevel = -82.0;
565 RunOne();
566
567 // custom CCA sensitivities for signals not in primary
568 m_CcaEdThresholdDbm = -62.0;
569 m_CcaSensitivityDbm = -72.0;
570 m_secondaryCcaSensitivityThresholds = std::make_tuple(-70.0, -70.0, -70.0);
571 m_obssPdLevel = -82.0;
572 RunOne();
573
574 // custom CCA sensitivities for signals not in primary with OBSS-PD level set to -80 dBm
575 m_CcaEdThresholdDbm = -62.0;
576 m_CcaSensitivityDbm = -72.0;
577 m_secondaryCcaSensitivityThresholds = std::make_tuple(-70.0, -70.0, -70.0);
578 m_obssPdLevel = -80.0;
579 RunOne();
580
581 // custom CCA sensitivities for signals not in primary with OBSS-PD level set to -70 dBm
582 m_CcaEdThresholdDbm = -62.0;
583 m_CcaSensitivityDbm = -72.0;
584 m_secondaryCcaSensitivityThresholds = std::make_tuple(-70.0, -70.0, -70.0);
585 m_obssPdLevel = -70.0;
586 RunOne();
587
589}
590
591/**
592 * \ingroup wifi-test
593 * \ingroup tests
594 *
595 * \brief PHY listener for CCA tests
596 */
598{
599 public:
601
602 void NotifyRxStart(Time duration) override
603 {
604 NS_LOG_FUNCTION(this << duration);
605 }
606
607 void NotifyRxEndOk() override
608 {
609 NS_LOG_FUNCTION(this);
610 }
611
612 void NotifyRxEndError() override
613 {
614 NS_LOG_FUNCTION(this);
615 }
616
617 void NotifyTxStart(Time duration, double txPowerDbm) override
618 {
619 NS_LOG_FUNCTION(this << duration << txPowerDbm);
620 }
621
623 WifiChannelListType channelType,
624 const std::vector<Time>& per20MhzDurations) override
625 {
626 NS_LOG_FUNCTION(this << duration << channelType << per20MhzDurations.size());
627 m_endCcaBusy = Simulator::Now() + duration;
628 m_lastCcaBusyChannelType = channelType;
629 m_lastPer20MhzCcaBusyDurations = per20MhzDurations;
631 }
632
633 void NotifySwitchingStart(Time duration) override
634 {
635 }
636
637 void NotifySleep() override
638 {
639 }
640
641 void NotifyOff() override
642 {
643 }
644
645 void NotifyWakeup() override
646 {
647 }
648
649 void NotifyOn() override
650 {
651 }
652
653 /**
654 * Reset function
655 */
656 void Reset()
657 {
658 m_notifications = 0;
662 }
663
664 std::size_t m_notifications{0}; ///< Number of CCA notifications
665 Time m_endCcaBusy{Seconds(0)}; ///< End of the CCA-BUSY duration
667 WIFI_CHANLIST_PRIMARY}; ///< Channel type indication for the last CCA-BUSY notification
668 std::vector<Time>
669 m_lastPer20MhzCcaBusyDurations{}; ///< End of the CCA-BUSY durations per 20 MHz
670};
671
672/**
673 * \ingroup wifi-test
674 * \ingroup tests
675 *
676 * \brief Wifi Phy Threshold Test base class
677 */
679{
680 public:
682
683 private:
684 void DoSetup() override;
685 void DoRun() override;
686 void DoTeardown() override;
687
688 /**
689 * Send an HE SU PPDU
690 * \param txPowerDbm the transmit power in dBm
691 * \param frequency the center frequency the transmitter is operating on
692 * \param bandwidth the bandwidth to use for the transmission in MHz
693 */
694 void SendHeSuPpdu(double txPowerDbm, uint16_t frequency, uint16_t bandwidth);
695
696 /**
697 * Start to generate a signal
698 * \param signalGenerator the signal generator to use
699 * \param txPowerDbm the transmit power in dBm
700 * \param frequency the center frequency of the signal to send in MHz
701 * \param bandwidth the bandwidth of the signal to send in MHz
702 * \param duration the duration of the signal
703 */
704 void StartSignal(Ptr<WaveformGenerator> signalGenerator,
705 double txPowerDbm,
706 uint16_t frequency,
707 uint16_t bandwidth,
708 Time duration);
709 /**
710 * Stop to generate a signal
711 * \param signalGenerator the signal generator to use
712 */
713 void StopSignal(Ptr<WaveformGenerator> signalGenerator);
714
715 /**
716 * Check the PHY state
717 * \param expectedState the expected state of the PHY
718 */
719 void CheckPhyState(WifiPhyState expectedState);
720 /// \copydoc CheckPhyState
721 void DoCheckPhyState(WifiPhyState expectedState);
722
723 /**
724 * Check the last CCA-BUSY notification
725 * \param expectedEndTime the expected CCA-BUSY end time
726 * \param expectedChannelType the expected channel type
727 * \param expectedPer20MhzDurations the expected per-20 MHz CCA-BUSY durations
728 */
729 void CheckLastCcaBusyNotification(Time expectedEndTime,
730 WifiChannelListType expectedChannelType,
731 const std::vector<Time>& expectedPer20MhzDurations);
732
733 /**
734 * Log scenario description
735 *
736 * \param log the scenario description to add to log
737 */
738 void LogScenario(const std::string& log) const;
739
740 /**
741 * structure that holds information to generate signals
742 */
744 {
745 double power{0.0}; //!< transmit power to use in dBm
746 Time startTime{Seconds(0)}; //!< time at which transmission will be started
747 Time duration{Seconds(0)}; //!< the duration of the transmission
748 uint16_t centerFreq{0}; //!< center frequency to use in MHz
749 uint16_t bandwidth{0}; //!< bandwidth to use in MHz
750 };
751
752 /**
753 * structure that holds information to generate PPDUs
754 */
756 {
757 double power{0.0}; //!< transmit power to use in dBm
758 Time startTime{Seconds(0)}; //!< time at which transmission will be started
759 uint16_t centerFreq{0}; //!< center frequency to use in MHz
760 uint16_t bandwidth{0}; //!< bandwidth to use in MHz
761 };
762
763 /**
764 * structure that holds information to perform PHY state check
765 */
767 {
768 Time timePoint{Seconds(0)}; //!< time at which the check will performed
769 WifiPhyState expectedPhyState{WifiPhyState::IDLE}; //!< expected PHY state
770 };
771
772 /**
773 * structure that holds information to perform CCA check
774 */
776 {
777 Time timePoint{Seconds(0)}; //!< time at which the check will performed
778 Time expectedCcaEndTime{Seconds(0)}; //!< expected CCA_BUSY end time
780 WIFI_CHANLIST_PRIMARY}; //!< expected channel list type
781 std::vector<Time> expectedPer20MhzDurations{}; //!< expected per-20 MHz CCA duration
782 };
783
784 /**
785 * Schedule test to perform.
786 * \param delay the reference delay to schedule the events
787 * \param generatedSignals the vector of signals to be generated
788 * \param generatedPpdus the vector of PPDUs to be generated
789 * \param stateCheckpoints the vector of PHY state checks
790 * \param ccaCheckpoints the vector of PHY CCA checks
791 */
792 void ScheduleTest(Time delay,
793 const std::vector<TxSignalInfo>& generatedSignals,
794 const std::vector<TxPpduInfo>& generatedPpdus,
795 const std::vector<StateCheckPoint>& stateCheckpoints,
796 const std::vector<CcaCheckPoint>& ccaCheckpoints);
797
798 /**
799 * Reset function
800 */
801 void Reset();
802
803 /**
804 * Run one function
805 */
806 void RunOne();
807
808 Ptr<SpectrumWifiPhy> m_rxPhy; ///< PHY object of the receiver
809 Ptr<SpectrumWifiPhy> m_txPhy; ///< PHY object of the transmitter
810
811 std::vector<Ptr<WaveformGenerator>> m_signalGenerators; ///< Generators of non-wifi signals
812 std::size_t
813 m_numSignalGenerators; ///< The number of non-wifi signals generators needed for the test
814
815 std::shared_ptr<CcaTestPhyListener>
816 m_rxPhyStateListener; ///< Listener for PHY state transitions
817
818 uint16_t m_frequency; ///< Operating frequency in MHz
819 uint16_t m_channelWidth; ///< Operating channel width in MHz
820};
821
823 : TestCase("Wi-Fi PHY CCA indication test"),
824 m_numSignalGenerators(2),
825 m_frequency(P20_CENTER_FREQUENCY),
826 m_channelWidth(20)
827{
828}
829
830void
832 double txPowerDbm,
833 uint16_t frequency,
834 uint16_t bandwidth,
835 Time duration)
836{
837 NS_LOG_FUNCTION(this << signalGenerator << txPowerDbm << frequency << bandwidth << duration);
838
839 BandInfo bandInfo;
840 bandInfo.fc = frequency * 1e6;
841 bandInfo.fl = bandInfo.fc - ((bandwidth / 2) * 1e6);
842 bandInfo.fh = bandInfo.fc + ((bandwidth / 2) * 1e6);
843 Bands bands;
844 bands.push_back(bandInfo);
845
846 Ptr<SpectrumModel> spectrumSignal = Create<SpectrumModel>(bands);
847 Ptr<SpectrumValue> signalPsd = Create<SpectrumValue>(spectrumSignal);
848 *signalPsd = DbmToW(txPowerDbm) / (bandwidth * 1e6);
849
850 signalGenerator->SetTxPowerSpectralDensity(signalPsd);
851 signalGenerator->SetPeriod(duration);
852 signalGenerator->Start();
853 Simulator::Schedule(duration, &WifiPhyCcaIndicationTest::StopSignal, this, signalGenerator);
854}
855
856void
858{
859 NS_LOG_FUNCTION(this << signalGenerator);
860 signalGenerator->Stop();
861}
862
863void
864WifiPhyCcaIndicationTest::SendHeSuPpdu(double txPowerDbm, uint16_t frequency, uint16_t bandwidth)
865{
866 NS_LOG_FUNCTION(this << txPowerDbm);
867
868 auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0,
869 frequency,
870 bandwidth,
874 WifiPhy::ChannelTuple{channelNum, bandwidth, WIFI_PHY_BAND_5GHZ, 0});
875
876 WifiTxVector txVector =
877 WifiTxVector(HePhy::GetHeMcs0(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, bandwidth, false);
878
879 Ptr<Packet> pkt = Create<Packet>(1000);
880 WifiMacHeader hdr;
882 hdr.SetQosTid(0);
883 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
884
885 m_txPhy->SetTxPowerStart(txPowerDbm);
886 m_txPhy->SetTxPowerEnd(txPowerDbm);
887
888 m_txPhy->Send(psdu, txVector);
889}
890
891void
893{
894 // This is needed to make sure PHY state will be checked as the last event if a state change
895 // occurred at the exact same time as the check
897}
898
899void
901{
902 WifiPhyState currentState;
903 PointerValue ptr;
904 m_rxPhy->GetAttribute("State", ptr);
905 Ptr<WifiPhyStateHelper> state = DynamicCast<WifiPhyStateHelper>(ptr.Get<WifiPhyStateHelper>());
906 currentState = state->GetState();
907 NS_TEST_ASSERT_MSG_EQ(currentState,
908 expectedState,
909 "PHY State " << currentState << " does not match expected state "
910 << expectedState << " at " << Simulator::Now());
911}
912
913void
915 Time expectedEndTime,
916 WifiChannelListType expectedChannelType,
917 const std::vector<Time>& expectedPer20MhzDurations)
918{
920 expectedEndTime,
921 "PHY CCA end time " << m_rxPhyStateListener->m_endCcaBusy
922 << " does not match expected time " << expectedEndTime
923 << " at " << Simulator::Now());
924 NS_TEST_ASSERT_MSG_EQ(m_rxPhyStateListener->m_lastCcaBusyChannelType,
925 expectedChannelType,
926 "PHY CCA-BUSY for " << m_rxPhyStateListener->m_lastCcaBusyChannelType
927 << " does not match expected channel type "
928 << expectedChannelType << " at " << Simulator::Now());
929 NS_TEST_ASSERT_MSG_EQ(m_rxPhyStateListener->m_lastPer20MhzCcaBusyDurations.size(),
930 expectedPer20MhzDurations.size(),
931 "PHY CCA-BUSY per-20 MHz durations does not match expected vector"
932 << " at " << Simulator::Now());
933 for (std::size_t i = 0; i < expectedPer20MhzDurations.size(); ++i)
934 {
935 NS_TEST_ASSERT_MSG_EQ(m_rxPhyStateListener->m_lastPer20MhzCcaBusyDurations.at(i),
936 expectedPer20MhzDurations.at(i),
937 "PHY CCA-BUSY per-20 MHz duration at index "
938 << i << " does not match expected duration at "
939 << Simulator::Now());
940 }
941}
942
943void
944WifiPhyCcaIndicationTest::LogScenario(const std::string& log) const
945{
946 NS_LOG_INFO(log);
947}
948
949void
951 const std::vector<TxSignalInfo>& generatedSignals,
952 const std::vector<TxPpduInfo>& generatedPpdus,
953 const std::vector<StateCheckPoint>& stateCheckpoints,
954 const std::vector<CcaCheckPoint>& ccaCheckpoints)
955{
956 for (const auto& generatedPpdu : generatedPpdus)
957 {
958 Simulator::Schedule(delay + generatedPpdu.startTime,
960 this,
961 generatedPpdu.power,
962 generatedPpdu.centerFreq,
963 generatedPpdu.bandwidth);
964 }
965
966 std::size_t index = 0;
967 for (const auto& generatedSignal : generatedSignals)
968 {
969 Simulator::Schedule(delay + generatedSignal.startTime,
971 this,
972 m_signalGenerators.at(index++),
973 generatedSignal.power,
974 generatedSignal.centerFreq,
975 generatedSignal.bandwidth,
976 generatedSignal.duration);
977 }
978
979 for (const auto& checkpoint : ccaCheckpoints)
980 {
981 Simulator::Schedule(delay + checkpoint.timePoint,
983 this,
984 Simulator::Now() + delay + checkpoint.expectedCcaEndTime,
985 checkpoint.expectedChannelListType,
986 checkpoint.expectedPer20MhzDurations);
987 }
988
989 for (const auto& checkpoint : stateCheckpoints)
990 {
991 Simulator::Schedule(delay + checkpoint.timePoint,
993 this,
994 checkpoint.expectedPhyState);
995 }
996
998}
999
1000void
1002{
1003 m_rxPhyStateListener->Reset();
1004}
1005
1006void
1008{
1009 // WifiHelper::EnableLogComponents ();
1010 // LogComponentEnable ("WifiPhyCcaTest", LOG_LEVEL_ALL);
1011
1012 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
1013
1014 Ptr<Node> rxNode = CreateObject<Node>();
1015 Ptr<WifiNetDevice> rxDev = CreateObject<WifiNetDevice>();
1016 rxDev->SetStandard(WIFI_STANDARD_80211ax);
1017 Ptr<VhtConfiguration> vhtConfiguration = CreateObject<VhtConfiguration>();
1018 rxDev->SetVhtConfiguration(vhtConfiguration);
1019 m_rxPhy = CreateObject<SpectrumWifiPhy>();
1020 m_rxPhyStateListener = std::make_unique<CcaTestPhyListener>();
1022 Ptr<InterferenceHelper> rxInterferenceHelper = CreateObject<InterferenceHelper>();
1023 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
1024 Ptr<ErrorRateModel> rxErrorModel = CreateObject<NistErrorRateModel>();
1025 m_rxPhy->SetErrorRateModel(rxErrorModel);
1026 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
1027 CreateObject<ThresholdPreambleDetectionModel>();
1028 m_rxPhy->SetPreambleDetectionModel(preambleDetectionModel);
1029 m_rxPhy->AddChannel(spectrumChannel);
1031 m_rxPhy->SetDevice(rxDev);
1032 rxDev->SetPhy(m_rxPhy);
1033 rxNode->AddDevice(rxDev);
1034
1035 Ptr<Node> txNode = CreateObject<Node>();
1036 Ptr<WifiNetDevice> txDev = CreateObject<WifiNetDevice>();
1037 m_txPhy = CreateObject<SpectrumWifiPhy>();
1038 m_txPhy->SetAttribute("ChannelSwitchDelay", TimeValue(Seconds(0)));
1039 Ptr<InterferenceHelper> txInterferenceHelper = CreateObject<InterferenceHelper>();
1040 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
1041 Ptr<ErrorRateModel> txErrorModel = CreateObject<NistErrorRateModel>();
1042 m_txPhy->SetErrorRateModel(txErrorModel);
1043 m_txPhy->AddChannel(spectrumChannel);
1045 m_txPhy->SetDevice(txDev);
1046 txDev->SetPhy(m_txPhy);
1047 txNode->AddDevice(txDev);
1048
1049 for (std::size_t i = 0; i < m_numSignalGenerators; ++i)
1050 {
1051 Ptr<Node> signalGeneratorNode = CreateObject<Node>();
1052 Ptr<NonCommunicatingNetDevice> signalGeneratorDev =
1053 CreateObject<NonCommunicatingNetDevice>();
1054 Ptr<WaveformGenerator> signalGenerator = CreateObject<WaveformGenerator>();
1055 signalGenerator->SetDevice(signalGeneratorDev);
1056 signalGenerator->SetChannel(spectrumChannel);
1057 signalGenerator->SetDutyCycle(1);
1058 signalGeneratorNode->AddDevice(signalGeneratorDev);
1059 m_signalGenerators.push_back(signalGenerator);
1060 }
1061}
1062
1063void
1065{
1068 int64_t streamNumber = 0;
1069 m_rxPhy->AssignStreams(streamNumber);
1070 m_txPhy->AssignStreams(streamNumber);
1071
1072 auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0,
1077
1082
1083 std::vector<Time> expectedPer20MhzCcaBusyDurations{};
1084 Time delay = Seconds(0.0);
1086 delay += Seconds(1.0);
1087
1088 //----------------------------------------------------------------------------------------------------------------------------------
1089 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal below the
1090 // energy detection threshold occupies P20
1091 Simulator::Schedule(delay,
1093 this,
1094 "Reception of a signal that occupies P20 below ED threshold");
1095 ScheduleTest(delay,
1096 {{-65.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
1097 {},
1098 {
1099 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1100 {MicroSeconds(100) - smallDelta,
1101 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1102 {MicroSeconds(100) + smallDelta,
1103 WifiPhyState::IDLE} // IDLE just after the transmission ends
1104 },
1105 {});
1106 delay += Seconds(1.0);
1107
1108 //----------------------------------------------------------------------------------------------------------------------------------
1109 // Verify PHY state is CCA-BUSY as long as a 20 MHz signal above the energy detection threshold
1110 // occupies P20
1111 Simulator::Schedule(delay,
1113 this,
1114 "Reception of signal that occupies P20 above ED threshold");
1115 ScheduleTest(delay,
1116 {{-60.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
1117 {},
1118 {
1119 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1120 {MicroSeconds(100) - smallDelta,
1121 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1122 {MicroSeconds(100) + smallDelta,
1123 WifiPhyState::IDLE} // IDLE just after the transmission ends
1124 },
1125 {{MicroSeconds(100) - smallDelta,
1126 MicroSeconds(100),
1128 ((m_channelWidth > 20)
1129 ? ((m_channelWidth > 40)
1130 ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1131 MicroSeconds(0),
1132 MicroSeconds(0),
1133 MicroSeconds(0),
1134 MicroSeconds(0),
1135 MicroSeconds(0),
1136 MicroSeconds(0),
1137 MicroSeconds(0)}
1138 : std::vector<Time>{MicroSeconds(100),
1139 MicroSeconds(0),
1140 MicroSeconds(0),
1141 MicroSeconds(0)})
1142 : std::vector<Time>{MicroSeconds(100), MicroSeconds(0)})
1143 : std::vector<Time>{})}});
1144 delay += Seconds(1.0);
1145
1146 //----------------------------------------------------------------------------------------------------------------------------------
1147 // Verify PHY state is CCA-BUSY as long as the sum of 20 MHz signals occupying P20 is above the
1148 // energy detection threshold
1149 Simulator::Schedule(delay,
1151 this,
1152 "Reception of two 20 MHz signals that occupies P20 below ED threshold with "
1153 "sum above ED threshold");
1155 delay,
1156 {{-64.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, 20},
1157 {-65.0, MicroSeconds(50), MicroSeconds(200), P20_CENTER_FREQUENCY, 20}},
1158 {},
1159 {
1160 {MicroSeconds(50) + aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1161 {MicroSeconds(100) - smallDelta,
1162 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1163 {MicroSeconds(100) + smallDelta,
1164 WifiPhyState::IDLE} // IDLE just after the transmission ends
1165 },
1166 {{MicroSeconds(100) - smallDelta,
1167 MicroSeconds(100),
1169 ((m_channelWidth > 20)
1170 ? ((m_channelWidth > 40)
1171 ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(50),
1172 MicroSeconds(0),
1173 MicroSeconds(0),
1174 MicroSeconds(0),
1175 MicroSeconds(0),
1176 MicroSeconds(0),
1177 MicroSeconds(0),
1178 MicroSeconds(0)}
1179 : std::vector<Time>{MicroSeconds(50),
1180 MicroSeconds(0),
1181 MicroSeconds(0),
1182 MicroSeconds(0)})
1183 : std::vector<Time>{MicroSeconds(50), MicroSeconds(0)})
1184 : std::vector<Time>{})}});
1185 delay += Seconds(1.0);
1186
1187 //----------------------------------------------------------------------------------------------------------------------------------
1188 // Verify PHY state stays IDLE when a 20 MHz HE SU PPDU with received power below the
1189 // corresponding CCA sensitivity threshold occupies P20
1191 delay,
1193 this,
1194 "Reception of a 20 MHz HE PPDU that occupies P20 below CCA sensitivity threshold");
1195 ScheduleTest(delay,
1196 {},
1197 {{-85.0, MicroSeconds(0), P20_CENTER_FREQUENCY, 20}},
1198 {
1199 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1200 {PpduDurations.at(20) - smallDelta,
1201 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1202 {PpduDurations.at(20) + smallDelta,
1203 WifiPhyState::IDLE} // IDLE just after the transmission ends
1204 },
1205 {});
1206 delay += Seconds(1.0);
1207
1208 //----------------------------------------------------------------------------------------------------------------------------------
1209 // Verify PHY state transitions to CCA-BUSY when an HE SU PPDU with received power above the CCA
1210 // sensitivity threshold occupies P20. The per20Bitmap should indicate idle on the primary 20
1211 // MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1213 delay,
1215 this,
1216 "Reception of a 20 MHz HE PPDU that occupies P20 above CCA sensitivity threshold");
1218 delay,
1219 {},
1220 {{-80.0, MicroSeconds(0), P20_CENTER_FREQUENCY, 20}},
1221 {
1222 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1223 {PpduDurations.at(20) - smallDelta,
1224 WifiPhyState::RX}, // RX just before the transmission ends
1225 {PpduDurations.at(20) + smallDelta,
1226 WifiPhyState::IDLE} // IDLE just after the transmission ends
1227 },
1228 {{aCcaTime,
1229 MicroSeconds(16),
1231 ((m_channelWidth > 20)
1232 ? ((m_channelWidth > 40)
1233 ? ((m_channelWidth > 80)
1234 ? std::vector<Time>{Seconds(0),
1235 Seconds(0),
1236 Seconds(0),
1237 Seconds(0),
1238 Seconds(0),
1239 Seconds(0),
1240 Seconds(0),
1241 Seconds(0)}
1242 : std::vector<Time>{Seconds(0), Seconds(0), Seconds(0), Seconds(0)})
1243 : std::vector<Time>{Seconds(0), Seconds(0)})
1244 : std::vector<Time>{})}});
1245 delay += Seconds(1.0);
1246
1247 //----------------------------------------------------------------------------------------------------------------------------------
1248 // Verify PHY state stays IDLE when a 40 MHz HE SU PPDU with received power below the CCA
1249 // sensitivity threshold occupies P40
1251 delay,
1253 this,
1254 "Reception of a 40 MHz HE PPDU that occupies P20 below CCA sensitivity threshold");
1255 ScheduleTest(delay,
1256 {},
1257 {{-80.0, MicroSeconds(0), P40_CENTER_FREQUENCY, 40}},
1258 {
1259 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1260 {PpduDurations.at(40) - smallDelta,
1261 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1262 {PpduDurations.at(40) + smallDelta,
1263 WifiPhyState::IDLE} // IDLE just after the transmission ends
1264 },
1265 {});
1266 delay += Seconds(1.0);
1267
1268 //----------------------------------------------------------------------------------------------------------------------------------
1269 // Verify PHY state transitions to CCA-BUSY when an HE SU PPDU with received power above the CCA
1270 // sensitivity threshold occupies P40. The per20Bitmap should indicate idle on the primary 20
1271 // MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1273 delay,
1275 this,
1276 "Reception of a 40 MHz HE PPDU that occupies P40 above CCA sensitivity threshold");
1278 delay,
1279 {},
1280 {{-75.0, MicroSeconds(0), P40_CENTER_FREQUENCY, 40}},
1281 {
1282 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1283 {PpduDurations.at(40) - smallDelta,
1284 (m_channelWidth > 20)
1285 ? WifiPhyState::RX
1286 : WifiPhyState::CCA_BUSY}, // RX or IDLE just before the transmission ends
1287 {PpduDurations.at(40) + smallDelta,
1288 WifiPhyState::IDLE} // IDLE just after the transmission ends
1289 },
1290 {{aCcaTime,
1291 MicroSeconds(16),
1293 ((m_channelWidth > 20)
1294 ? ((m_channelWidth > 40)
1295 ? ((m_channelWidth > 80)
1296 ? std::vector<Time>{Seconds(0),
1297 Seconds(0),
1298 Seconds(0),
1299 Seconds(0),
1300 Seconds(0),
1301 Seconds(0),
1302 Seconds(0),
1303 Seconds(0)}
1304 : std::vector<Time>{Seconds(0), Seconds(0), Seconds(0), Seconds(0)})
1305 : std::vector<Time>{Seconds(0), Seconds(0)})
1306 : std::vector<Time>{})}});
1307 delay += Seconds(1.0);
1308
1309 if (m_channelWidth > 20)
1310 {
1311 //----------------------------------------------------------------------------------------------------------------------------------
1312 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a 20 MHz signal
1313 // below the energy detection threshold occupies S20
1314 Simulator::Schedule(delay,
1316 this,
1317 "Reception of a 20 MHz signal that occupies S20 below ED threshold");
1318 ScheduleTest(delay,
1319 {{-65.0, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
1320 {},
1321 {
1322 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1323 {MicroSeconds(100) - smallDelta,
1324 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1325 {MicroSeconds(100) + smallDelta,
1326 WifiPhyState::IDLE} // IDLE just after the transmission ends
1327 },
1328 {});
1329 delay += Seconds(1.0);
1330
1331 //----------------------------------------------------------------------------------------------------------------------------------
1332 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz signal
1333 // above the energy detection threshold occupies S20
1334 Simulator::Schedule(delay,
1336 this,
1337 "Reception of a 20 MHz signal that occupies S20 above ED threshold");
1339 delay,
1340 {{-60.0, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
1341 {},
1342 {
1343 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1344 {MicroSeconds(100) - smallDelta,
1345 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1346 {MicroSeconds(100) + smallDelta,
1347 WifiPhyState::IDLE} // IDLE just after the transmission ends
1348 },
1349 {{MicroSeconds(100) - smallDelta,
1350 MicroSeconds(100),
1352 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1353 MicroSeconds(100),
1354 MicroSeconds(0),
1355 MicroSeconds(0),
1356 MicroSeconds(0),
1357 MicroSeconds(0),
1358 MicroSeconds(0),
1359 MicroSeconds(0)}
1360 : std::vector<Time>{MicroSeconds(0),
1361 MicroSeconds(100),
1362 MicroSeconds(0),
1363 MicroSeconds(0)})
1364 : std::vector<Time>{MicroSeconds(0), MicroSeconds(100)})}});
1365 delay += Seconds(1.0);
1366
1367 //----------------------------------------------------------------------------------------------------------------------------------
1368 // Verify PHY state is CCA-BUSY as long as a 40 MHz signal above the energy detection
1369 // threshold occupies P40
1370 Simulator::Schedule(delay,
1372 this,
1373 "Reception of a 40 MHz signal that occupies P40 above ED threshold");
1375 delay,
1376 {{-55.0, MicroSeconds(0), MicroSeconds(100), P40_CENTER_FREQUENCY, 40}},
1377 {},
1378 {
1379 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1380 {MicroSeconds(100) - smallDelta,
1381 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1382 {MicroSeconds(100) + smallDelta,
1383 WifiPhyState::IDLE} // IDLE just after the transmission ends
1384 },
1385 {{MicroSeconds(100) - smallDelta,
1386 MicroSeconds(100),
1388 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1389 MicroSeconds(100),
1390 MicroSeconds(0),
1391 MicroSeconds(0),
1392 MicroSeconds(0),
1393 MicroSeconds(0),
1394 MicroSeconds(0),
1395 MicroSeconds(0)}
1396 : std::vector<Time>{MicroSeconds(100),
1397 MicroSeconds(100),
1398 MicroSeconds(0),
1399 MicroSeconds(0)})
1400 : std::vector<Time>{MicroSeconds(100), MicroSeconds(100)})}});
1401 delay += Seconds(1.0);
1402
1403 //----------------------------------------------------------------------------------------------------------------------------------
1404 // Verify PHY notifies CCA-BUSY for the primary channel while the secondary channel was
1405 // already in CCA-BUSY state
1406 Simulator::Schedule(delay,
1408 this,
1409 "Reception of a signal that occupies S20 followed by the reception of "
1410 "another signal that occupies P20");
1412 delay,
1413 {{-60.0, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, 20},
1414 {-60.0, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
1415 {},
1416 {
1417 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
1418 {MicroSeconds(50) + aCcaTime,
1419 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after aCCATime that
1420 // followed the second transmission
1421 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
1422 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1423 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
1424 WifiPhyState::IDLE} // IDLE just after the transmission ends
1425 },
1426 {{aCcaTime, // notification upon reception of the first signal
1427 MicroSeconds(100),
1429 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1430 MicroSeconds(100),
1431 MicroSeconds(0),
1432 MicroSeconds(0),
1433 MicroSeconds(0),
1434 MicroSeconds(0),
1435 MicroSeconds(0),
1436 MicroSeconds(0)}
1437 : std::vector<Time>{MicroSeconds(0),
1438 MicroSeconds(100),
1439 MicroSeconds(0),
1440 MicroSeconds(0)})
1441 : std::vector<Time>{MicroSeconds(0), MicroSeconds(100)})},
1442 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
1443 MicroSeconds(50) + MicroSeconds(100),
1445 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1446 MicroSeconds(50),
1447 MicroSeconds(0),
1448 MicroSeconds(0),
1449 MicroSeconds(0),
1450 MicroSeconds(0),
1451 MicroSeconds(0),
1452 MicroSeconds(0)}
1453 : std::vector<Time>{MicroSeconds(100),
1454 MicroSeconds(50),
1455 MicroSeconds(0),
1456 MicroSeconds(0)})
1457 : std::vector<Time>{MicroSeconds(100), MicroSeconds(50)})}});
1458 delay += Seconds(1.0);
1459
1460 //----------------------------------------------------------------------------------------------------------------------------------
1461 // Verify PHY updates per-20 MHz CCA durations if a signal arrives on the secondary channel
1462 // while primary is CCA-BUSY
1463 Simulator::Schedule(delay,
1465 this,
1466 "Reception of a signal that occupies P20 followed by the reception of "
1467 "another signal that occupies S20");
1469 delay,
1470 {{-60.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, 20},
1471 {-60.0, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
1472 {},
1473 {
1474 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1475 {MicroSeconds(50) + aCcaTime,
1476 WifiPhyState::CCA_BUSY}, // state of primary is still CCA-BUSY after aCCATime that
1477 // followed the second transmission
1478 {MicroSeconds(100) - smallDelta,
1479 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the first transmission ends
1480 {MicroSeconds(100) + smallDelta,
1481 WifiPhyState::IDLE} // IDLE just after the first transmission ends
1482 },
1483 {{aCcaTime, // notification upon reception of the first signal
1484 MicroSeconds(100),
1486 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1487 MicroSeconds(0),
1488 MicroSeconds(0),
1489 MicroSeconds(0),
1490 MicroSeconds(0),
1491 MicroSeconds(0),
1492 MicroSeconds(0),
1493 MicroSeconds(0)}
1494 : std::vector<Time>{MicroSeconds(100),
1495 MicroSeconds(0),
1496 MicroSeconds(0),
1497 MicroSeconds(0)})
1498 : std::vector<Time>{MicroSeconds(100), MicroSeconds(0)})},
1499 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
1500 MicroSeconds(100),
1502 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(50),
1503 MicroSeconds(100),
1504 MicroSeconds(0),
1505 MicroSeconds(0),
1506 MicroSeconds(0),
1507 MicroSeconds(0),
1508 MicroSeconds(0),
1509 MicroSeconds(0)}
1510 : std::vector<Time>{MicroSeconds(50),
1511 MicroSeconds(100),
1512 MicroSeconds(0),
1513 MicroSeconds(0)})
1514 : std::vector<Time>{MicroSeconds(50), MicroSeconds(100)})}});
1515 delay += Seconds(1.0);
1516
1517 //----------------------------------------------------------------------------------------------------------------------------------
1518 // Verify PHY state stays IDLE when a 20 MHz HE SU PPDU with received power below the CCA
1519 // sensitivity threshold occupies S40
1521 delay,
1523 this,
1524 "Reception of a 20 MHz HE PPDU that occupies S20 below CCA sensitivity threshold");
1525 ScheduleTest(delay,
1526 {},
1527 {{-75.0, MicroSeconds(0), S20_CENTER_FREQUENCY, 20}},
1528 {
1529 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1530 {PpduDurations.at(20) - smallDelta,
1531 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1532 {PpduDurations.at(20) + smallDelta,
1533 WifiPhyState::IDLE} // IDLE just after the transmission ends
1534 },
1535 {});
1536 delay += Seconds(1.0);
1537
1538 //----------------------------------------------------------------------------------------------------------------------------------
1539 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz HE SU PPDU
1540 // with received power above the CCA sensitivity threshold occupies S20
1542 delay,
1544 this,
1545 "Reception of a 20 MHz HE PPDU that occupies S20 above CCA sensitivity threshold");
1546 ScheduleTest(delay,
1547 {},
1548 {{-70.0, MicroSeconds(0), S20_CENTER_FREQUENCY, 20}},
1549 {
1550 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1551 {PpduDurations.at(20) - smallDelta,
1552 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1553 {PpduDurations.at(20) + smallDelta,
1554 WifiPhyState::IDLE} // IDLE just after the transmission ends
1555 },
1556 {{aCcaTime,
1557 PpduDurations.at(20),
1559 ((m_channelWidth > 40)
1560 ? ((m_channelWidth > 80) ? std::vector<Time>{NanoSeconds(0),
1561 PpduDurations.at(20),
1562 NanoSeconds(0),
1563 NanoSeconds(0),
1564 NanoSeconds(0),
1565 NanoSeconds(0),
1566 NanoSeconds(0),
1567 NanoSeconds(0)}
1568 : std::vector<Time>{NanoSeconds(0),
1569 PpduDurations.at(20),
1570 NanoSeconds(0),
1571 NanoSeconds(0)})
1572 : std::vector<Time>{NanoSeconds(0), PpduDurations.at(20)})}});
1573 delay += Seconds(1.0);
1574
1575 //----------------------------------------------------------------------------------------------------------------------------------
1576 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a signal
1577 // above the energy detection threshold occupies the S20 while a 40 MHz PPDU below the CCA
1578 // sensitivity threshold is received on P40.
1580 delay,
1582 this,
1583 "Reception of a 20 MHz signal that occupies S20 above ED threshold followed by a 40 "
1584 "MHz HE PPDU that occupies P40 below CCA sensitivity threshold");
1586 delay,
1587 {{-60.0,
1588 MicroSeconds(0),
1589 MicroSeconds(100),
1591 20}}, // signal on S20 above threshold
1592 {{-80.0, MicroSeconds(50), P40_CENTER_FREQUENCY, 40}}, // PPDU on P40 below threshold
1593 {
1594 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // PHY state stays IDLE
1595 },
1596 {{MicroSeconds(50) - smallDelta,
1597 MicroSeconds(100),
1599 ((m_channelWidth > 20)
1600 ? ((m_channelWidth > 40)
1601 ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1602 MicroSeconds(100),
1603 MicroSeconds(0),
1604 MicroSeconds(0),
1605 MicroSeconds(0),
1606 MicroSeconds(0),
1607 MicroSeconds(0),
1608 MicroSeconds(0)}
1609 : std::vector<Time>{MicroSeconds(0),
1610 MicroSeconds(100),
1611 MicroSeconds(0),
1612 MicroSeconds(0)})
1613 : std::vector<Time>{MicroSeconds(0), MicroSeconds(100)})
1614 : std::vector<Time>{})},
1615 {MicroSeconds(100) - smallDelta,
1616 MicroSeconds(100),
1618 ((m_channelWidth > 40) ? ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1619 MicroSeconds(46),
1620 MicroSeconds(0),
1621 MicroSeconds(0),
1622 MicroSeconds(0),
1623 MicroSeconds(0),
1624 MicroSeconds(0),
1625 MicroSeconds(0)}
1626 : std::vector<Time>{MicroSeconds(0),
1627 MicroSeconds(46),
1628 MicroSeconds(0),
1629 MicroSeconds(0)})
1630 : std::vector<Time>{MicroSeconds(0), MicroSeconds(46)})}});
1631 delay += Seconds(1.0);
1632 }
1633
1634 if (m_channelWidth > 40)
1635 {
1636 //----------------------------------------------------------------------------------------------------------------------------------
1637 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal below
1638 // the energy detection threshold occupies S40
1639 Simulator::Schedule(delay,
1641 this,
1642 "Reception of a 20 MHz signal that occupies the first subchannel of "
1643 "S40 below ED threshold");
1644 ScheduleTest(delay,
1645 {{-65.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20}},
1646 {},
1647 {
1648 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1649 {MicroSeconds(100) - smallDelta,
1650 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1651 {MicroSeconds(100) + smallDelta,
1652 WifiPhyState::IDLE} // IDLE just after the transmission ends
1653 },
1654 {});
1655 delay += Seconds(1.0);
1656
1657 //----------------------------------------------------------------------------------------------------------------------------------
1658 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy detection
1659 // threshold occupies the first 20 MHz subchannel of the S40: 27.3.20.6.4: Any signal within
1660 // the secondary 40 MHz channel at or above a threshold of –59 dBm within a period of
1661 // aCCATime after the signal arrives at the receiver’s antenna(s).
1662 Simulator::Schedule(delay,
1664 this,
1665 "Reception of a 20 MHz signal that occupies the first subchannel of "
1666 "S40 above ED threshold");
1667 ScheduleTest(delay,
1668 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20}},
1669 {},
1670 {
1671 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1672 {MicroSeconds(100) - smallDelta,
1673 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1674 {MicroSeconds(100) + smallDelta,
1675 WifiPhyState::IDLE} // IDLE just after the transmission ends
1676 },
1677 {{MicroSeconds(100) - smallDelta,
1678 MicroSeconds(100),
1680 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1681 MicroSeconds(0),
1682 MicroSeconds(100),
1683 MicroSeconds(0),
1684 MicroSeconds(0),
1685 MicroSeconds(0),
1686 MicroSeconds(0),
1687 MicroSeconds(0)}
1688 : std::vector<Time>{MicroSeconds(0),
1689 MicroSeconds(0),
1690 MicroSeconds(100),
1691 MicroSeconds(0)})}});
1692 delay += Seconds(1.0);
1693
1694 //----------------------------------------------------------------------------------------------------------------------------------
1695 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection threshold
1696 // occupies the second 20 MHz subchannel of the S40
1697 Simulator::Schedule(delay,
1699 this,
1700 "Reception of a 20 MHz signal that occupies the second subchannel of "
1701 "S40 below ED threshold");
1702 ScheduleTest(delay,
1703 {{-65.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY + 10, 20}},
1704 {},
1705 {
1706 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1707 {MicroSeconds(100) - smallDelta,
1708 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1709 {MicroSeconds(100) + smallDelta,
1710 WifiPhyState::IDLE} // IDLE just after the transmission ends
1711 },
1712 {});
1713 delay += Seconds(1.0);
1714
1715 //----------------------------------------------------------------------------------------------------------------------------------
1716 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy detection
1717 // threshold occupies the second 20 MHz subchannel of the S40: 27.3.20.6.4: Any signal
1718 // within the secondary 40 MHz channel at or above a threshold of –59 dBm within a period of
1719 // aCCATime after the signal arrives at the receiver’s antenna(s).
1720 Simulator::Schedule(delay,
1722 this,
1723 "Reception of a 20 MHz signal that occupies the second subchannel of "
1724 "S40 above ED threshold");
1725 ScheduleTest(delay,
1726 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY + 10, 20}},
1727 {},
1728 {
1729 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1730 {MicroSeconds(100) - smallDelta,
1731 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1732 {MicroSeconds(100) + smallDelta,
1733 WifiPhyState::IDLE} // IDLE just after the transmission ends
1734 },
1735 {{MicroSeconds(100) - smallDelta,
1736 MicroSeconds(100),
1738 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1739 MicroSeconds(0),
1740 MicroSeconds(0),
1741 MicroSeconds(100),
1742 MicroSeconds(0),
1743 MicroSeconds(0),
1744 MicroSeconds(0),
1745 MicroSeconds(0)}
1746 : std::vector<Time>{MicroSeconds(0),
1747 MicroSeconds(0),
1748 MicroSeconds(0),
1749 MicroSeconds(100)})}});
1750 delay += Seconds(1.0);
1751
1752 //----------------------------------------------------------------------------------------------------------------------------------
1753 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection threshold
1754 // occupies S40
1755 Simulator::Schedule(delay,
1757 this,
1758 "Reception of a 40 MHz signal that occupies S40 below ED threshold");
1759 ScheduleTest(delay,
1760 {{-60.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY, 40}},
1761 {},
1762 {
1763 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1764 {MicroSeconds(100) - smallDelta,
1765 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1766 {MicroSeconds(100) + smallDelta,
1767 WifiPhyState::IDLE} // IDLE just after the transmission ends
1768 },
1769 {});
1770 delay += Seconds(1.0);
1771
1772 //----------------------------------------------------------------------------------------------------------------------------------
1773 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy detection
1774 // threshold occupies S40: 27.3.20.6.4: Any signal within the secondary 40 MHz channel at or
1775 // above a threshold of –59 dBm within a period of aCCATime after the signal arrives at the
1776 // receiver’s antenna(s).
1777 Simulator::Schedule(delay,
1779 this,
1780 "Reception of a 20 MHz signal that occupies the second subchannel of "
1781 "S40 above ED threshold");
1782 ScheduleTest(delay,
1783 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY, 40}},
1784 {},
1785 {
1786 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1787 {MicroSeconds(100) - smallDelta,
1788 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1789 {MicroSeconds(100) + smallDelta,
1790 WifiPhyState::IDLE} // IDLE just after the transmission ends
1791 },
1792 {{MicroSeconds(100) - smallDelta,
1793 MicroSeconds(100),
1795 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1796 MicroSeconds(0),
1797 MicroSeconds(100),
1798 MicroSeconds(100),
1799 MicroSeconds(0),
1800 MicroSeconds(0),
1801 MicroSeconds(0),
1802 MicroSeconds(0)}
1803 : std::vector<Time>{MicroSeconds(0),
1804 MicroSeconds(0),
1805 MicroSeconds(100),
1806 MicroSeconds(100)})}});
1807 delay += Seconds(1.0);
1808
1809 //----------------------------------------------------------------------------------------------------------------------------------
1810 // Verify PHY state is CCA-BUSY as long as a 80 MHz signal above the energy detection
1811 // threshold occupies P80
1812 Simulator::Schedule(delay,
1814 this,
1815 "Reception of a 80 MHz signal that occupies P80 above ED threshold");
1816 ScheduleTest(delay,
1817 {{-55.0, MicroSeconds(0), MicroSeconds(100), P80_CENTER_FREQUENCY, 80}},
1818 {},
1819 {
1820 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
1821 {MicroSeconds(100) - smallDelta,
1822 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1823 {MicroSeconds(100) + smallDelta,
1824 WifiPhyState::IDLE} // IDLE just after the transmission ends
1825 },
1826 {{MicroSeconds(100) - smallDelta,
1827 MicroSeconds(100),
1829 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1830 MicroSeconds(100),
1831 MicroSeconds(100),
1832 MicroSeconds(100),
1833 MicroSeconds(0),
1834 MicroSeconds(0),
1835 MicroSeconds(0),
1836 MicroSeconds(0)}
1837 : std::vector<Time>{MicroSeconds(100),
1838 MicroSeconds(100),
1839 MicroSeconds(100),
1840 MicroSeconds(100)})}});
1841 delay += Seconds(1.0);
1842
1843 //----------------------------------------------------------------------------------------------------------------------------------
1844 // Verify PHY notifies CCA-BUSY for the P20 channel while the S40 channel was already in
1845 // CCA-BUSY state
1846 Simulator::Schedule(delay,
1848 this,
1849 "Reception of a 20 MHz signal that occupies S40 followed by the "
1850 "reception of another 20 MHz signal that occupies P20");
1852 delay,
1853 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20},
1854 {-55.0, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
1855 {},
1856 {
1857 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
1858 {MicroSeconds(50) + aCcaTime,
1859 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after aCCATime that
1860 // followed the second transmission
1861 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
1862 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1863 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
1864 WifiPhyState::IDLE} // IDLE just after the transmission ends
1865 },
1866 {{aCcaTime, // notification upon reception of the first signal
1867 MicroSeconds(100),
1869 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1870 MicroSeconds(0),
1871 MicroSeconds(100),
1872 MicroSeconds(0),
1873 MicroSeconds(0),
1874 MicroSeconds(0),
1875 MicroSeconds(0),
1876 MicroSeconds(0)}
1877 : std::vector<Time>{MicroSeconds(0),
1878 MicroSeconds(0),
1879 MicroSeconds(100),
1880 MicroSeconds(0)})},
1881 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
1882 MicroSeconds(50) + MicroSeconds(100),
1884 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(100),
1885 MicroSeconds(0),
1886 MicroSeconds(50),
1887 MicroSeconds(0),
1888 MicroSeconds(0),
1889 MicroSeconds(0),
1890 MicroSeconds(0),
1891 MicroSeconds(0)}
1892 : std::vector<Time>{MicroSeconds(100),
1893 MicroSeconds(0),
1894 MicroSeconds(50),
1895 MicroSeconds(0)})}});
1896 delay += Seconds(1.0);
1897
1898 //----------------------------------------------------------------------------------------------------------------------------------
1899 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S40
1900 // channel was already in CCA-BUSY state
1901 Simulator::Schedule(delay,
1903 this,
1904 "Reception of a signal that occupies S40 followed by the reception of "
1905 "another signal that occupies S20");
1907 delay,
1908 {{-55.0, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20},
1909 {-55.0, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
1910 {},
1911 {
1912 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
1913 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // state of primary stays IDLE
1914 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
1915 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1916 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
1917 WifiPhyState::IDLE} // IDLE just after the transmission ends
1918 },
1919 {{aCcaTime, // notification upon reception of the first signal
1920 MicroSeconds(100),
1922 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1923 MicroSeconds(0),
1924 MicroSeconds(100),
1925 MicroSeconds(0),
1926 MicroSeconds(0),
1927 MicroSeconds(0),
1928 MicroSeconds(0),
1929 MicroSeconds(0)}
1930 : std::vector<Time>{MicroSeconds(0),
1931 MicroSeconds(0),
1932 MicroSeconds(100),
1933 MicroSeconds(0)})},
1934 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
1935 MicroSeconds(50) + MicroSeconds(100),
1937 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
1938 MicroSeconds(100),
1939 MicroSeconds(50),
1940 MicroSeconds(0),
1941 MicroSeconds(0),
1942 MicroSeconds(0),
1943 MicroSeconds(0),
1944 MicroSeconds(0)}
1945 : std::vector<Time>{MicroSeconds(0),
1946 MicroSeconds(100),
1947 MicroSeconds(50),
1948 MicroSeconds(0)})}});
1949 delay += Seconds(1.0);
1950
1951 //----------------------------------------------------------------------------------------------------------------------------------
1952 // Verify PHY state stays IDLE when a 40 MHz HE SU PPDU with received power below the CCA
1953 // sensitivity threshold occupies S40
1955 delay,
1957 this,
1958 "Reception of a 40 MHz HE PPDU that occupies S40 below CCA sensitivity threshold");
1959 ScheduleTest(delay,
1960 {},
1961 {{-75.0, MicroSeconds(0), S40_CENTER_FREQUENCY, 40}},
1962 {
1963 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1964 {PpduDurations.at(20) - smallDelta,
1965 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1966 {PpduDurations.at(20) + smallDelta,
1967 WifiPhyState::IDLE} // IDLE just after the transmission ends
1968 },
1969 {});
1970 delay += Seconds(1.0);
1971
1972 //----------------------------------------------------------------------------------------------------------------------------------
1973 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 40 MHz HE SU PPDU
1974 // with received power above the CCA sensitivity threshold occupies S40
1976 delay,
1978 this,
1979 "Reception of a 40 MHz HE PPDU that occupies S40 above CCA sensitivity threshold");
1980 ScheduleTest(delay,
1981 {},
1982 {{-70.0, MicroSeconds(0), S40_CENTER_FREQUENCY, 40}},
1983 {
1984 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
1985 {PpduDurations.at(40) - smallDelta,
1986 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1987 {PpduDurations.at(40) + smallDelta,
1988 WifiPhyState::IDLE} // IDLE just after the transmission ends
1989 },
1990 {{aCcaTime,
1991 PpduDurations.at(40),
1993 ((m_channelWidth > 80) ? std::vector<Time>{NanoSeconds(0),
1994 NanoSeconds(0),
1995 PpduDurations.at(40),
1996 PpduDurations.at(40),
1997 NanoSeconds(0),
1998 NanoSeconds(0),
1999 NanoSeconds(0),
2000 NanoSeconds(0)}
2001 : std::vector<Time>{NanoSeconds(0),
2002 NanoSeconds(0),
2003 PpduDurations.at(40),
2004 PpduDurations.at(40)})}});
2005 delay += Seconds(1.0);
2006
2007 //----------------------------------------------------------------------------------------------------------------------------------
2008 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a signal
2009 // above the energy detection threshold occupies the S40 while a 80 MHz PPDU below the CCA
2010 // sensitivity threshold is received on P80.
2012 delay,
2014 this,
2015 "Reception of a 40 MHz signal that occupies S40 above ED threshold followed by a 80 "
2016 "MHz HE PPDU that occupies P80 below CCA sensitivity threshold");
2018 delay,
2019 {{-55.0,
2020 MicroSeconds(0),
2021 MicroSeconds(100),
2023 40}}, // signal on S40 above threshold
2024 {{-80.0, MicroSeconds(50), P80_CENTER_FREQUENCY, 80}}, // PPDU on P80 below threshold
2025 {
2026 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // PHY state stays IDLE
2027 },
2028 {{MicroSeconds(50) - smallDelta,
2029 MicroSeconds(100),
2031 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
2032 MicroSeconds(0),
2033 MicroSeconds(100),
2034 MicroSeconds(100),
2035 MicroSeconds(0),
2036 MicroSeconds(0),
2037 MicroSeconds(0),
2038 MicroSeconds(0)}
2039 : std::vector<Time>{MicroSeconds(0),
2040 MicroSeconds(0),
2041 MicroSeconds(100),
2042 MicroSeconds(100)})},
2043 {MicroSeconds(100) - smallDelta,
2044 MicroSeconds(100),
2046 ((m_channelWidth > 80) ? std::vector<Time>{MicroSeconds(0),
2047 MicroSeconds(0),
2048 MicroSeconds(46),
2049 MicroSeconds(46),
2050 MicroSeconds(0),
2051 MicroSeconds(0),
2052 MicroSeconds(0),
2053 MicroSeconds(0)}
2054 : std::vector<Time>{MicroSeconds(0),
2055 MicroSeconds(0),
2056 MicroSeconds(46),
2057 MicroSeconds(46)})}});
2058 delay += Seconds(1.0);
2059 }
2060 else // 20 or 40 MHz receiver
2061 {
2062 //----------------------------------------------------------------------------------------------------------------------------------
2063 // Verify PHY notifies CCA-BUSY when a 80 MHz HE SU PPDU with received power above the CCA
2064 // sensitivity threshold occupies P40 The per20Bitmap should indicate idle for all
2065 // subchannels because received power is below -62 dBm (27.3.20.6.5).
2066 Simulator::Schedule(delay,
2068 this,
2069 "Reception of a 80 MHz HE PPDU that occupies the 40 MHz band above CCA "
2070 "sensitivity threshold");
2071 ScheduleTest(delay,
2072 {},
2073 {{-70.0, MicroSeconds(0), P80_CENTER_FREQUENCY, 80}},
2074 {
2075 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCCATime
2076 {PpduDurations.at(80) - smallDelta,
2077 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2078 {PpduDurations.at(80) + smallDelta,
2079 WifiPhyState::IDLE} // IDLE just after the transmission ends
2080 },
2081 {{aCcaTime,
2082 MicroSeconds(16),
2084 ((m_channelWidth > 20)
2085 ? ((m_channelWidth > 40)
2086 ? ((m_channelWidth > 80) ? std::vector<Time>{Seconds(0),
2087 Seconds(0),
2088 Seconds(0),
2089 Seconds(0),
2090 Seconds(0),
2091 Seconds(0),
2092 Seconds(0),
2093 Seconds(0)}
2094 : std::vector<Time>{Seconds(0),
2095 Seconds(0),
2096 Seconds(0),
2097 Seconds(0)})
2098 : std::vector<Time>{Seconds(0), Seconds(0)})
2099 : std::vector<Time>{})},
2100 {PpduDurations.at(80) - smallDelta,
2101 PpduDurations.at(80),
2103 ((m_channelWidth > 20)
2104 ? ((m_channelWidth > 40)
2105 ? ((m_channelWidth > 80) ? std::vector<Time>{Seconds(0),
2106 Seconds(0),
2107 Seconds(0),
2108 Seconds(0),
2109 Seconds(0),
2110 Seconds(0),
2111 Seconds(0),
2112 Seconds(0)}
2113 : std::vector<Time>{Seconds(0),
2114 Seconds(0),
2115 Seconds(0),
2116 Seconds(0)})
2117 : std::vector<Time>{Seconds(0), Seconds(0)})
2118 : std::vector<Time>{})}});
2119 delay += Seconds(1.0);
2120
2121 //----------------------------------------------------------------------------------------------------------------------------------
2122 // Verify PHY notifies CCA-BUSY when a 80 MHz HE SU PPDU with received power above the CCA
2123 // sensitivity threshold occupies P40 The per20Bitmap should indicate CCA_BUSY for all
2124 // subchannels because received power is above -62 dBm (27.3.20.6.5).
2125 Simulator::Schedule(delay,
2127 this,
2128 "Reception of a 80 MHz HE PPDU that occupies the 40 MHz band above CCA "
2129 "sensitivity threshold");
2131 delay,
2132 {},
2133 {{-55.0, MicroSeconds(0), P80_CENTER_FREQUENCY, 80}},
2134 {
2135 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCCATime
2136 {PpduDurations.at(80) - smallDelta,
2137 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2138 {PpduDurations.at(80) + smallDelta,
2139 WifiPhyState::IDLE} // IDLE just after the transmission ends
2140 },
2141 {{aCcaTime,
2142 MicroSeconds(16),
2144 ((m_channelWidth > 20)
2145 ? ((m_channelWidth > 40)
2146 ? ((m_channelWidth > 80) ? std::vector<Time>{NanoSeconds(271200),
2147 NanoSeconds(271200),
2148 NanoSeconds(271200),
2149 NanoSeconds(271200),
2150 NanoSeconds(0),
2151 NanoSeconds(0),
2152 NanoSeconds(0),
2153 NanoSeconds(0)}
2154 : std::vector<Time>{NanoSeconds(271200),
2155 NanoSeconds(271200),
2156 NanoSeconds(271200),
2157 NanoSeconds(271200)})
2158 : std::vector<Time>{NanoSeconds(271200), NanoSeconds(271200)})
2159 : std::vector<Time>{})},
2160 {PpduDurations.at(80) - smallDelta,
2161 PpduDurations.at(80),
2163 ((m_channelWidth > 20)
2164 ? ((m_channelWidth > 40)
2165 ? ((m_channelWidth > 80) ? std::vector<Time>{NanoSeconds(243200),
2166 NanoSeconds(243200),
2167 NanoSeconds(243200),
2168 NanoSeconds(243200),
2169 NanoSeconds(0),
2170 NanoSeconds(0),
2171 NanoSeconds(0),
2172 NanoSeconds(0)}
2173 : std::vector<Time>{NanoSeconds(243200),
2174 NanoSeconds(243200),
2175 NanoSeconds(243200),
2176 NanoSeconds(243200)})
2177 : std::vector<Time>{NanoSeconds(243200), NanoSeconds(243200)})
2178 : std::vector<Time>{})}});
2179 delay += Seconds(1.0);
2180
2181 //----------------------------------------------------------------------------------------------------------------------------------
2182 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal not
2183 // occupying the operational channel is being received
2185 delay,
2187 this,
2188 "Reception of a 40 MHz HE PPDU that does not occupy the operational channel");
2189 ScheduleTest(delay,
2190 {},
2191 {{-50.0, MicroSeconds(0), S40_CENTER_FREQUENCY, 40}},
2192 {
2193 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2194 {PpduDurations.at(20) - smallDelta,
2195 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2196 {PpduDurations.at(20) + smallDelta,
2197 WifiPhyState::IDLE} // IDLE just after the transmission ends
2198 },
2199 {});
2200 delay += Seconds(1.0);
2201 }
2202
2203 if (m_channelWidth > 80)
2204 {
2205 //----------------------------------------------------------------------------------------------------------------------------------
2206 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2207 // energy detection threshold occupies the first 20 MHz subchannel of the S80
2208 Simulator::Schedule(delay,
2210 this,
2211 "Reception of a 20 MHz signal that occupies the first subchannel of "
2212 "S80 below ED threshold");
2213 ScheduleTest(delay,
2214 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 30, 20}},
2215 {},
2216 {
2217 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2218 {MicroSeconds(100) - smallDelta,
2219 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2220 {MicroSeconds(100) + smallDelta,
2221 WifiPhyState::IDLE} // IDLE just after the transmission ends
2222 },
2223 {});
2224 delay += Seconds(1.0);
2225
2226 //----------------------------------------------------------------------------------------------------------------------------------
2227 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2228 // energy detection threshold occupies the first 20 MHz subchannel of the S80 27.3.20.6.4:
2229 // Any signal within the secondary 80 MHz channel at or above –56 dBm.
2230 Simulator::Schedule(delay,
2232 this,
2233 "Reception of a 20 MHz signal that occupies the first subchannel of "
2234 "S80 above ED threshold");
2235 ScheduleTest(delay,
2236 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 30, 20}},
2237 {},
2238 {
2239 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2240 {MicroSeconds(100) - smallDelta,
2241 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2242 {MicroSeconds(100) + smallDelta,
2243 WifiPhyState::IDLE} // IDLE just after the transmission ends
2244 },
2245 {{MicroSeconds(100) - smallDelta,
2246 MicroSeconds(100),
2248 std::vector<Time>{MicroSeconds(0),
2249 MicroSeconds(0),
2250 MicroSeconds(0),
2251 MicroSeconds(0),
2252 MicroSeconds(100),
2253 MicroSeconds(0),
2254 MicroSeconds(0),
2255 MicroSeconds(0)}}});
2256 delay += Seconds(1.0);
2257
2258 //----------------------------------------------------------------------------------------------------------------------------------
2259 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2260 // energy detection threshold occupies the second 20 MHz subchannel of the S80
2261 Simulator::Schedule(delay,
2263 this,
2264 "Reception of a 20 MHz signal that occupies the second subchannel of "
2265 "S80 below ED threshold");
2266 ScheduleTest(delay,
2267 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 10, 20}},
2268 {},
2269 {
2270 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2271 {MicroSeconds(100) - smallDelta,
2272 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2273 {MicroSeconds(100) + smallDelta,
2274 WifiPhyState::IDLE} // IDLE just after the transmission ends
2275 },
2276 {});
2277 delay += Seconds(1.0);
2278
2279 //----------------------------------------------------------------------------------------------------------------------------------
2280 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2281 // energy detection threshold occupies the second 20 MHz subchannel of the S80 27.3.20.6.4:
2282 // Any signal within the secondary 80 MHz channel at or above –56 dBm.
2283 Simulator::Schedule(delay,
2285 this,
2286 "Reception of a 20 MHz signal that occupies the second subchannel of "
2287 "S80 above ED threshold");
2288 ScheduleTest(delay,
2289 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 10, 20}},
2290 {},
2291 {
2292 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2293 {MicroSeconds(100) - smallDelta,
2294 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2295 {MicroSeconds(100) + smallDelta,
2296 WifiPhyState::IDLE} // IDLE just after the transmission ends
2297 },
2298 {{MicroSeconds(100) - smallDelta,
2299 MicroSeconds(100),
2301 std::vector<Time>{MicroSeconds(0),
2302 MicroSeconds(0),
2303 MicroSeconds(0),
2304 MicroSeconds(0),
2305 MicroSeconds(0),
2306 MicroSeconds(100),
2307 MicroSeconds(0),
2308 MicroSeconds(0)}}});
2309 delay += Seconds(1.0);
2310
2311 //----------------------------------------------------------------------------------------------------------------------------------
2312 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2313 // energy detection threshold occupies the third 20 MHz subchannel of the S80
2314 Simulator::Schedule(delay,
2316 this,
2317 "Reception of a 20 MHz signal that occupies the third subchannel of "
2318 "S80 below ED threshold");
2319 ScheduleTest(delay,
2320 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 10, 20}},
2321 {},
2322 {
2323 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2324 {MicroSeconds(100) - smallDelta,
2325 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2326 {MicroSeconds(100) + smallDelta,
2327 WifiPhyState::IDLE} // IDLE just after the transmission ends
2328 },
2329 {});
2330 delay += Seconds(1.0);
2331
2332 //----------------------------------------------------------------------------------------------------------------------------------
2333 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2334 // energy detection threshold occupies the third 20 MHz subchannel of the S80 27.3.20.6.4:
2335 // Any signal within the secondary 80 MHz channel at or above –56 dBm.
2336 Simulator::Schedule(delay,
2338 this,
2339 "Reception of a 20 MHz signal that occupies the third subchannel of "
2340 "S80 above ED threshold");
2341 ScheduleTest(delay,
2342 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 10, 20}},
2343 {},
2344 {
2345 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2346 {MicroSeconds(100) - smallDelta,
2347 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2348 {MicroSeconds(100) + smallDelta,
2349 WifiPhyState::IDLE} // IDLE just after the transmission ends
2350 },
2351 {{MicroSeconds(100) - smallDelta,
2352 MicroSeconds(100),
2354 std::vector<Time>{MicroSeconds(0),
2355 MicroSeconds(0),
2356 MicroSeconds(0),
2357 MicroSeconds(0),
2358 MicroSeconds(0),
2359 MicroSeconds(0),
2360 MicroSeconds(100),
2361 MicroSeconds(0)}}});
2362 delay += Seconds(1.0);
2363
2364 //----------------------------------------------------------------------------------------------------------------------------------
2365 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2366 // energy detection threshold occupies the fourth 20 MHz subchannel of the S80
2367 Simulator::Schedule(delay,
2369 this,
2370 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
2371 "S80 below ED threshold");
2372 ScheduleTest(delay,
2373 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 30, 20}},
2374 {},
2375 {
2376 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2377 {MicroSeconds(100) - smallDelta,
2378 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2379 {MicroSeconds(100) + smallDelta,
2380 WifiPhyState::IDLE} // IDLE just after the transmission ends
2381 },
2382 {});
2383 delay += Seconds(1.0);
2384
2385 //----------------------------------------------------------------------------------------------------------------------------------
2386 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2387 // energy detection threshold occupies the fourth 20 MHz subchannel of the S80 27.3.20.6.4:
2388 // Any signal within the secondary 80 MHz channel at or above –56 dBm.
2389 Simulator::Schedule(delay,
2391 this,
2392 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
2393 "S80 above ED threshold");
2394 ScheduleTest(delay,
2395 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 30, 20}},
2396 {},
2397 {
2398 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2399 {MicroSeconds(100) - smallDelta,
2400 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2401 {MicroSeconds(100) + smallDelta,
2402 WifiPhyState::IDLE} // IDLE just after the transmission ends
2403 },
2404 {{MicroSeconds(100) - smallDelta,
2405 MicroSeconds(100),
2407 std::vector<Time>{MicroSeconds(0),
2408 MicroSeconds(0),
2409 MicroSeconds(0),
2410 MicroSeconds(0),
2411 MicroSeconds(0),
2412 MicroSeconds(0),
2413 MicroSeconds(0),
2414 MicroSeconds(100)}}});
2415 delay += Seconds(1.0);
2416
2417 //----------------------------------------------------------------------------------------------------------------------------------
2418 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2419 // energy detection threshold occupies the first and second 20 MHz subchannels of the S80
2420 Simulator::Schedule(delay,
2422 this,
2423 "Reception of a 40 MHz signal that occupies the first and second "
2424 "subchannels of S80 below ED threshold");
2425 ScheduleTest(delay,
2426 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 20, 40}},
2427 {},
2428 {
2429 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2430 {MicroSeconds(100) - smallDelta,
2431 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2432 {MicroSeconds(100) + smallDelta,
2433 WifiPhyState::IDLE} // IDLE just after the transmission ends
2434 },
2435 {});
2436 delay += Seconds(1.0);
2437
2438 //----------------------------------------------------------------------------------------------------------------------------------
2439 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2440 // energy detection threshold occupies the first and second 20 MHz subchannels of the S80
2441 // 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2442 Simulator::Schedule(delay,
2444 this,
2445 "Reception of a 40 MHz signal that occupies the first and second "
2446 "subchannels of S80 above ED threshold");
2447 ScheduleTest(delay,
2448 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 20, 40}},
2449 {},
2450 {
2451 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2452 {MicroSeconds(100) - smallDelta,
2453 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2454 {MicroSeconds(100) + smallDelta,
2455 WifiPhyState::IDLE} // IDLE just after the transmission ends
2456 },
2457 {{MicroSeconds(100) - smallDelta,
2458 MicroSeconds(100),
2460 std::vector<Time>{MicroSeconds(0),
2461 MicroSeconds(0),
2462 MicroSeconds(0),
2463 MicroSeconds(0),
2464 MicroSeconds(100),
2465 MicroSeconds(100),
2466 MicroSeconds(0),
2467 MicroSeconds(0)}}});
2468 delay += Seconds(1.0);
2469
2470 //----------------------------------------------------------------------------------------------------------------------------------
2471 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2472 // energy detection threshold occupies the third and fourth 20 MHz subchannels of the S80
2473 Simulator::Schedule(delay,
2475 this,
2476 "Reception of a 40 MHz signal that occupies the third and fourth "
2477 "subchannels of S80 below ED threshold");
2478 ScheduleTest(delay,
2479 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 20, 40}},
2480 {},
2481 {
2482 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2483 {MicroSeconds(100) - smallDelta,
2484 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2485 {MicroSeconds(100) + smallDelta,
2486 WifiPhyState::IDLE} // IDLE just after the transmission ends
2487 },
2488 {});
2489 delay += Seconds(1.0);
2490
2491 //----------------------------------------------------------------------------------------------------------------------------------
2492 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2493 // energy detection threshold occupies the third and fourth 20 MHz subchannels of the S80
2494 // 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2495 Simulator::Schedule(delay,
2497 this,
2498 "Reception of a 40 MHz signal that occupies the third and fourth "
2499 "subchannels of S80 above ED threshold");
2500 ScheduleTest(delay,
2501 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 20, 40}},
2502 {},
2503 {
2504 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2505 {MicroSeconds(100) - smallDelta,
2506 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2507 {MicroSeconds(100) + smallDelta,
2508 WifiPhyState::IDLE} // IDLE just after the transmission ends
2509 },
2510 {{MicroSeconds(100) - smallDelta,
2511 MicroSeconds(100),
2513 std::vector<Time>{MicroSeconds(0),
2514 MicroSeconds(0),
2515 MicroSeconds(0),
2516 MicroSeconds(0),
2517 MicroSeconds(0),
2518 MicroSeconds(0),
2519 MicroSeconds(100),
2520 MicroSeconds(100)}}});
2521 delay += Seconds(1.0);
2522
2523 //----------------------------------------------------------------------------------------------------------------------------------
2524 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2525 // energy detection threshold occupies the S80
2526 Simulator::Schedule(delay,
2528 this,
2529 "Reception of a 80 MHz signal that occupies S80 below ED threshold");
2530 ScheduleTest(delay,
2531 {{-65.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY, 80}},
2532 {},
2533 {
2534 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2535 {MicroSeconds(100) - smallDelta,
2536 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2537 {MicroSeconds(100) + smallDelta,
2538 WifiPhyState::IDLE} // IDLE just after the transmission ends
2539 },
2540 {});
2541 delay += Seconds(1.0);
2542
2543 //----------------------------------------------------------------------------------------------------------------------------------
2544 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2545 // energy detection threshold occupies the S80 27.3.20.6.4: Any signal within the secondary
2546 // 80 MHz channel at or above –56 dBm.
2547 Simulator::Schedule(delay,
2549 this,
2550 "Reception of a 80 MHz signal that occupies S80 above ED threshold");
2551 ScheduleTest(delay,
2552 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY, 80}},
2553 {},
2554 {
2555 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2556 {MicroSeconds(100) - smallDelta,
2557 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2558 {MicroSeconds(100) + smallDelta,
2559 WifiPhyState::IDLE} // IDLE just after the transmission ends
2560 },
2561 {{MicroSeconds(100) - smallDelta,
2562 MicroSeconds(100),
2564 std::vector<Time>{MicroSeconds(0),
2565 MicroSeconds(0),
2566 MicroSeconds(0),
2567 MicroSeconds(0),
2568 MicroSeconds(100),
2569 MicroSeconds(100),
2570 MicroSeconds(100),
2571 MicroSeconds(100)}}});
2572 delay += Seconds(1.0);
2573
2574 //----------------------------------------------------------------------------------------------------------------------------------
2575 // Verify PHY state stays IDLE as long as a 160 MHz signal below the energy detection
2576 // threshold occupies the whole band
2578 delay,
2580 this,
2581 "Reception of a 160 MHz signal that occupies the whole band below ED threshold");
2582 ScheduleTest(delay,
2583 {{-55.0, MicroSeconds(0), MicroSeconds(100), P160_CENTER_FREQUENCY, 160}},
2584 {},
2585 {
2586 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2587 {MicroSeconds(100) - smallDelta,
2588 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2589 {MicroSeconds(100) + smallDelta,
2590 WifiPhyState::IDLE} // IDLE just after the transmission ends
2591 },
2592 {});
2593
2594 delay += Seconds(1.0);
2595
2596 //----------------------------------------------------------------------------------------------------------------------------------
2597 // Verify PHY state is CCA-BUSY as long as a 160 MHz signal above the energy detection
2598 // threshold occupies the whole band
2600 delay,
2602 this,
2603 "Reception of a 160 MHz signal that occupies the whole band above ED threshold");
2604 ScheduleTest(delay,
2605 {{-50.0, MicroSeconds(0), MicroSeconds(100), P160_CENTER_FREQUENCY, 160}},
2606 {},
2607 {
2608 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
2609 {MicroSeconds(100) - smallDelta,
2610 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2611 {MicroSeconds(100) + smallDelta,
2612 WifiPhyState::IDLE} // IDLE just after the transmission ends
2613 },
2614 {{MicroSeconds(100) - smallDelta,
2615 MicroSeconds(100),
2617 std::vector<Time>{MicroSeconds(100),
2618 MicroSeconds(100),
2619 MicroSeconds(100),
2620 MicroSeconds(100),
2621 MicroSeconds(100),
2622 MicroSeconds(100),
2623 MicroSeconds(100),
2624 MicroSeconds(100)}}});
2625 delay += Seconds(1.0);
2626
2627 //----------------------------------------------------------------------------------------------------------------------------------
2628 // Verify PHY notifies CCA-BUSY for the P20 channel while the S80 channel was already in
2629 // CCA-BUSY state
2630 Simulator::Schedule(delay,
2632 this,
2633 "Reception of a 20 MHz signal that occupies S80 followed by the "
2634 "reception of another 20 MHz signal that occupies P20");
2636 delay,
2637 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 10, 20},
2638 {-55.0, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, 20}},
2639 {},
2640 {
2641 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
2642 {MicroSeconds(50) + aCcaTime,
2643 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after aCCATime that
2644 // followed the second transmission
2645 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2646 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2647 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2648 WifiPhyState::IDLE} // IDLE just after the transmission ends
2649 },
2650 {{aCcaTime, // notification upon reception of the first signal
2651 MicroSeconds(100),
2653 std::vector<Time>{MicroSeconds(0),
2654 MicroSeconds(0),
2655 MicroSeconds(0),
2656 MicroSeconds(0),
2657 MicroSeconds(0),
2658 MicroSeconds(0),
2659 MicroSeconds(100),
2660 MicroSeconds(0)}},
2661 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
2662 MicroSeconds(50) + MicroSeconds(100),
2664 std::vector<Time>{MicroSeconds(100),
2665 MicroSeconds(0),
2666 MicroSeconds(00),
2667 MicroSeconds(0),
2668 MicroSeconds(0),
2669 MicroSeconds(0),
2670 MicroSeconds(50),
2671 MicroSeconds(0)}}});
2672 delay += Seconds(1.0);
2673
2674 //----------------------------------------------------------------------------------------------------------------------------------
2675 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S40 channel while the S80
2676 // channel was already in CCA-BUSY state
2677 Simulator::Schedule(delay,
2679 this,
2680 "Reception of a signal that occupies S80 followed by the reception of "
2681 "another signal that occupies S40");
2683 delay,
2684 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 30, 20},
2685 {-55.0, MicroSeconds(50), MicroSeconds(100), S40_CENTER_FREQUENCY - 10, 20}},
2686 {},
2687 {
2688 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
2689 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // state of primary stays IDLE
2690 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2691 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2692 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2693 WifiPhyState::IDLE} // IDLE just after the transmission ends
2694 },
2695 {{aCcaTime, // notification upon reception of the first signal
2696 MicroSeconds(100),
2698 std::vector<Time>{MicroSeconds(0),
2699 MicroSeconds(0),
2700 MicroSeconds(0),
2701 MicroSeconds(0),
2702 MicroSeconds(0),
2703 MicroSeconds(0),
2704 MicroSeconds(0),
2705 MicroSeconds(100)}},
2706 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
2707 MicroSeconds(50) + MicroSeconds(100),
2709 std::vector<Time>{MicroSeconds(0),
2710 MicroSeconds(0),
2711 MicroSeconds(100),
2712 MicroSeconds(0),
2713 MicroSeconds(0),
2714 MicroSeconds(0),
2715 MicroSeconds(0),
2716 MicroSeconds(50)}}});
2717 delay += Seconds(1.0);
2718
2719 //----------------------------------------------------------------------------------------------------------------------------------
2720 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S80
2721 // channel was already in CCA-BUSY state
2722 Simulator::Schedule(delay,
2724 this,
2725 "Reception of a signal that occupies S80 followed by the reception of "
2726 "another signal that occupies S20");
2728 delay,
2729 {{-55.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY - 30, 20},
2730 {-55.0, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, 20}},
2731 {},
2732 {
2733 {aCcaTime, WifiPhyState::IDLE}, // state of primary stays idle after aCCATime
2734 {MicroSeconds(50) + aCcaTime, WifiPhyState::IDLE}, // state of primary stays IDLE
2735 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2736 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2737 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2738 WifiPhyState::IDLE} // IDLE just after the transmission ends
2739 },
2740 {{aCcaTime, // notification upon reception of the first signal
2741 MicroSeconds(100),
2743 std::vector<Time>{MicroSeconds(0),
2744 MicroSeconds(0),
2745 MicroSeconds(0),
2746 MicroSeconds(0),
2747 MicroSeconds(100),
2748 MicroSeconds(0),
2749 MicroSeconds(0),
2750 MicroSeconds(0)}},
2751 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
2752 MicroSeconds(50) + MicroSeconds(100),
2754 std::vector<Time>{MicroSeconds(0),
2755 MicroSeconds(100),
2756 MicroSeconds(0),
2757 MicroSeconds(0),
2758 MicroSeconds(50),
2759 MicroSeconds(0),
2760 MicroSeconds(0),
2761 MicroSeconds(0)}}});
2762 delay += Seconds(1.0);
2763
2764 //----------------------------------------------------------------------------------------------------------------------------------
2765 // Verify PHY state stays IDLE when a 80 MHz HE SU PPDU with received power below the CCA
2766 // sensitivity threshold occupies S80
2768 delay,
2770 this,
2771 "Reception of a 40 MHz HE PPDU that occupies S40 below CCA sensitivity threshold");
2772 ScheduleTest(delay,
2773 {},
2774 {{-70.0, MicroSeconds(0), S80_CENTER_FREQUENCY, 80}},
2775 {
2776 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2777 {PpduDurations.at(20) - smallDelta,
2778 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2779 {PpduDurations.at(20) + smallDelta,
2780 WifiPhyState::IDLE} // IDLE just after the transmission ends
2781 },
2782 {});
2783 delay += Seconds(1.0);
2784
2785 //----------------------------------------------------------------------------------------------------------------------------------
2786 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 80 MHz HE SU PPDU
2787 // with received power above the CCA sensitivity threshold occupies S80
2789 delay,
2791 this,
2792 "Reception of a 80 MHz HE PPDU that occupies S80 above CCA sensitivity threshold");
2793 ScheduleTest(delay,
2794 {},
2795 {{-65.0, MicroSeconds(0), S80_CENTER_FREQUENCY, 80}},
2796 {
2797 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2798 {PpduDurations.at(80) - smallDelta,
2799 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2800 {PpduDurations.at(80) + smallDelta,
2801 WifiPhyState::IDLE} // IDLE just after the transmission ends
2802 },
2803 {{aCcaTime,
2804 PpduDurations.at(80),
2806 std::vector<Time>{NanoSeconds(0),
2807 NanoSeconds(0),
2808 NanoSeconds(0),
2809 NanoSeconds(0),
2810 PpduDurations.at(80),
2811 PpduDurations.at(80),
2812 PpduDurations.at(80),
2813 PpduDurations.at(80)}}});
2814 delay += Seconds(1.0);
2815
2816 //----------------------------------------------------------------------------------------------------------------------------------
2817 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if only the per20bitmap
2818 // parameter changes
2819 Simulator::Schedule(delay,
2821 this,
2822 "Reception of a 20 MHz signal that generates a per20bitmap parameter "
2823 "change when previous CCA indication reports IDLE");
2824 ScheduleTest(delay,
2825 {{-60.0, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY + 30, 20}},
2826 {},
2827 {
2828 {aCcaTime, WifiPhyState::IDLE}, // IDLE after aCCATime
2829 {MicroSeconds(100) - smallDelta,
2830 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2831 {MicroSeconds(100) + smallDelta,
2832 WifiPhyState::IDLE} // IDLE just after the transmission ends
2833 },
2834 {{aCcaTime,
2835 Seconds(0),
2837 std::vector<Time>{MicroSeconds(0),
2838 MicroSeconds(0),
2839 MicroSeconds(0),
2840 MicroSeconds(0),
2841 MicroSeconds(0),
2842 MicroSeconds(0),
2843 MicroSeconds(0),
2844 MicroSeconds(100)}}});
2845 delay += Seconds(1.0);
2846
2847 //----------------------------------------------------------------------------------------------------------------------------------
2848 // Verify PHY state stays CCA_BUSY and CCA-BUSY indication is reported if only the
2849 // per20bitmap parameter changes
2851 delay,
2853 this,
2854 "Reception of a 20 MHz signal that generates a per20bitmap parameter change when "
2855 "previous CCA indication reports BUSY for the primary channel");
2857 delay,
2858 {{-50.0, MicroSeconds(0), MicroSeconds(100), P80_CENTER_FREQUENCY, 80},
2859 {-60.0, MicroSeconds(50), MicroSeconds(200), S80_CENTER_FREQUENCY + 30, 20}},
2860 {},
2861 {
2862 {aCcaTime, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCCATime
2863 {MicroSeconds(100) - smallDelta,
2864 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2865 {MicroSeconds(100) + smallDelta,
2866 WifiPhyState::IDLE} // IDLE just after the transmission ends
2867 },
2868 {{aCcaTime,
2869 MicroSeconds(100),
2871 std::vector<Time>{MicroSeconds(100),
2872 MicroSeconds(100),
2873 MicroSeconds(100),
2874 MicroSeconds(100),
2875 MicroSeconds(0),
2876 MicroSeconds(0),
2877 MicroSeconds(0),
2878 MicroSeconds(0)}},
2879 {MicroSeconds(50) + aCcaTime, // notification upon reception of the second signal
2880 MicroSeconds(100),
2882 std::vector<Time>{MicroSeconds(50),
2883 MicroSeconds(50),
2884 MicroSeconds(50),
2885 MicroSeconds(50),
2886 MicroSeconds(0),
2887 MicroSeconds(0),
2888 MicroSeconds(0),
2889 MicroSeconds(200)}}});
2890 delay += Seconds(1.0);
2891 }
2892
2894}
2895
2896void
2898{
2899 m_frequency = 5180;
2900 m_channelWidth = 20;
2901 RunOne();
2902
2903 m_frequency = 5190;
2904 m_channelWidth = 40;
2905 RunOne();
2906
2907 m_frequency = 5210;
2908 m_channelWidth = 80;
2909 RunOne();
2910
2911 m_frequency = 5250;
2912 m_channelWidth = 160;
2913 RunOne();
2914
2916}
2917
2918void
2920{
2921 m_rxPhy->Dispose();
2922 m_rxPhy = nullptr;
2923 m_txPhy->Dispose();
2924 m_txPhy = nullptr;
2925 for (auto& signalGenerator : m_signalGenerators)
2926 {
2927 signalGenerator->Dispose();
2928 signalGenerator = nullptr;
2929 }
2930}
2931
2932/**
2933 * \ingroup wifi-test
2934 * \ingroup tests
2935 *
2936 * \brief Wi-Fi PHY CCA Test Suite
2937 */
2939{
2940 public:
2942};
2943
2945 : TestSuite("wifi-phy-cca", Type::UNIT)
2946{
2947 AddTestCase(new WifiPhyCcaThresholdsTest, TestCase::Duration::QUICK);
2948 AddTestCase(new WifiPhyCcaIndicationTest, TestCase::Duration::QUICK);
2949}
2950
2951static 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 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,...
void NotifyTxStart(Time duration, double txPowerDbm) override
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.
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.
void SendHeSuPpdu(double txPowerDbm, uint16_t frequency, uint16_t bandwidth)
Send an HE SU PPDU.
void StartSignal(Ptr< WaveformGenerator > signalGenerator, double txPowerDbm, uint16_t frequency, uint16_t bandwidth, Time duration)
Start to generate a signal.
void RunOne()
Run one function.
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.
uint16_t m_frequency
Operating frequency in MHz.
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.
uint16_t m_channelWidth
Operating channel width in MHz.
Wi-Fi PHY CCA Test Suite.
PHY CCA thresholds test.
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.
double m_CcaSensitivityDbm
The current CCA sensitivity threshold for signals that occupy the primary 20 MHz channel (in dBm)
Ptr< SpectrumWifiPhy > m_phy
The spectrum PHY.
Ptr< ObssPdAlgorithm > m_obssPdAlgorithm
The OBSS-PD algorithm.
Ptr< HtPpdu > CreateDummyHtPpdu(uint16_t bandwidth, const WifiPhyOperatingChannel &channel)
Create a HT PPDU.
Ptr< VhtPpdu > CreateDummyVhtPpdu(uint16_t bandwidth, const WifiPhyOperatingChannel &channel)
Create a VHT PPDU.
void VerifyCcaThreshold(const Ptr< PhyEntity > phy, const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType, double expectedCcaThresholdDbm)
Function to verify the CCA threshold that is being reported by a given PHY entity upon reception of a...
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 (in ...
void RunOne()
Run tests for given CCA attributes.
Ptr< VhtConfiguration > m_vhtConfiguration
The VHT configuration.
double m_CcaEdThresholdDbm
The current CCA-ED threshold for a 20 MHz subchannel (in dBm)
void DoRun() override
Implementation to actually run this TestCase.
Ptr< HePpdu > CreateDummyHePpdu(uint16_t bandwidth, const WifiPhyOperatingChannel &channel)
Create a HE PPDU.
Ptr< OfdmPpdu > CreateDummyNonHtPpdu(const WifiPhyOperatingChannel &channel)
Create a non-HT PPDU.
double m_obssPdLevel
The current OBSS-PD level (in dBm)
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
static WifiMode GetHtMcs0()
Return MCS 0 from HT MCS values.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:211
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:251
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:309
void Dispose()
Dispose of this Object.
Definition: object.cc:258
void SetObssPdLevel(double level)
virtual void ConnectWifiNetDevice(const Ptr< WifiNetDevice > device)
Connect the WifiNetDevice and setup eventual callbacks.
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6 Mbps.
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Ptr< T > Get() const
Definition: pointer.h:234
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
void SetDevice(const Ptr< WifiNetDevice > device) override
Sets the device this PHY is associated with.
void AddChannel(const Ptr< SpectrumChannel > channel, const FrequencyRange &freqRange=WHOLE_WIFI_SPECTRUM)
Attach a SpectrumChannel to use for a given frequency range.
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1406
std::tuple< double, double, double > SecondaryCcaSensitivityThresholds
Tuple identifying CCA sensitivity thresholds for secondary channels.
void SetSecondaryCcaSensitivityThresholds(const SecondaryCcaSensitivityThresholds &thresholds)
Sets the CCA sensitivity thresholds for PPDUs that do not occupy the primary channel.
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.
void SetVhtConfiguration(Ptr< VhtConfiguration > vhtConfiguration)
void SetStandard(WifiStandard standard)
Set the Wifi standard.
void SetPhy(const Ptr< WifiPhy > phy)
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition: wifi-phy.cc:651
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument.
Definition: wifi-phy.cc:1741
void SetCcaEdThreshold(double threshold)
Sets the CCA energy detection threshold (dBm).
Definition: wifi-phy.cc:499
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:660
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:982
void RegisterListener(const std::shared_ptr< WifiPhyListener > &listener)
Definition: wifi-phy.cc:468
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:1119
void SetCcaSensitivityThreshold(double threshold)
Sets the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:512
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:733
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:549
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:681
std::tuple< uint8_t, uint16_t, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:903
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1054
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:536
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: wifi-phy.cc:2258
receive notifications about PHY events.
Class that keeps track of all information about the current PHY operating channel.
static ConstIterator FindFirst(uint8_t number, uint16_t frequency, uint16_t width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first channel 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:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#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:145
#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:511
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1343
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1355
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
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.
Definition: wifi-phy-band.h:37
@ 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.
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:40
@ WIFI_MAC_QOSDATA
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
uint16_t centerFreq
center frequency to use in MHz
Time startTime
time at which transmission will be started
uint16_t bandwidth
bandwidth to use in MHz
double power
transmit power to use in dBm
structure that holds information to generate signals
uint16_t centerFreq
center frequency to use in MHz
double power
transmit power to use in dBm
uint16_t bandwidth
bandwidth to use in MHz
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
constexpr uint32_t P40_CENTER_FREQUENCY
constexpr uint32_t P20_CENTER_FREQUENCY
const Time aCcaTime
const std::map< uint16_t, Time > PpduDurations
constexpr uint32_t P160_CENTER_FREQUENCY
constexpr uint32_t P80_CENTER_FREQUENCY
constexpr uint32_t S40_CENTER_FREQUENCY
const Time smallDelta
constexpr uint32_t S80_CENTER_FREQUENCY
constexpr uint32_t S20_CENTER_FREQUENCY