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