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/eht-configuration.h"
11#include "ns3/eht-phy.h"
12#include "ns3/eht-ppdu.h"
13#include "ns3/he-ppdu.h"
14#include "ns3/ht-ppdu.h"
15#include "ns3/interference-helper.h"
16#include "ns3/log.h"
17#include "ns3/multi-model-spectrum-channel.h"
18#include "ns3/nist-error-rate-model.h"
19#include "ns3/non-communicating-net-device.h"
20#include "ns3/ofdm-ppdu.h"
21#include "ns3/pointer.h"
22#include "ns3/rng-seed-manager.h"
23#include "ns3/spectrum-wifi-helper.h"
24#include "ns3/spectrum-wifi-phy.h"
25#include "ns3/test.h"
26#include "ns3/threshold-preamble-detection-model.h"
27#include "ns3/vht-configuration.h"
28#include "ns3/vht-ppdu.h"
29#include "ns3/waveform-generator.h"
30#include "ns3/wifi-mac-header.h"
31#include "ns3/wifi-net-device.h"
32#include "ns3/wifi-phy-listener.h"
33#include "ns3/wifi-psdu.h"
34#include "ns3/wifi-spectrum-value-helper.h"
35#include "ns3/wifi-standards.h"
36#include "ns3/wifi-utils.h"
37
38#include <algorithm>
39#include <memory>
40#include <vector>
41
42using namespace ns3;
43
44NS_LOG_COMPONENT_DEFINE("WifiPhyCcaTest");
45
58// add small delta to be right after aCcaTime, since test checks are scheduled before wifi
59// events
61const std::map<MHz_u, Time> hePpduDurations = {
62 {20, NanoSeconds(1009600)},
63 {40, NanoSeconds(533600)},
64 {80, NanoSeconds(275200)},
65};
66const std::map<MHz_u, Time> ehtPpduDurations = {
67 {20, NanoSeconds(1017600)},
68 {40, NanoSeconds(541600)},
69 {80, NanoSeconds(287200)},
70 {160, NanoSeconds(178400)},
71};
72
73/**
74 * @ingroup wifi-test
75 * @ingroup tests
76 *
77 * @brief PHY CCA thresholds test
78 */
80{
81 public:
83
84 private:
85 void DoSetup() override;
86 void DoTeardown() override;
87 void DoRun() override;
88
89 /**
90 * Run tests for given CCA attributes
91 */
92 void RunOne();
93
94 /**
95 * Create a dummy PSDU whose payload is 1000 bytes
96 * @return a dummy PSDU whose payload is 1000 bytes
97 */
99 /**
100 * Create a non-HT PPDU
101 * @param channel the operating channel of the PHY used for the transmission
102 * @return a non-HT PPDU
103 */
105 /**
106 * Create a HT PPDU
107 * @param bandwidth the bandwidth used for the transmission the PPDU
108 * @param channel the operating channel of the PHY used for the transmission
109 * @return a HT PPDU
110 */
112 /**
113 * Create a VHT PPDU
114 * @param bandwidth the bandwidth used for the transmission the PPDU
115 * @param channel the operating channel of the PHY used for the transmission
116 * @return a VHT PPDU
117 */
119 /**
120 * Create a HE PPDU
121 * @param bandwidth the bandwidth used for the transmission the PPDU
122 * @param channel the operating channel of the PHY used for the transmission
123 * @return a HE PPDU
124 */
126 /**
127 * Create a EHT PPDU
128 * @param bandwidth the bandwidth used for the transmission the PPDU
129 * @param channel the operating channel of the PHY used for the transmission
130 * @return a EHT PPDU
131 */
133
134 /**
135 * Function to verify the CCA threshold that is being reported by a given PHY entity upon
136 * reception of a signal or a PPDU
137 * @param phy the PHY entity to verify
138 * @param ppdu the incoming PPDU or signal (if nullptr)
139 * @param channelType the channel list type that indicates which channel the PPDU or the
140 * signal occupies
141 * @param expectedCcaThreshold the CCA threshold that is expected to be reported
142 */
143 void VerifyCcaThreshold(const std::shared_ptr<PhyEntity> phy,
144 const Ptr<const WifiPpdu> ppdu,
145 WifiChannelListType channelType,
146 dBm_u expectedCcaThreshold);
147
148 Ptr<WifiNetDevice> m_device; ///< The WifiNetDevice
149 Ptr<SpectrumWifiPhy> m_phy; ///< The spectrum PHY
150 Ptr<ObssPdAlgorithm> m_obssPdAlgorithm; ///< The OBSS-PD algorithm
151 Ptr<VhtConfiguration> m_vhtConfiguration; ///< The VHT configuration
152 Ptr<EhtConfiguration> m_ehtConfiguration; ///< The EHT configuration
153
154 dBm_u m_CcaEdThreshold; ///< The current CCA-ED threshold for a 20 MHz subchannel
155 dBm_u m_CcaSensitivity; ///< The current CCA sensitivity threshold for signals that occupy
156 ///< the primary 20 MHz channel
157
159 m_secondaryCcaSensitivityThresholds; ///< The current CCA sensitivity thresholds for
160 ///< signals that do not occupy the primary 20 MHz
161 ///< channel
162
163 dBm_u m_obssPdLevel; ///< The current OBSS-PD level
164 dBm_u m_per20CcaSensitivity; ///< The current CCA sensitivity threshold for Per 20MHz check
165};
166
168 : TestCase("Wi-Fi PHY CCA thresholds test"),
169 m_CcaEdThreshold{-62.0},
170 m_CcaSensitivity{-82.0},
172 m_obssPdLevel{-82.0},
174{
175}
176
179{
180 Ptr<Packet> pkt = Create<Packet>(1000);
181 WifiMacHeader hdr;
183 hdr.SetQosTid(0);
184 return Create<WifiPsdu>(pkt, hdr);
185}
186
189{
193 NanoSeconds(800),
194 1,
195 1,
196 0,
197 MHz_u{20},
198 false);
200 return Create<OfdmPpdu>(psdu, txVector, channel, 0);
201}
202
205{
209 NanoSeconds(800),
210 1,
211 1,
212 0,
213 bandwidth,
214 false);
216 return Create<HtPpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
217}
218
221 const WifiPhyOperatingChannel& channel)
222{
226 NanoSeconds(800),
227 1,
228 1,
229 0,
230 bandwidth,
231 false);
233 return Create<VhtPpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
234}
235
238{
242 NanoSeconds(800),
243 1,
244 1,
245 0,
246 bandwidth,
247 false);
249 return Create<HePpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
250}
251
254 const WifiPhyOperatingChannel& channel)
255{
259 NanoSeconds(800),
260 1,
261 1,
262 0,
263 bandwidth,
264 false};
265 WifiConstPsduMap psdus;
266 psdus.emplace(1, CreateDummyPsdu());
267 return Create<EhtPpdu>(psdus,
268 txVector,
269 channel,
270 MicroSeconds(100),
271 0,
273}
274
275void
276WifiPhyCcaThresholdsTest::VerifyCcaThreshold(const std::shared_ptr<PhyEntity> phy,
277 const Ptr<const WifiPpdu> ppdu,
278 WifiChannelListType channelType,
279 dBm_u expectedCcaThreshold)
280{
281 NS_LOG_FUNCTION(this << phy << channelType << expectedCcaThreshold);
282 const auto actualThreshold = phy->GetCcaThreshold(ppdu, channelType);
283 NS_LOG_INFO((ppdu == nullptr ? "any signal" : "a PPDU")
284 << " in " << channelType << " channel: " << actualThreshold << "dBm");
285 NS_TEST_EXPECT_MSG_EQ_TOL(actualThreshold,
286 expectedCcaThreshold,
287 dB_u{1e-6},
288 "Actual CCA threshold for "
289 << (ppdu == nullptr ? "any signal" : "a PPDU") << " in "
290 << channelType << " channel " << actualThreshold
291 << "dBm does not match expected threshold "
292 << expectedCcaThreshold << "dBm");
293}
294
295void
297{
298 // WifiHelper::EnableLogComponents ();
299 // LogComponentEnable ("WifiPhyCcaTest", LOG_LEVEL_ALL);
300
302 m_device->SetStandard(WIFI_STANDARD_80211be);
304 m_device->SetVhtConfiguration(m_vhtConfiguration);
306 m_device->SetEhtConfiguration(m_ehtConfiguration);
307
309 m_phy->SetDevice(m_device);
310 m_device->SetPhy(m_phy);
311 m_phy->SetInterferenceHelper(CreateObject<InterferenceHelper>());
313
314 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
315 MHz_u{0},
316 MHz_u{320},
319 ->number;
320 m_phy->SetOperatingChannel(WifiPhy::ChannelTuple{channelNum, 320, WIFI_PHY_BAND_6GHZ, 0});
321 m_phy->ConfigureStandard(WIFI_STANDARD_80211be);
322
324 m_device->AggregateObject(m_obssPdAlgorithm);
325 m_obssPdAlgorithm->ConnectWifiNetDevice(m_device);
326}
327
328void
330{
331 m_device->Dispose();
332 m_device = nullptr;
333}
334
335void
337{
338 m_phy->SetCcaEdThreshold(m_CcaEdThreshold);
339 m_phy->SetCcaSensitivityThreshold(m_CcaSensitivity);
340 m_vhtConfiguration->SetSecondaryCcaSensitivityThresholds(m_secondaryCcaSensitivityThresholds);
341 m_obssPdAlgorithm->SetObssPdLevel(m_obssPdLevel);
342 m_ehtConfiguration->m_per20CcaSensitivityThreshold = m_per20CcaSensitivity;
343
344 // OFDM PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
346 nullptr,
349
350 //-----------------------------------------------------------------------------------------------------------------------------------
351
352 // OFDM PHY: 20 MHz non-HT PPDU in primary channel (20 MHz) if power above CCA sensitivity
353 // threshold
355 CreateDummyNonHtPpdu(m_phy->GetOperatingChannel()),
358
359 //-----------------------------------------------------------------------------------------------------------------------------------
360
361 // HT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
363 nullptr,
366
367 // HT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
369 nullptr,
372
373 //-----------------------------------------------------------------------------------------------------------------------------------
374
375 // HT PHY: 20 MHz HT PPDU in primary channel (20 MHz) if power in primary above CCA
376 // sensitivity threshold
378 CreateDummyHtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
381
382 // HT PHY: 40 MHz HT PPDU in primary channel (20 MHz) if power in primary above CCA
383 // sensitivity threshold
385 CreateDummyHtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
388
389 //-----------------------------------------------------------------------------------------------------------------------------------
390
391 // VHT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
393 nullptr,
396
397 // VHT PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
399 nullptr,
402
403 // VHT PHY: any signal in secondary40 channel (40 MHz) if power above CCA-ED threshold + 3dB
405 nullptr,
407 m_CcaEdThreshold + dB_u{3.0});
408
409 // VHT PHY: any signal in secondary80 channel (80 MHz) if power above CCA-ED threshold + 6dB
411 nullptr,
413 m_CcaEdThreshold + dB_u{6.0});
414
415 //-----------------------------------------------------------------------------------------------------------------------------------
416
417 // VHT PHY: 20 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
418 // sensitivity threshold
420 CreateDummyVhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
423
424 // VHT PHY: 40 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
425 // sensitivity threshold
427 CreateDummyVhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
430
431 // VHT PHY: 80 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
432 // sensitivity threshold
434 CreateDummyVhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
437
438 // VHT PHY: 160 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
439 // sensitivity threshold
441 CreateDummyVhtPpdu(MHz_u{160}, m_phy->GetOperatingChannel()),
444
445 //-----------------------------------------------------------------------------------------------------------------------------------
446
447 // VHT PHY: 20 MHz VHT PPDU in secondary channel (20 MHz) if power above the CCA sensitivity
448 // threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
450 CreateDummyVhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
453
454 // VHT PHY: 20 MHz VHT PPDU in secondary40 channel (40 MHz) if power above the CCA
455 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20
456 // MHz
458 CreateDummyVhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
461
462 // VHT PHY: 40 MHz VHT PPDU in secondary40 channel (40 MHz) if power above the CCA
463 // sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20
464 // MHz
466 CreateDummyVhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
469
470 // VHT PHY: 20 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA
471 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20
472 // MHz
474 CreateDummyVhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
477
478 // VHT PHY: 40 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA
479 // sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20
480 // MHz
482 CreateDummyVhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
485
486 // VHT PHY: 80 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA
487 // sensitivity threshold corresponding to a 80 MHz PPDU that does not occupy the primary 20
488 // MHz
490 CreateDummyVhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
493
494 //-----------------------------------------------------------------------------------------------------------------------------------
495
496 // HE PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
498 nullptr,
501
502 // HE PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
504 nullptr,
507
508 // HE PHY: any signal in secondary40 channel (40 MHz) if power above CCA-ED threshold + 3dB
510 nullptr,
512 m_CcaEdThreshold + dB_u{3.0});
513
514 // HE PHY: any signal in secondary80 channel (80 MHz) if power above CCA-ED threshold + 6dB
516 nullptr,
518 m_CcaEdThreshold + dB_u{6.0});
519
520 //-----------------------------------------------------------------------------------------------------------------------------------
521
522 // HE PHY: 20 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA
523 // sensitivity threshold
525 CreateDummyHePpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
528
529 // HE PHY: 40 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA
530 // sensitivity threshold
532 CreateDummyHePpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
535
536 // HE PHY: 80 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA
537 // sensitivity threshold
539 CreateDummyHePpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
542
543 // HE PHY: 160 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA
544 // sensitivity threshold
546 CreateDummyHePpdu(MHz_u{160}, m_phy->GetOperatingChannel()),
549
550 //-----------------------------------------------------------------------------------------------------------------------------------
551
552 // HE PHY: 20 MHz HE PPDU in secondary channel (20 MHz) if power above the max between the
553 // CCA sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary
554 // 20 MHz and the OBSS-PD level
556 CreateDummyHePpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
558 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
559
560 // HE PHY: 20 MHz HE PPDU in secondary40 channel (40 MHz) if power above the max between the
561 // CCA sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary
562 // 20 MHz and the OBSS-PD level
564 CreateDummyHePpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
566 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
567
568 // HE PHY: 40 MHz HE PPDU in secondary40 channel (40 MHz) if power above the max between the
569 // CCA sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary
570 // 20 MHz and the OBSS-PD level plus 3 dB
572 m_phy->GetPhyEntity(WIFI_MOD_CLASS_HE),
573 CreateDummyHePpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
575 std::max(m_obssPdLevel + dB_u{3.0}, std::get<1>(m_secondaryCcaSensitivityThresholds)));
576
577 // HE PHY: 20 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the
578 // CCA sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary
579 // 20 MHz and the OBSS-PD level
581 CreateDummyHePpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
583 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
584
585 // HE PHY: 40 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the
586 // CCA sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary
587 // 20 MHz and the OBSS-PD level plus 3 dB
589 m_phy->GetPhyEntity(WIFI_MOD_CLASS_HE),
590 CreateDummyHePpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
592 std::max(m_obssPdLevel + dB_u{3.0}, std::get<1>(m_secondaryCcaSensitivityThresholds)));
593
594 // HE PHY: 80 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the
595 // CCA sensitivity threshold corresponding to a 80 MHz PPDU that does not occupy the primary
596 // 20 MHz and the OBSS-PD level plus 6 dB
598 m_phy->GetPhyEntity(WIFI_MOD_CLASS_HE),
599 CreateDummyHePpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
601 std::max(m_obssPdLevel + dB_u{6.0}, std::get<2>(m_secondaryCcaSensitivityThresholds)));
602
603 //-----------------------------------------------------------------------------------------------------------------------------------
604
605 // EHT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
607 nullptr,
610
611 // EHT PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
613 nullptr,
616
617 // EHT PHY: any signal in secondary40 channel (40 MHz) if power in any 20 MHz subchannel
618 // above CCA-ED threshold
620 nullptr,
623
624 // EHT PHY: any signal in secondary80 channel (80 MHz) if power in any 20 MHz subchannel
625 // above CCA-ED threshold
627 nullptr,
630
631 // EHT PHY: any signal in secondary160 channel (160 MHz) if power in any 20 MHz subchannel
632 // above CCA-ED threshold
634 nullptr,
637
638 //-----------------------------------------------------------------------------------------------------------------------------------
639 // EHT PHY: 20 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
640 // sensitivity threshold
642 CreateDummyEhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
645 // EHT PHY: 40 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
646 // sensitivity threshold
648 CreateDummyEhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
651
652 // EHT PHY: 80 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
653 // sensitivity threshold
655 CreateDummyEhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
658
659 // EHT PHY: 160 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
660 // sensitivity threshold
662 CreateDummyEhtPpdu(MHz_u{160}, m_phy->GetOperatingChannel()),
665
666 // EHT PHY: 320 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
667 // sensitivity threshold
669 CreateDummyEhtPpdu(MHz_u{320}, m_phy->GetOperatingChannel()),
672
673 //-----------------------------------------------------------------------------------------------------------------------------------
674
675 // EHT PHY: 20 MHz EHT PPDU in secondary channel (20 MHz) if power above the max between the
676 // CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
678 CreateDummyEhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
681
682 // EHT PHY: 20 MHz EHT PPDU in secondary40 channel (40 MHz) if power above the max between
683 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
685 CreateDummyEhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
688
689 // EHT PHY: 40 MHz EHT PPDU in secondary40 channel (40 MHz) if power above the max between
690 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
692 CreateDummyEhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
695
696 // EHT PHY: 20 MHz EHT PPDU in secondary80 channel (80 MHz) if power above the max between
697 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
699 CreateDummyEhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
702
703 // EHT PHY: 40 MHz EHT PPDU in secondary80 channel (80 MHz) if power above the max between
704 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
706 CreateDummyEhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
709
710 // EHT PHY: 80 MHz EHT PPDU in secondary80 channel (80 MHz) if power above the max between
711 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
713 CreateDummyEhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
716
717 // EHT PHY: 160 MHz EHT PPDU in secondary160 channel (160 MHz) if power above the max
718 // between the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
720 CreateDummyEhtPpdu(160, m_phy->GetOperatingChannel()),
723}
724
725void
727{
728 // default attributes
729 m_CcaEdThreshold = dBm_u{-62};
730 m_CcaSensitivity = dBm_u{-82};
731 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
732 m_obssPdLevel = dBm_u{-82};
734 RunOne();
735
736 // default attributes with OBSS-PD level set to -80 dBm
737 m_CcaEdThreshold = dBm_u{-62};
738 m_CcaSensitivity = dBm_u{-82};
739 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
740 m_obssPdLevel = dBm_u{-80};
742 RunOne();
743
744 // default attributes with OBSS-PD level set to -70 dBm
745 m_CcaEdThreshold = dBm_u{-62};
746 m_CcaSensitivity = dBm_u{-82};
747 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
748 m_obssPdLevel = dBm_u{-70};
750 RunOne();
751
752 // CCA-ED set to -65 dBm
753 m_CcaEdThreshold = dBm_u{-65};
754 m_CcaSensitivity = dBm_u{-82};
755 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
756 m_obssPdLevel = dBm_u{-82};
758 RunOne();
759
760 // CCA sensitivity for signals in primary set to -75 dBm
761 m_CcaEdThreshold = dBm_u{-62};
762 m_CcaSensitivity = dBm_u{-75};
763 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
764 m_obssPdLevel = dBm_u{-82};
766 RunOne();
767
768 // custom CCA sensitivities for signals not in primary
769 m_CcaEdThreshold = dBm_u{-62};
770 m_CcaSensitivity = dBm_u{-72};
771 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-70}, dBm_u{-70}, dBm_u{-70});
772 m_obssPdLevel = dBm_u{-82};
773 m_per20CcaSensitivity = -75.0;
774 RunOne();
775
776 // custom CCA sensitivities for signals not in primary with OBSS-PD level set to -80 dBm
777 m_CcaEdThreshold = dBm_u{-62};
778 m_CcaSensitivity = dBm_u{-72};
779 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-70}, dBm_u{-70}, dBm_u{-70});
780 m_obssPdLevel = dBm_u{-80};
781 m_per20CcaSensitivity = -69.0;
782 RunOne();
783
784 // custom CCA sensitivities for signals not in primary with OBSS-PD level set to -70 dBm
785 m_CcaEdThreshold = dBm_u{-62};
786 m_CcaSensitivity = dBm_u{-72};
787 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-70}, dBm_u{-70}, dBm_u{-70});
788 m_obssPdLevel = dBm_u{-70};
789 m_per20CcaSensitivity = -66.0;
790 RunOne();
791
793}
794
795/**
796 * @ingroup wifi-test
797 * @ingroup tests
798 *
799 * @brief PHY listener for CCA tests
800 */
802{
803 public:
805
806 void NotifyRxStart(Time duration) override
807 {
808 NS_LOG_FUNCTION(this << duration);
809 }
810
811 void NotifyRxEndOk() override
812 {
813 NS_LOG_FUNCTION(this);
814 }
815
816 void NotifyRxEndError(const WifiTxVector& txVector) override
817 {
818 NS_LOG_FUNCTION(this << txVector);
819 }
820
821 void NotifyTxStart(Time duration, dBm_u txPower) override
822 {
823 NS_LOG_FUNCTION(this << duration << txPower);
824 }
825
827 WifiChannelListType channelType,
828 const std::vector<Time>& per20MhzDurations) override
829 {
830 NS_LOG_FUNCTION(this << duration << channelType << per20MhzDurations.size());
831 m_endCcaBusy = Simulator::Now() + duration;
832 m_lastCcaBusyChannelType = channelType;
833 m_lastPer20MhzCcaBusyDurations = per20MhzDurations;
835 }
836
837 void NotifySwitchingStart(Time duration) override
838 {
839 }
840
841 void NotifySleep() override
842 {
843 }
844
845 void NotifyOff() override
846 {
847 }
848
849 void NotifyWakeup() override
850 {
851 }
852
853 void NotifyOn() override
854 {
855 }
856
857 /**
858 * Reset function
859 */
867
868 std::size_t m_notifications{0}; ///< Number of CCA notifications
869 Time m_endCcaBusy{Seconds(0)}; ///< End of the CCA-BUSY duration
871 WIFI_CHANLIST_PRIMARY}; ///< Channel type indication for the last CCA-BUSY notification
872 std::vector<Time>
873 m_lastPer20MhzCcaBusyDurations{}; ///< End of the CCA-BUSY durations per 20 MHz
874};
875
876/**
877 * @ingroup wifi-test
878 * @ingroup tests
879 *
880 * @brief Wifi Phy Threshold Test base class
881 */
883{
884 public:
885 /**
886 * Constructor
887 *
888 * @param standard the standard to use for the test
889 */
891
892 private:
893 void DoSetup() override;
894 void DoRun() override;
895 void DoTeardown() override;
896
897 /**
898 * Send a HE or EHT SU PPDU
899 * @param txPower the transmit power
900 * @param frequency the center frequency the transmitter is operating on
901 * @param bandwidth the bandwidth to use for the transmission
902 */
903 void SendSuPpdu(dBm_u txPower, MHz_u frequency, MHz_u bandwidth);
904
905 /**
906 * Start to generate a signal
907 * @param signalGenerator the signal generator to use
908 * @param txPower the transmit power
909 * @param frequency the center frequency of the signal to send
910 * @param bandwidth the bandwidth of the signal to send
911 * @param duration the duration of the signal
912 */
913 void StartSignal(Ptr<WaveformGenerator> signalGenerator,
914 dBm_u txPower,
915 MHz_u frequency,
916 MHz_u bandwidth,
917 Time duration);
918 /**
919 * Stop to generate a signal
920 * @param signalGenerator the signal generator to use
921 */
922 void StopSignal(Ptr<WaveformGenerator> signalGenerator);
923
924 /**
925 * Check the PHY state
926 * @param expectedState the expected state of the PHY
927 */
928 void CheckPhyState(WifiPhyState expectedState);
929 /// @copydoc CheckPhyState
930 void DoCheckPhyState(WifiPhyState expectedState);
931
932 /**
933 * Check the last CCA-BUSY notification
934 * @param expectedEndTime the expected CCA-BUSY end time
935 * @param expectedChannelType the expected channel type
936 * @param expectedPer20MhzDurations the expected per-20 MHz CCA-BUSY durations
937 */
938 void CheckLastCcaBusyNotification(Time expectedEndTime,
939 WifiChannelListType expectedChannelType,
940 const std::vector<Time>& expectedPer20MhzDurations);
941
942 /**
943 * Log scenario description
944 *
945 * @param log the scenario description to add to log
946 */
947 void LogScenario(const std::string& log) const;
948
949 /**
950 * structure that holds information to generate signals
951 */
953 {
954 dBm_u power{0.0}; //!< transmit power to use
955 Time startTime{Seconds(0)}; //!< time at which transmission will be started
956 Time duration{Seconds(0)}; //!< the duration of the transmission
957 MHz_u centerFreq{0}; //!< center frequency to use
958 MHz_u bandwidth{0}; //!< bandwidth to use
959 };
960
961 /**
962 * structure that holds information to generate PPDUs
963 */
965 {
966 dBm_u power{0.0}; //!< transmit power to use
967 Time startTime{Seconds(0)}; //!< time at which transmission will be started
968 MHz_u centerFreq{0}; //!< center frequency to use
969 MHz_u bandwidth{0}; //!< bandwidth to use
970 };
971
972 /**
973 * structure that holds information to perform PHY state check
974 */
976 {
977 Time timePoint{Seconds(0)}; //!< time at which the check will performed
979 };
980
981 /**
982 * structure that holds information to perform CCA check
983 */
985 {
986 Time timePoint{Seconds(0)}; //!< time at which the check will performed
987 Time expectedCcaEndTime{Seconds(0)}; //!< expected CCA_BUSY end time
990 std::vector<Time> expectedPer20MhzDurations{}; //!< expected per-20 MHz CCA duration
991 };
992
993 /**
994 * Schedule test to perform.
995 * @param delay the reference delay to schedule the events
996 * @param generatedSignals the vector of signals to be generated
997 * @param generatedPpdus the vector of PPDUs to be generated
998 * @param stateCheckpoints the vector of PHY state checks
999 * @param ccaCheckpoints the vector of PHY CCA checks
1000 */
1001 void ScheduleTest(Time delay,
1002 const std::vector<TxSignalInfo>& generatedSignals,
1003 const std::vector<TxPpduInfo>& generatedPpdus,
1004 const std::vector<StateCheckPoint>& stateCheckpoints,
1005 const std::vector<CcaCheckPoint>& ccaCheckpoints);
1006
1007 /**
1008 * Reset function
1009 */
1010 void Reset();
1011
1012 /**
1013 * Reset the expected Per 20 MHz CCA durations
1014 */
1016
1017 /**
1018 * Run one function
1019 */
1020 void RunOne();
1021
1022 WifiStandard m_standard; ///< The standard to use for the test
1023
1024 Ptr<SpectrumWifiPhy> m_rxPhy; ///< PHY object of the receiver
1025 Ptr<SpectrumWifiPhy> m_txPhy; ///< PHY object of the transmitter
1026
1027 std::vector<Ptr<WaveformGenerator>> m_signalGenerators; ///< Generators of non-wifi signals
1028 std::size_t m_numSignalGenerators; ///< The number of non-wifi signals generators needed for
1029 ///< the test
1030
1031 std::shared_ptr<CcaTestPhyListener>
1032 m_rxPhyStateListener; ///< Listener for PHY state transitions
1033
1034 MHz_u m_frequency; ///< Operating frequency
1035 MHz_u m_channelWidth; ///< Operating channel width
1036
1037 std::vector<std::vector<Time>>
1038 m_expectedPer20MhzCcaBusyDurations{}; ///< expected Per 20Mhz CCA durations per check
1039};
1040
1042 : TestCase("Wi-Fi PHY CCA indication test for " + ((standard == WIFI_STANDARD_80211ax)
1043 ? std::string("802.11ax")
1044 : std::string("802.11be"))),
1045 m_standard{standard},
1049{
1050}
1051
1052void
1054 dBm_u txPower,
1055 MHz_u frequency,
1056 MHz_u bandwidth,
1057 Time duration)
1058{
1059 NS_LOG_FUNCTION(this << signalGenerator << txPower << frequency << bandwidth << duration);
1060
1061 BandInfo bandInfo;
1062 bandInfo.fc = MHzToHz(frequency);
1063 bandInfo.fl = bandInfo.fc - MHzToHz(bandwidth / 2);
1064 bandInfo.fh = bandInfo.fc + MHzToHz(bandwidth / 2);
1065 Bands bands;
1066 bands.push_back(bandInfo);
1067
1068 Ptr<SpectrumModel> spectrumSignal = Create<SpectrumModel>(bands);
1069 Ptr<SpectrumValue> signalPsd = Create<SpectrumValue>(spectrumSignal);
1070 *signalPsd = DbmToW(txPower) / MHzToHz(bandwidth);
1071
1072 signalGenerator->SetTxPowerSpectralDensity(signalPsd);
1073 signalGenerator->SetPeriod(duration);
1074 signalGenerator->Start();
1075 Simulator::Schedule(duration, &WifiPhyCcaIndicationTest::StopSignal, this, signalGenerator);
1076}
1077
1078void
1080{
1081 NS_LOG_FUNCTION(this << signalGenerator);
1082 signalGenerator->Stop();
1083}
1084
1085void
1087{
1088 NS_LOG_FUNCTION(this << txPower);
1089
1090 auto channelNum =
1092 ->number;
1093 m_txPhy->SetOperatingChannel(
1094 WifiPhy::ChannelTuple{channelNum, bandwidth, WIFI_PHY_BAND_6GHZ, 0});
1095
1096 const auto mcs =
1098 const auto preamble =
1101 txVector{mcs, WIFI_MIN_TX_PWR_LEVEL, preamble, NanoSeconds(800), 1, 1, 0, bandwidth, false};
1102 Ptr<Packet> pkt = Create<Packet>(1000);
1103 WifiMacHeader hdr;
1105 hdr.SetQosTid(0);
1106 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
1107
1108 m_txPhy->SetTxPowerStart(txPower);
1109 m_txPhy->SetTxPowerEnd(txPower);
1110
1111 m_txPhy->Send(psdu, txVector);
1112}
1113
1114void
1116{
1117 // This is needed to make sure PHY state will be checked as the last event if a state change
1118 // occurred at the exact same time as the check
1120}
1121
1122void
1124{
1125 WifiPhyState currentState;
1126 PointerValue ptr;
1127 m_rxPhy->GetAttribute("State", ptr);
1129 currentState = state->GetState();
1130 NS_TEST_ASSERT_MSG_EQ(currentState,
1131 expectedState,
1132 "PHY State " << currentState << " does not match expected state "
1133 << expectedState << " at " << Simulator::Now());
1134}
1135
1136void
1138 Time expectedEndTime,
1139 WifiChannelListType expectedChannelType,
1140 const std::vector<Time>& expectedPer20MhzDurations)
1141{
1143 expectedEndTime,
1144 "PHY CCA end time " << m_rxPhyStateListener->m_endCcaBusy
1145 << " does not match expected time " << expectedEndTime
1146 << " at " << Simulator::Now());
1147 NS_TEST_ASSERT_MSG_EQ(m_rxPhyStateListener->m_lastCcaBusyChannelType,
1148 expectedChannelType,
1149 "PHY CCA-BUSY for " << m_rxPhyStateListener->m_lastCcaBusyChannelType
1150 << " does not match expected channel type "
1151 << expectedChannelType << " at " << Simulator::Now());
1152 NS_TEST_ASSERT_MSG_EQ(m_rxPhyStateListener->m_lastPer20MhzCcaBusyDurations.size(),
1153 expectedPer20MhzDurations.size(),
1154 "PHY CCA-BUSY per-20 MHz durations does not match expected vector"
1155 << " at " << Simulator::Now());
1156 for (std::size_t i = 0; i < expectedPer20MhzDurations.size(); ++i)
1157 {
1158 NS_TEST_ASSERT_MSG_EQ(m_rxPhyStateListener->m_lastPer20MhzCcaBusyDurations.at(i),
1159 expectedPer20MhzDurations.at(i),
1160 "PHY CCA-BUSY per-20 MHz duration at index "
1161 << i << " does not match expected duration at "
1162 << Simulator::Now());
1163 }
1164}
1165
1166void
1167WifiPhyCcaIndicationTest::LogScenario(const std::string& log) const
1168{
1169 NS_LOG_INFO(log);
1170}
1171
1172void
1174 const std::vector<TxSignalInfo>& generatedSignals,
1175 const std::vector<TxPpduInfo>& generatedPpdus,
1176 const std::vector<StateCheckPoint>& stateCheckpoints,
1177 const std::vector<CcaCheckPoint>& ccaCheckpoints)
1178{
1179 for (const auto& generatedPpdu : generatedPpdus)
1180 {
1181 Simulator::Schedule(delay + generatedPpdu.startTime,
1183 this,
1184 generatedPpdu.power,
1185 generatedPpdu.centerFreq,
1186 generatedPpdu.bandwidth);
1187 }
1188
1189 std::size_t index = 0;
1190 for (const auto& generatedSignal : generatedSignals)
1191 {
1192 Simulator::Schedule(delay + generatedSignal.startTime,
1194 this,
1195 m_signalGenerators.at(index++),
1196 generatedSignal.power,
1197 generatedSignal.centerFreq,
1198 generatedSignal.bandwidth,
1199 generatedSignal.duration);
1200 }
1201
1202 for (const auto& checkpoint : ccaCheckpoints)
1203 {
1204 Simulator::Schedule(delay + checkpoint.timePoint,
1206 this,
1207 Simulator::Now() + delay + checkpoint.expectedCcaEndTime,
1208 checkpoint.expectedChannelListType,
1209 checkpoint.expectedPer20MhzDurations);
1210 }
1211
1212 for (const auto& checkpoint : stateCheckpoints)
1213 {
1214 Simulator::Schedule(delay + checkpoint.timePoint,
1216 this,
1217 checkpoint.expectedPhyState);
1218 }
1219
1221}
1222
1223void
1228
1229void
1231{
1233 switch (static_cast<uint16_t>(m_channelWidth))
1234 {
1235 case 20:
1236 default:
1237 // no Per-20 MHz CCA
1240 break;
1241 case 40:
1244 break;
1245 case 80:
1247 MicroSeconds(0),
1248 MicroSeconds(0),
1249 MicroSeconds(0),
1250 MicroSeconds(0),
1251 });
1253 MicroSeconds(0),
1254 MicroSeconds(0),
1255 MicroSeconds(0),
1256 MicroSeconds(0),
1257 });
1258 break;
1259 case 160:
1261 MicroSeconds(0),
1262 MicroSeconds(0),
1263 MicroSeconds(0),
1264 MicroSeconds(0),
1265 MicroSeconds(0),
1266 MicroSeconds(0),
1267 MicroSeconds(0),
1268 MicroSeconds(0),
1269 });
1271 MicroSeconds(0),
1272 MicroSeconds(0),
1273 MicroSeconds(0),
1274 MicroSeconds(0),
1275 MicroSeconds(0),
1276 MicroSeconds(0),
1277 MicroSeconds(0),
1278 MicroSeconds(0),
1279 });
1280 break;
1281 case 320:
1283 MicroSeconds(0),
1284 MicroSeconds(0),
1285 MicroSeconds(0),
1286 MicroSeconds(0),
1287 MicroSeconds(0),
1288 MicroSeconds(0),
1289 MicroSeconds(0),
1290 MicroSeconds(0),
1291 MicroSeconds(0),
1292 MicroSeconds(0),
1293 MicroSeconds(0),
1294 MicroSeconds(0),
1295 MicroSeconds(0),
1296 MicroSeconds(0),
1297 MicroSeconds(0),
1298 MicroSeconds(0),
1299 });
1301 MicroSeconds(0),
1302 MicroSeconds(0),
1303 MicroSeconds(0),
1304 MicroSeconds(0),
1305 MicroSeconds(0),
1306 MicroSeconds(0),
1307 MicroSeconds(0),
1308 MicroSeconds(0),
1309 MicroSeconds(0),
1310 MicroSeconds(0),
1311 MicroSeconds(0),
1312 MicroSeconds(0),
1313 MicroSeconds(0),
1314 MicroSeconds(0),
1315 MicroSeconds(0),
1316 MicroSeconds(0),
1317 });
1318 break;
1319 }
1320}
1321
1322void
1324{
1325 // WifiHelper::EnableLogComponents ();
1326 // LogComponentEnable ("WifiPhyCcaTest", LOG_LEVEL_ALL);
1327
1329
1330 Ptr<Node> rxNode = CreateObject<Node>();
1332 rxDev->SetStandard(m_standard);
1333 auto vhtConfiguration = CreateObject<VhtConfiguration>();
1334 rxDev->SetVhtConfiguration(vhtConfiguration);
1336 {
1337 auto ehtConfiguration = CreateObject<EhtConfiguration>();
1338 rxDev->SetEhtConfiguration(ehtConfiguration);
1339 }
1341 m_rxPhyStateListener = std::make_unique<CcaTestPhyListener>();
1342 m_rxPhy->RegisterListener(m_rxPhyStateListener);
1344 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
1346 m_rxPhy->SetErrorRateModel(rxErrorModel);
1347 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
1349 m_rxPhy->SetPreambleDetectionModel(preambleDetectionModel);
1350 m_rxPhy->AddChannel(spectrumChannel);
1351 m_rxPhy->ConfigureStandard(m_standard);
1352 m_rxPhy->SetDevice(rxDev);
1353 rxDev->SetPhy(m_rxPhy);
1354 rxNode->AddDevice(rxDev);
1355
1356 Ptr<Node> txNode = CreateObject<Node>();
1359 m_txPhy->SetAttribute("ChannelSwitchDelay", TimeValue(Seconds(0)));
1361 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
1363 m_txPhy->SetErrorRateModel(txErrorModel);
1364 m_txPhy->AddChannel(spectrumChannel);
1365 m_txPhy->ConfigureStandard(m_standard);
1366 m_txPhy->SetDevice(txDev);
1367 txDev->SetPhy(m_txPhy);
1368 txNode->AddDevice(txDev);
1369
1370 for (std::size_t i = 0; i < m_numSignalGenerators; ++i)
1371 {
1372 Ptr<Node> signalGeneratorNode = CreateObject<Node>();
1373 Ptr<NonCommunicatingNetDevice> signalGeneratorDev =
1376 signalGenerator->SetDevice(signalGeneratorDev);
1377 signalGenerator->SetChannel(spectrumChannel);
1378 signalGenerator->SetDutyCycle(1);
1379 signalGeneratorNode->AddDevice(signalGeneratorDev);
1380 m_signalGenerators.push_back(signalGenerator);
1381 }
1382}
1383
1384void
1386{
1389 int64_t streamNumber = 0;
1390 m_rxPhy->AssignStreams(streamNumber);
1391 m_txPhy->AssignStreams(streamNumber);
1392
1393 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
1396 m_standard,
1398 ->number;
1399
1400 m_rxPhy->SetOperatingChannel(
1402 m_txPhy->SetOperatingChannel(
1404
1405 const auto& ppduDurations =
1407
1408 Time delay;
1410 delay += Seconds(1);
1411
1413
1414 //----------------------------------------------------------------------------------------------------------------------------------
1415 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal below
1416 // the energy detection threshold occupies P20
1417 Simulator::Schedule(delay,
1419 this,
1420 "Reception of a signal that occupies P20 below ED threshold");
1422 delay,
1423 {{dBm_u{-65}, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
1424 {},
1425 {
1426 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1427 {MicroSeconds(100) - smallDelta,
1428 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1429 {MicroSeconds(100) + smallDelta,
1430 WifiPhyState::IDLE} // IDLE just after the transmission ends
1431 },
1432 {});
1433 delay += Seconds(1);
1434
1435 //----------------------------------------------------------------------------------------------------------------------------------
1436 // Verify PHY state is CCA-BUSY as long as a 20 MHz signal above the energy detection
1437 // threshold occupies P20
1438 Simulator::Schedule(delay,
1440 this,
1441 "Reception of signal that occupies P20 above ED threshold");
1442 if (m_channelWidth > 20)
1443 {
1445 }
1447 delay,
1448 {{dBm_u{-60.0}, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
1449 {},
1450 {
1451 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1452 {MicroSeconds(100) - smallDelta,
1453 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1454 {MicroSeconds(100) + smallDelta,
1455 WifiPhyState::IDLE} // IDLE just after the transmission ends
1456 },
1457 {{MicroSeconds(100) - smallDelta,
1458 MicroSeconds(100),
1461 delay += Seconds(1);
1463
1464 //----------------------------------------------------------------------------------------------------------------------------------
1465 // Verify PHY state is CCA-BUSY as long as the sum of 20 MHz signals occupying P20 is above
1466 // the energy detection threshold
1467 Simulator::Schedule(delay,
1469 this,
1470 "Reception of two 20 MHz signals that occupies P20 below ED threshold with "
1471 "sum above ED threshold");
1472 if (m_channelWidth > 20)
1473 {
1475 }
1476 ScheduleTest(delay,
1477 {{-64.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}},
1478 {-65.0, MicroSeconds(50), MicroSeconds(200), P20_CENTER_FREQUENCY, MHz_u{20}}},
1479 {},
1480 {
1482 WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1483 {MicroSeconds(100) - smallDelta,
1484 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1485 {MicroSeconds(100) + smallDelta,
1486 WifiPhyState::IDLE} // IDLE just after the transmission ends
1487 },
1488 {{MicroSeconds(100) - smallDelta,
1489 MicroSeconds(100),
1492 delay += Seconds(1);
1494
1495 //----------------------------------------------------------------------------------------------------------------------------------
1496 // Verify PHY state stays IDLE when a 20 MHz PPDU with received power below the
1497 // corresponding CCA sensitivity threshold occupies P20
1499 delay,
1501 this,
1502 "Reception of a 20 MHz PPDU that occupies P20 below CCA sensitivity threshold");
1503 ScheduleTest(delay,
1504 {},
1505 {{dBm_u{-85}, MicroSeconds(0), P20_CENTER_FREQUENCY, MHz_u{20}}},
1506 {
1507 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1508 {ppduDurations.at(MHz_u{20}) - smallDelta,
1509 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1510 {ppduDurations.at(MHz_u{20}) + smallDelta,
1511 WifiPhyState::IDLE} // IDLE just after the transmission ends
1512 },
1513 {});
1514 delay += Seconds(1);
1515
1516 //----------------------------------------------------------------------------------------------------------------------------------
1517 // Verify PHY state transitions to CCA-BUSY when an PPDU with received power above the CCA
1518 // sensitivity threshold occupies P20. The per20Bitmap should indicate idle on the primary
1519 // 20 MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1521 delay,
1523 this,
1524 "Reception of a 20 MHz PPDU that occupies P20 above CCA sensitivity threshold");
1526 delay,
1527 {},
1528 {{dBm_u{-80}, MicroSeconds(0), P20_CENTER_FREQUENCY, MHz_u{20}}},
1529 {
1530 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1531 {ppduDurations.at(MHz_u{20}) - smallDelta,
1532 WifiPhyState::RX}, // RX just before the transmission ends
1533 {ppduDurations.at(MHz_u{20}) + smallDelta,
1534 WifiPhyState::IDLE} // IDLE just after the transmission ends
1535 },
1537 MicroSeconds(16),
1540 delay += Seconds(1);
1541
1542 //----------------------------------------------------------------------------------------------------------------------------------
1543 // Verify PHY state stays IDLE when a 40 MHz PPDU with received power below the CCA
1544 // sensitivity threshold occupies P40
1546 delay,
1548 this,
1549 "Reception of a 40 MHz PPDU that occupies P20 below CCA sensitivity threshold");
1550 ScheduleTest(delay,
1551 {},
1552 {{dBm_u{-80}, MicroSeconds(0), P40_CENTER_FREQUENCY, MHz_u{40}}},
1553 {
1554 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1555 {ppduDurations.at(MHz_u{40}) - smallDelta,
1556 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1557 {ppduDurations.at(MHz_u{40}) + smallDelta,
1558 WifiPhyState::IDLE} // IDLE just after the transmission ends
1559 },
1560 {});
1561 delay += Seconds(1);
1562
1563 //----------------------------------------------------------------------------------------------------------------------------------
1564 // Verify PHY state transitions to CCA-BUSY when an PPDU with received power above the CCA
1565 // sensitivity threshold occupies P40. The per20Bitmap should indicate idle on the primary
1566 // 20 MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1568 delay,
1570 this,
1571 "Reception of a 40 MHz PPDU that occupies P40 above CCA sensitivity threshold");
1573 delay,
1574 {},
1575 {{dBm_u{-75}, MicroSeconds(0), P40_CENTER_FREQUENCY, MHz_u{40}}},
1576 {
1577 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1578 {ppduDurations.at(MHz_u{40}) - smallDelta,
1579 (m_channelWidth > MHz_u{20})
1581 : WifiPhyState::CCA_BUSY}, // RX or IDLE just before the transmission ends
1582 {ppduDurations.at(MHz_u{40}) + smallDelta,
1583 WifiPhyState::IDLE} // IDLE just after the transmission ends
1584 },
1586 MicroSeconds(16),
1589 delay += Seconds(1);
1590
1591 if (m_channelWidth > MHz_u{20})
1592 {
1593 //----------------------------------------------------------------------------------------------------------------------------------
1594 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a 20 MHz
1595 // signal below the energy detection threshold occupies S20
1596 Simulator::Schedule(delay,
1598 this,
1599 "Reception of a 20 MHz signal that occupies S20 below ED threshold");
1601 delay,
1602 {{dBm_u{-65}, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
1603 {},
1604 {
1605 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1606 {MicroSeconds(100) - smallDelta,
1607 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1608 {MicroSeconds(100) + smallDelta,
1609 WifiPhyState::IDLE} // IDLE just after the transmission ends
1610 },
1611 {});
1612 delay += Seconds(1);
1613
1614 //----------------------------------------------------------------------------------------------------------------------------------
1615 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz signal
1616 // above the energy detection threshold occupies S20
1617 Simulator::Schedule(delay,
1619 this,
1620 "Reception of a 20 MHz signal that occupies S20 above ED threshold");
1623 delay,
1624 {{dBm_u{-60}, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
1625 {},
1626 {
1627 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1628 {MicroSeconds(100) - smallDelta,
1629 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1630 {MicroSeconds(100) + smallDelta,
1631 WifiPhyState::IDLE} // IDLE just after the transmission ends
1632 },
1633 {{MicroSeconds(100) - smallDelta,
1634 MicroSeconds(100),
1637 delay += Seconds(1);
1639
1640 //----------------------------------------------------------------------------------------------------------------------------------
1641 // Verify PHY state is CCA-BUSY as long as a 40 MHz signal above the energy detection
1642 // threshold occupies P40
1643 Simulator::Schedule(delay,
1645 this,
1646 "Reception of a 40 MHz signal that occupies P40 above ED threshold");
1647 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 2, MicroSeconds(100));
1649 delay,
1650 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), P40_CENTER_FREQUENCY, MHz_u{40}}},
1651 {},
1652 {
1653 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1654 {MicroSeconds(100) - smallDelta,
1655 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1656 {MicroSeconds(100) + smallDelta,
1657 WifiPhyState::IDLE} // IDLE just after the transmission ends
1658 },
1659 {{MicroSeconds(100) - smallDelta,
1660 MicroSeconds(100),
1663 delay += Seconds(1);
1665
1666 //----------------------------------------------------------------------------------------------------------------------------------
1667 // Verify PHY notifies CCA-BUSY for the primary channel while the secondary channel was
1668 // already in CCA-BUSY state
1669 Simulator::Schedule(delay,
1671 this,
1672 "Reception of a signal that occupies S20 followed by the reception of "
1673 "another signal that occupies P20");
1678 delay,
1680 {dBm_u{-60}, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
1681 {},
1682 {
1684 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
1686 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
1687 // aCcaTimeWithDelta that followed the second
1688 // transmission
1689 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
1690 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1691 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
1692 WifiPhyState::IDLE} // IDLE just after the transmission ends
1693 },
1694 {{aCcaTimeWithDelta, // notification upon reception of the first signal
1695 MicroSeconds(100),
1698 {MicroSeconds(50) +
1699 aCcaTimeWithDelta, // notification upon reception of the second signal
1700 MicroSeconds(50) + MicroSeconds(100),
1703 delay += Seconds(1);
1705
1706 //----------------------------------------------------------------------------------------------------------------------------------
1707 // Verify PHY updates per-20 MHz CCA durations if a signal arrives on the secondary
1708 // channel while primary is CCA-BUSY
1709 Simulator::Schedule(delay,
1711 this,
1712 "Reception of a signal that occupies P20 followed by the reception of "
1713 "another signal that occupies S20");
1718 delay,
1720 {dBm_u{-60}, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
1721 {},
1722 {
1723 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1725 WifiPhyState::CCA_BUSY}, // state of primary is still CCA-BUSY after
1726 // aCcaTimeWithDelta that followed the second
1727 // transmission
1728 {MicroSeconds(100) - smallDelta,
1729 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the first transmission ends
1730 {MicroSeconds(100) + smallDelta,
1731 WifiPhyState::IDLE} // IDLE just after the first transmission ends
1732 },
1733 {{aCcaTimeWithDelta, // notification upon reception of the first signal
1734 MicroSeconds(100),
1737 {MicroSeconds(50) +
1738 aCcaTimeWithDelta, // notification upon reception of the second signal
1739 MicroSeconds(100),
1742 delay += Seconds(1);
1744
1745 //----------------------------------------------------------------------------------------------------------------------------------
1746 // Verify PHY state stays IDLE when a 20 MHz PPDU with received power below the CCA
1747 // sensitivity threshold occupies S40
1749 delay,
1751 this,
1752 "Reception of a 20 MHz PPDU that occupies S20 below CCA sensitivity threshold");
1753 ScheduleTest(delay,
1754 {},
1755 {{dBm_u{-75}, MicroSeconds(0), S20_CENTER_FREQUENCY, MHz_u{20}}},
1756 {
1757 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1758 {ppduDurations.at(MHz_u{20}) - smallDelta,
1759 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1760 {ppduDurations.at(MHz_u{20}) + smallDelta,
1761 WifiPhyState::IDLE} // IDLE just after the transmission ends
1762 },
1763 {});
1764 delay += Seconds(1);
1765
1766 //----------------------------------------------------------------------------------------------------------------------------------
1767 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz PPDU
1768 // with received power above the CCA sensitivity threshold occupies S20
1770 delay,
1772 this,
1773 "Reception of a 20 MHz PPDU that occupies S20 above CCA sensitivity threshold");
1774 m_expectedPer20MhzCcaBusyDurations.at(0).at(1) = ppduDurations.at(MHz_u{20});
1775 ScheduleTest(delay,
1776 {},
1777 {{dBm_u{-70}, MicroSeconds(0), S20_CENTER_FREQUENCY, MHz_u{20}}},
1778 {
1779 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1780 {ppduDurations.at(MHz_u{20}) - smallDelta,
1781 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1782 {ppduDurations.at(MHz_u{20}) + smallDelta,
1783 WifiPhyState::IDLE} // IDLE just after the transmission ends
1784 },
1786 ppduDurations.at(MHz_u{20}),
1789 delay += Seconds(1);
1791
1792 //----------------------------------------------------------------------------------------------------------------------------------
1793 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a
1794 // signal above the energy detection threshold occupies the S20 while a 40 MHz PPDU
1795 // below the CCA sensitivity threshold is received on P40.
1796 Simulator::Schedule(delay,
1798 this,
1799 "Reception of a 20 MHz signal that occupies S20 above ED threshold "
1800 "followed by a 40 "
1801 "MHz PPDU that occupies P40 below CCA sensitivity threshold");
1805 delay,
1806 {{dBm_u{-60},
1807 MicroSeconds(0),
1808 MicroSeconds(100),
1810 MHz_u{20}}}, // signal on S20 above threshold
1811 {{dBm_u{-80},
1812 MicroSeconds(50),
1814 MHz_u{40}}}, // PPDU on P40 below threshold
1815 {
1816 {MicroSeconds(50) + aCcaTimeWithDelta, WifiPhyState::IDLE}, // PHY state stays IDLE
1817 },
1818 {{MicroSeconds(50) - smallDelta,
1819 MicroSeconds(100),
1822 {MicroSeconds(100) - smallDelta,
1823 MicroSeconds(100),
1826 delay += Seconds(1);
1828 }
1829
1830 if (m_channelWidth > MHz_u{40})
1831 {
1832 //----------------------------------------------------------------------------------------------------------------------------------
1833 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal
1834 // below the energy detection threshold occupies S40
1835 Simulator::Schedule(delay,
1837 this,
1838 "Reception of a 20 MHz signal that occupies the first subchannel of "
1839 "S40 below ED threshold");
1840 ScheduleTest(delay,
1841 {{dBm_u{-65},
1842 MicroSeconds(0),
1843 MicroSeconds(100),
1845 MHz_u{20}}},
1846 {},
1847 {
1848 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1849 {MicroSeconds(100) - smallDelta,
1850 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1851 {MicroSeconds(100) + smallDelta,
1852 WifiPhyState::IDLE} // IDLE just after the transmission ends
1853 },
1854 {});
1855 delay += Seconds(1);
1856
1857 //----------------------------------------------------------------------------------------------------------------------------------
1858 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy
1859 // detection threshold occupies the first 20 MHz subchannel of the S40: 27.3.20.6.4: Any
1860 // signal within the secondary 40 MHz channel at or above a threshold of –59 dBm within
1861 // a period of aCcaTimeWithDelta after the signal arrives at the receiver’s antenna(s).
1862 Simulator::Schedule(delay,
1864 this,
1865 "Reception of a 20 MHz signal that occupies the first subchannel of "
1866 "S40 above ED threshold");
1868 ScheduleTest(delay,
1869 {{dBm_u{-55},
1870 MicroSeconds(0),
1871 MicroSeconds(100),
1873 MHz_u{20}}},
1874 {},
1875 {
1876 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1877 {MicroSeconds(100) - smallDelta,
1878 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1879 {MicroSeconds(100) + smallDelta,
1880 WifiPhyState::IDLE} // IDLE just after the transmission ends
1881 },
1882 {{MicroSeconds(100) - smallDelta,
1883 MicroSeconds(100),
1886 delay += Seconds(1);
1888
1889 //----------------------------------------------------------------------------------------------------------------------------------
1890 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection
1891 // threshold occupies the second 20 MHz subchannel of the S40
1892 Simulator::Schedule(delay,
1894 this,
1895 "Reception of a 20 MHz signal that occupies the second subchannel of "
1896 "S40 below ED threshold");
1897 ScheduleTest(delay,
1898 {{dBm_u{-65},
1899 MicroSeconds(0),
1900 MicroSeconds(100),
1902 MHz_u{20}}},
1903 {},
1904 {
1905 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1906 {MicroSeconds(100) - smallDelta,
1907 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1908 {MicroSeconds(100) + smallDelta,
1909 WifiPhyState::IDLE} // IDLE just after the transmission ends
1910 },
1911 {});
1912 delay += Seconds(1);
1913
1914 //----------------------------------------------------------------------------------------------------------------------------------
1915 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy
1916 // detection threshold occupies the second 20 MHz subchannel of the S40: 27.3.20.6.4:
1917 // Any signal within the secondary 40 MHz channel at or above a threshold of –59 dBm
1918 // within a period of aCcaTimeWithDelta after the signal arrives at the receiver's
1919 // antenna(s).
1920 Simulator::Schedule(delay,
1922 this,
1923 "Reception of a 20 MHz signal that occupies the second subchannel of "
1924 "S40 above ED threshold");
1926 ScheduleTest(delay,
1927 {{dBm_u{-55},
1928 MicroSeconds(0),
1929 MicroSeconds(100),
1931 MHz_u{20}}},
1932 {},
1933 {
1934 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1935 {MicroSeconds(100) - smallDelta,
1936 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1937 {MicroSeconds(100) + smallDelta,
1938 WifiPhyState::IDLE} // IDLE just after the transmission ends
1939 },
1940 {{MicroSeconds(100) - smallDelta,
1941 MicroSeconds(100),
1944 delay += Seconds(1);
1946
1947 //----------------------------------------------------------------------------------------------------------------------------------
1948 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection
1949 // threshold occupies S40
1950 Simulator::Schedule(delay,
1952 this,
1953 "Reception of a 40 MHz signal that occupies S40 below ED threshold");
1955 delay,
1956 {{dBm_u{-60}, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY, MHz_u{40}}},
1957 {},
1958 {
1959 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1960 {MicroSeconds(100) - smallDelta,
1961 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1962 {MicroSeconds(100) + smallDelta,
1963 WifiPhyState::IDLE} // IDLE just after the transmission ends
1964 },
1965 {});
1966 delay += Seconds(1);
1967
1968 //----------------------------------------------------------------------------------------------------------------------------------
1969 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy
1970 // detection threshold occupies S40: 27.3.20.6.4: Any signal within the secondary 40 MHz
1971 // channel at or above a threshold of –59 dBm within a period of aCcaTimeWithDelta after
1972 // the signal arrives at the receiver's antenna(s).
1973 Simulator::Schedule(delay,
1975 this,
1976 "Reception of a 20 MHz signal that occupies the second subchannel of "
1977 "S40 above ED threshold");
1978 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 2, 2, MicroSeconds(100));
1980 delay,
1981 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY, MHz_u{40}}},
1982 {},
1983 {
1984 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1985 {MicroSeconds(100) - smallDelta,
1986 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1987 {MicroSeconds(100) + smallDelta,
1988 WifiPhyState::IDLE} // IDLE just after the transmission ends
1989 },
1990 {{MicroSeconds(100) - smallDelta,
1991 MicroSeconds(100),
1994 delay += Seconds(1);
1996
1997 //----------------------------------------------------------------------------------------------------------------------------------
1998 // Verify PHY state is CCA-BUSY as long as a 80 MHz signal above the energy detection
1999 // threshold occupies P80
2000 Simulator::Schedule(delay,
2002 this,
2003 "Reception of a 80 MHz signal that occupies P80 above ED threshold");
2004 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 4, MicroSeconds(100));
2006 delay,
2007 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), P80_CENTER_FREQUENCY, MHz_u{80}}},
2008 {},
2009 {
2010 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
2011 {MicroSeconds(100) - smallDelta,
2012 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2013 {MicroSeconds(100) + smallDelta,
2014 WifiPhyState::IDLE} // IDLE just after the transmission ends
2015 },
2016 {{MicroSeconds(100) - smallDelta,
2017 MicroSeconds(100),
2020 delay += Seconds(1);
2022
2023 //----------------------------------------------------------------------------------------------------------------------------------
2024 // Verify PHY notifies CCA-BUSY for the P20 channel while the S40 channel was already in
2025 // CCA-BUSY state
2026 Simulator::Schedule(delay,
2028 this,
2029 "Reception of a 20 MHz signal that occupies S40 followed by the "
2030 "reception of another 20 MHz signal that occupies P20");
2035 delay,
2036 {{dBm_u{-55},
2037 MicroSeconds(0),
2038 MicroSeconds(100),
2040 MHz_u{20}},
2041 {dBm_u{-55}, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
2042 {},
2043 {
2045 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2047 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
2048 // aCcaTimeWithDelta that followed the second
2049 // transmission
2050 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2051 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2052 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2053 WifiPhyState::IDLE} // IDLE just after the transmission ends
2054 },
2055 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2056 MicroSeconds(100),
2059 {MicroSeconds(50) +
2060 aCcaTimeWithDelta, // notification upon reception of the second signal
2061 MicroSeconds(50) + MicroSeconds(100),
2064 delay += Seconds(1);
2066
2067 //----------------------------------------------------------------------------------------------------------------------------------
2068 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S40
2069 // channel was already in CCA-BUSY state
2070 Simulator::Schedule(delay,
2072 this,
2073 "Reception of a signal that occupies S40 followed by the reception of "
2074 "another signal that occupies S20");
2079 delay,
2080 {{dBm_u{-55},
2081 MicroSeconds(0),
2082 MicroSeconds(100),
2084 MHz_u{20}},
2085 {dBm_u{-55}, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
2086 {},
2087 {
2089 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2091 WifiPhyState::IDLE}, // state of primary stays IDLE
2092 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2093 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2094 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2095 WifiPhyState::IDLE} // IDLE just after the transmission ends
2096 },
2097 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2098 MicroSeconds(100),
2101 {MicroSeconds(50) +
2102 aCcaTimeWithDelta, // notification upon reception of the second signal
2103 MicroSeconds(50) + MicroSeconds(100),
2106 delay += Seconds(1);
2108
2109 //----------------------------------------------------------------------------------------------------------------------------------
2110 // Verify PHY state stays IDLE when a 40 MHz PPDU with received power below the CCA
2111 // sensitivity threshold occupies S40
2113 delay,
2115 this,
2116 "Reception of a 40 MHz PPDU that occupies S40 below CCA sensitivity threshold");
2117 ScheduleTest(delay,
2118 {},
2119 {{dBm_u{-75}, MicroSeconds(0), S40_CENTER_FREQUENCY, MHz_u{40}}},
2120 {
2121 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2122 {ppduDurations.at(MHz_u{40}) - smallDelta,
2123 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2124 {ppduDurations.at(MHz_u{40}) + smallDelta,
2125 WifiPhyState::IDLE} // IDLE just after the transmission ends
2126 },
2127 {});
2128 delay += Seconds(1);
2129
2130 //----------------------------------------------------------------------------------------------------------------------------------
2131 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 40 MHz PPDU
2132 // with received power above the CCA sensitivity threshold occupies S40
2133 const dBm_u rxPower{(m_standard == WIFI_STANDARD_80211ax) ? -70.0 : -67.0};
2135 delay,
2137 this,
2138 "Reception of a 40 MHz PPDU that occupies S40 above CCA sensitivity threshold");
2139 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 2,
2140 2,
2141 ppduDurations.at(MHz_u{40}));
2142 ScheduleTest(delay,
2143 {},
2144 {{rxPower, MicroSeconds(0), S40_CENTER_FREQUENCY, MHz_u{40}}},
2145 {
2146 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2147 {ppduDurations.at(MHz_u{40}) - smallDelta,
2148 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2149 {ppduDurations.at(MHz_u{40}) + smallDelta,
2150 WifiPhyState::IDLE} // IDLE just after the transmission ends
2151 },
2153 ppduDurations.at(MHz_u{40}),
2156 delay += Seconds(1);
2158
2159 //----------------------------------------------------------------------------------------------------------------------------------
2160 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a
2161 // signal above the energy detection threshold occupies the S40 while a 80 MHz PPDU
2162 // below the CCA sensitivity threshold is received on P80.
2163 Simulator::Schedule(delay,
2165 this,
2166 "Reception of a 40 MHz signal that occupies S40 above ED threshold "
2167 "followed by a 80 "
2168 "MHz PPDU that occupies P80 below CCA sensitivity threshold");
2169 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 2, 2, MicroSeconds(100));
2170 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(1).begin() + 2, 2, MicroSeconds(46));
2172 delay,
2173 {{dBm_u{-55},
2174 MicroSeconds(0),
2175 MicroSeconds(100),
2177 MHz_u{40}}}, // signal on S40 above threshold
2178 {{dBm_u{-80},
2179 MicroSeconds(50),
2181 MHz_u{80}}}, // PPDU on P80 below threshold
2182 {
2183 {MicroSeconds(50) + aCcaTimeWithDelta, WifiPhyState::IDLE}, // PHY state stays IDLE
2184 },
2185 {{MicroSeconds(50) - smallDelta,
2186 MicroSeconds(100),
2189 {MicroSeconds(100) - smallDelta,
2190 MicroSeconds(100),
2193 delay += Seconds(1);
2195 }
2196 else // 20 or 40 MHz receiver
2197 {
2198 //----------------------------------------------------------------------------------------------------------------------------------
2199 // Verify PHY notifies CCA-BUSY when a 80 MHz PPDU with received power above the CCA
2200 // sensitivity threshold occupies P40 The per20Bitmap should indicate idle for all
2201 // subchannels because received power is below -62 dBm (27.3.20.6.5).
2202 Simulator::Schedule(delay,
2204 this,
2205 "Reception of a 80 MHz PPDU that occupies the 40 MHz band above CCA "
2206 "sensitivity threshold");
2208 delay,
2209 {},
2210 {{dBm_u{-70}, MicroSeconds(0), P80_CENTER_FREQUENCY, MHz_u{80}}},
2211 {
2212 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCcaTimeWithDelta
2213 {ppduDurations.at(MHz_u{80}) - smallDelta,
2214 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2215 {ppduDurations.at(MHz_u{80}) + smallDelta,
2216 WifiPhyState::IDLE} // IDLE just after the transmission ends
2217 },
2219 MicroSeconds(16),
2222 {ppduDurations.at(MHz_u{80}) - smallDelta,
2223 ppduDurations.at(MHz_u{80}),
2226 delay += Seconds(1);
2228
2229 //----------------------------------------------------------------------------------------------------------------------------------
2230 // Verify PHY notifies CCA-BUSY when a 80 MHz PPDU with received power above the CCA
2231 // sensitivity threshold occupies P40 The per20Bitmap should indicate CCA_BUSY for all
2232 // subchannels because received power is above -62 dBm (27.3.20.6.5).
2233 Simulator::Schedule(delay,
2235 this,
2236 "Reception of a 80 MHz PPDU that occupies the 40 MHz band above CCA "
2237 "sensitivity threshold");
2238 if (m_channelWidth > 20)
2239 {
2240 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(),
2241 2,
2242 ppduDurations.at(80) - aCcaTime);
2243 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(1).begin(),
2244 2,
2245 ppduDurations.at(80) - phyHeaderDuration);
2246 }
2248 delay,
2249 {},
2250 {{dBm_u{-55}, MicroSeconds(0), P80_CENTER_FREQUENCY, MHz_u{80}}},
2251 {
2252 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCcaTimeWithDelta
2253 {ppduDurations.at(MHz_u{80}) - smallDelta,
2254 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2255 {ppduDurations.at(MHz_u{80}) + smallDelta,
2256 WifiPhyState::IDLE} // IDLE just after the transmission ends
2257 },
2259 MicroSeconds(16),
2262 {ppduDurations.at(MHz_u{80}) - smallDelta,
2263 ppduDurations.at(MHz_u{80}),
2266 delay += Seconds(1);
2268
2269 //----------------------------------------------------------------------------------------------------------------------------------
2270 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal not
2271 // occupying the operational channel is being received
2273 delay,
2275 this,
2276 "Reception of a 40 MHz PPDU that does not occupy the operational channel");
2277 ScheduleTest(delay,
2278 {},
2279 {{dBm_u{-50}, MicroSeconds(0), S40_CENTER_FREQUENCY, MHz_u{40}}},
2280 {
2281 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2282 {ppduDurations.at(MHz_u{20}) - smallDelta,
2283 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2284 {ppduDurations.at(MHz_u{20}) + smallDelta,
2285 WifiPhyState::IDLE} // IDLE just after the transmission ends
2286 },
2287 {});
2288 delay += Seconds(1);
2289 }
2290
2291 if (m_channelWidth > MHz_u{80})
2292 {
2293 //----------------------------------------------------------------------------------------------------------------------------------
2294 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2295 // the energy detection threshold occupies the first 20 MHz subchannel of the S80
2296 Simulator::Schedule(delay,
2298 this,
2299 "Reception of a 20 MHz signal that occupies the first subchannel of "
2300 "S80 below ED threshold");
2301 ScheduleTest(delay,
2302 {{dBm_u{-65},
2303 MicroSeconds(0),
2304 MicroSeconds(100),
2306 MHz_u{20}}},
2307 {},
2308 {
2309 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2310 {MicroSeconds(100) - smallDelta,
2311 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2312 {MicroSeconds(100) + smallDelta,
2313 WifiPhyState::IDLE} // IDLE just after the transmission ends
2314 },
2315 {});
2316 delay += Seconds(1);
2317
2318 //----------------------------------------------------------------------------------------------------------------------------------
2319 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2320 // energy detection threshold occupies the first 20 MHz subchannel of the
2321 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2322 Simulator::Schedule(delay,
2324 this,
2325 "Reception of a 20 MHz signal that occupies the first subchannel of "
2326 "S80 above ED threshold");
2328 ScheduleTest(delay,
2329 {{dBm_u{-55},
2330 MicroSeconds(0),
2331 MicroSeconds(100),
2333 MHz_u{20}}},
2334 {},
2335 {
2336 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2337 {MicroSeconds(100) - smallDelta,
2338 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2339 {MicroSeconds(100) + smallDelta,
2340 WifiPhyState::IDLE} // IDLE just after the transmission ends
2341 },
2342 {{MicroSeconds(100) - smallDelta,
2343 MicroSeconds(100),
2346 delay += Seconds(1);
2348
2349 //----------------------------------------------------------------------------------------------------------------------------------
2350 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2351 // the energy detection threshold occupies the second 20 MHz subchannel of the S80
2352 Simulator::Schedule(delay,
2354 this,
2355 "Reception of a 20 MHz signal that occupies the second subchannel of "
2356 "S80 below ED threshold");
2357 ScheduleTest(delay,
2358 {{dBm_u{-65},
2359 MicroSeconds(0),
2360 MicroSeconds(100),
2362 MHz_u{20}}},
2363 {},
2364 {
2365 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2366 {MicroSeconds(100) - smallDelta,
2367 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2368 {MicroSeconds(100) + smallDelta,
2369 WifiPhyState::IDLE} // IDLE just after the transmission ends
2370 },
2371 {});
2372 delay += Seconds(1);
2373
2374 //----------------------------------------------------------------------------------------------------------------------------------
2375 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2376 // energy detection threshold occupies the second 20 MHz subchannel of the
2377 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2378 Simulator::Schedule(delay,
2380 this,
2381 "Reception of a 20 MHz signal that occupies the second subchannel of "
2382 "S80 above ED threshold");
2384 ScheduleTest(delay,
2385 {{dBm_u{-55},
2386 MicroSeconds(0),
2387 MicroSeconds(100),
2389 MHz_u{20}}},
2390 {},
2391 {
2392 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2393 {MicroSeconds(100) - smallDelta,
2394 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2395 {MicroSeconds(100) + smallDelta,
2396 WifiPhyState::IDLE} // IDLE just after the transmission ends
2397 },
2398 {{MicroSeconds(100) - smallDelta,
2399 MicroSeconds(100),
2402 delay += Seconds(1);
2404
2405 //----------------------------------------------------------------------------------------------------------------------------------
2406 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2407 // the energy detection threshold occupies the third 20 MHz subchannel of the S80
2408 Simulator::Schedule(delay,
2410 this,
2411 "Reception of a 20 MHz signal that occupies the third subchannel of "
2412 "S80 below ED threshold");
2413 ScheduleTest(delay,
2414 {{dBm_u{-65},
2415 MicroSeconds(0),
2416 MicroSeconds(100),
2418 MHz_u{20}}},
2419 {},
2420 {
2421 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2422 {MicroSeconds(100) - smallDelta,
2423 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2424 {MicroSeconds(100) + smallDelta,
2425 WifiPhyState::IDLE} // IDLE just after the transmission ends
2426 },
2427 {});
2428 delay += Seconds(1);
2429
2430 //----------------------------------------------------------------------------------------------------------------------------------
2431 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2432 // energy detection threshold occupies the third 20 MHz subchannel of the
2433 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2434 Simulator::Schedule(delay,
2436 this,
2437 "Reception of a 20 MHz signal that occupies the third subchannel of "
2438 "S80 above ED threshold");
2440 ScheduleTest(delay,
2441 {{dBm_u{-55},
2442 MicroSeconds(0),
2443 MicroSeconds(100),
2445 MHz_u{20}}},
2446 {},
2447 {
2448 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2449 {MicroSeconds(100) - smallDelta,
2450 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2451 {MicroSeconds(100) + smallDelta,
2452 WifiPhyState::IDLE} // IDLE just after the transmission ends
2453 },
2454 {{MicroSeconds(100) - smallDelta,
2455 MicroSeconds(100),
2458 delay += Seconds(1);
2460
2461 //----------------------------------------------------------------------------------------------------------------------------------
2462 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2463 // the energy detection threshold occupies the fourth 20 MHz subchannel of the S80
2464 Simulator::Schedule(delay,
2466 this,
2467 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
2468 "S80 below ED threshold");
2469 ScheduleTest(delay,
2470 {{dBm_u{-65},
2471 MicroSeconds(0),
2472 MicroSeconds(100),
2474 MHz_u{20}}},
2475 {},
2476 {
2477 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2478 {MicroSeconds(100) - smallDelta,
2479 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2480 {MicroSeconds(100) + smallDelta,
2481 WifiPhyState::IDLE} // IDLE just after the transmission ends
2482 },
2483 {});
2484 delay += Seconds(1);
2485
2486 //----------------------------------------------------------------------------------------------------------------------------------
2487 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2488 // energy detection threshold occupies the fourth 20 MHz subchannel of the
2489 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2490 Simulator::Schedule(delay,
2492 this,
2493 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
2494 "S80 above ED threshold");
2496 ScheduleTest(delay,
2497 {{dBm_u{-55},
2498 MicroSeconds(0),
2499 MicroSeconds(100),
2501 MHz_u{20}}},
2502 {},
2503 {
2504 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2505 {MicroSeconds(100) - smallDelta,
2506 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2507 {MicroSeconds(100) + smallDelta,
2508 WifiPhyState::IDLE} // IDLE just after the transmission ends
2509 },
2510 {{MicroSeconds(100) - smallDelta,
2511 MicroSeconds(100),
2514 delay += Seconds(1);
2516
2517 //----------------------------------------------------------------------------------------------------------------------------------
2518 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2519 // the energy detection threshold occupies the first and second 20 MHz subchannels of
2520 // the S80
2521 Simulator::Schedule(delay,
2523 this,
2524 "Reception of a 40 MHz signal that occupies the first and second "
2525 "subchannels of S80 below ED threshold");
2526 ScheduleTest(delay,
2527 {{dBm_u{-65},
2528 MicroSeconds(0),
2529 MicroSeconds(100),
2531 MHz_u{40}}},
2532 {},
2533 {
2534 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2535 {MicroSeconds(100) - smallDelta,
2536 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2537 {MicroSeconds(100) + smallDelta,
2538 WifiPhyState::IDLE} // IDLE just after the transmission ends
2539 },
2540 {});
2541 delay += Seconds(1);
2542
2543 //----------------------------------------------------------------------------------------------------------------------------------
2544 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2545 // energy detection threshold occupies the first and second 20 MHz subchannels of the
2546 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2547 Simulator::Schedule(delay,
2549 this,
2550 "Reception of a 40 MHz signal that occupies the first and second "
2551 "subchannels of S80 above ED threshold");
2552 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 4, 2, MicroSeconds(100));
2553 ScheduleTest(delay,
2554 {{dBm_u{-55},
2555 MicroSeconds(0),
2556 MicroSeconds(100),
2558 MHz_u{40}}},
2559 {},
2560 {
2561 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2562 {MicroSeconds(100) - smallDelta,
2563 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2564 {MicroSeconds(100) + smallDelta,
2565 WifiPhyState::IDLE} // IDLE just after the transmission ends
2566 },
2567 {{MicroSeconds(100) - smallDelta,
2568 MicroSeconds(100),
2571 delay += Seconds(1);
2573
2574 //----------------------------------------------------------------------------------------------------------------------------------
2575 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2576 // the energy detection threshold occupies the third and fourth 20 MHz subchannels of
2577 // 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 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
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
2603 // S80 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 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 6, 2, MicroSeconds(100));
2610 ScheduleTest(delay,
2611 {{dBm_u{-55},
2612 MicroSeconds(0),
2613 MicroSeconds(100),
2615 MHz_u{40}}},
2616 {},
2617 {
2618 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2619 {MicroSeconds(100) - smallDelta,
2620 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2621 {MicroSeconds(100) + smallDelta,
2622 WifiPhyState::IDLE} // IDLE just after the transmission ends
2623 },
2624 {{MicroSeconds(100) - smallDelta,
2625 MicroSeconds(100),
2628 delay += Seconds(1);
2630
2631 //----------------------------------------------------------------------------------------------------------------------------------
2632 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2633 // the energy detection threshold occupies the S80
2634 Simulator::Schedule(delay,
2636 this,
2637 "Reception of a 80 MHz signal that occupies S80 below ED threshold");
2639 delay,
2640 {{dBm_u{-65}, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY, MHz_u{80}}},
2641 {},
2642 {
2643 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2644 {MicroSeconds(100) - smallDelta,
2645 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2646 {MicroSeconds(100) + smallDelta,
2647 WifiPhyState::IDLE} // IDLE just after the transmission ends
2648 },
2649 {});
2650 delay += Seconds(1);
2651
2652 //----------------------------------------------------------------------------------------------------------------------------------
2653 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2654 // energy detection threshold occupies the S80 27.3.20.6.4: Any signal within the
2655 // secondary 80 MHz channel at or above –56 dBm.
2656 Simulator::Schedule(delay,
2658 this,
2659 "Reception of a 80 MHz signal that occupies S80 above ED threshold");
2660 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 4, 4, MicroSeconds(100));
2662 delay,
2663 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY, MHz_u{80}}},
2664 {},
2665 {
2666 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2667 {MicroSeconds(100) - smallDelta,
2668 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2669 {MicroSeconds(100) + smallDelta,
2670 WifiPhyState::IDLE} // IDLE just after the transmission ends
2671 },
2672 {{MicroSeconds(100) - smallDelta,
2673 MicroSeconds(100),
2676 delay += Seconds(1);
2678
2679 //----------------------------------------------------------------------------------------------------------------------------------
2680 // Verify PHY state stays IDLE as long as a 160 MHz signal below the energy detection
2681 // threshold occupies the whole band
2683 delay,
2685 this,
2686 "Reception of a 160 MHz signal that occupies the whole band below ED threshold");
2688 delay,
2689 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), P160_CENTER_FREQUENCY, MHz_u{160}}},
2690 {},
2691 {
2692 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2693 {MicroSeconds(100) - smallDelta,
2694 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2695 {MicroSeconds(100) + smallDelta,
2696 WifiPhyState::IDLE} // IDLE just after the transmission ends
2697 },
2698 {});
2699
2700 delay += Seconds(1);
2701
2702 //----------------------------------------------------------------------------------------------------------------------------------
2703 // Verify PHY state is CCA-BUSY as long as a 160 MHz signal above the energy detection
2704 // threshold occupies the whole band
2706 delay,
2708 this,
2709 "Reception of a 160 MHz signal that occupies the whole band above ED threshold");
2710 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 8, MicroSeconds(100));
2712 delay,
2713 {{dBm_u{-50}, MicroSeconds(0), MicroSeconds(100), P160_CENTER_FREQUENCY, MHz_u{160}}},
2714 {},
2715 {
2716 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
2717 {MicroSeconds(100) - smallDelta,
2718 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2719 {MicroSeconds(100) + smallDelta,
2720 WifiPhyState::IDLE} // IDLE just after the transmission ends
2721 },
2722 {{MicroSeconds(100) - smallDelta,
2723 MicroSeconds(100),
2726 delay += Seconds(1);
2728
2729 //----------------------------------------------------------------------------------------------------------------------------------
2730 // Verify PHY notifies CCA-BUSY for the P20 channel while the S80 channel was already in
2731 // CCA-BUSY state
2732 Simulator::Schedule(delay,
2734 this,
2735 "Reception of a 20 MHz signal that occupies S80 followed by the "
2736 "reception of another 20 MHz signal that occupies P20");
2741 delay,
2742 {{dBm_u{-55},
2743 MicroSeconds(0),
2744 MicroSeconds(100),
2746 MHz_u{20}},
2747 {dBm_u{-55}, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
2748 {},
2749 {
2751 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2753 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
2754 // aCcaTimeWithDelta that followed the second
2755 // transmission
2756 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2757 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2758 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2759 WifiPhyState::IDLE} // IDLE just after the transmission ends
2760 },
2761 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2762 MicroSeconds(100),
2765 {MicroSeconds(50) +
2766 aCcaTimeWithDelta, // notification upon reception of the second signal
2767 MicroSeconds(50) + MicroSeconds(100),
2770 delay += Seconds(1);
2772
2773 //----------------------------------------------------------------------------------------------------------------------------------
2774 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S40 channel while the S80
2775 // channel was already in CCA-BUSY state
2776 Simulator::Schedule(delay,
2778 this,
2779 "Reception of a signal that occupies S80 followed by the reception of "
2780 "another signal that occupies S40");
2785 delay,
2786 {{dBm_u{-55},
2787 MicroSeconds(0),
2788 MicroSeconds(100),
2790 MHz_u{20}},
2791 {dBm_u{-55},
2792 MicroSeconds(50),
2793 MicroSeconds(100),
2795 MHz_u{20}}},
2796 {},
2797 {
2799 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2801 WifiPhyState::IDLE}, // state of primary stays IDLE
2802 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2803 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2804 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2805 WifiPhyState::IDLE} // IDLE just after the transmission ends
2806 },
2807 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2808 MicroSeconds(100),
2811 {MicroSeconds(50) +
2812 aCcaTimeWithDelta, // notification upon reception of the second signal
2813 MicroSeconds(50) + MicroSeconds(100),
2816 delay += Seconds(1);
2818
2819 //----------------------------------------------------------------------------------------------------------------------------------
2820 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S80
2821 // channel was already in CCA-BUSY state
2822 Simulator::Schedule(delay,
2824 this,
2825 "Reception of a signal that occupies S80 followed by the reception of "
2826 "another signal that occupies S20");
2831 delay,
2832 {{dBm_u{-55},
2833 MicroSeconds(0),
2834 MicroSeconds(100),
2836 MHz_u{20}},
2837 {dBm_u{-55}, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
2838 {},
2839 {
2841 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2843 WifiPhyState::IDLE}, // state of primary stays IDLE
2844 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2845 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2846 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2847 WifiPhyState::IDLE} // IDLE just after the transmission ends
2848 },
2849 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2850 MicroSeconds(100),
2853 {MicroSeconds(50) +
2854 aCcaTimeWithDelta, // notification upon reception of the second signal
2855 MicroSeconds(50) + MicroSeconds(100),
2858 delay += Seconds(1);
2860
2861 //----------------------------------------------------------------------------------------------------------------------------------
2862 // Verify PHY state stays IDLE when a 80 MHz PPDU with received power below the CCA
2863 // sensitivity threshold occupies S80
2865 delay,
2867 this,
2868 "Reception of a 80 MHz PPDU that occupies S80 below CCA sensitivity threshold");
2869 ScheduleTest(delay,
2870 {},
2871 {{dBm_u{-70}, MicroSeconds(0), S80_CENTER_FREQUENCY, MHz_u{80}}},
2872 {
2873 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2874 {ppduDurations.at(MHz_u{80}) - smallDelta,
2875 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2876 {ppduDurations.at(MHz_u{80}) + smallDelta,
2877 WifiPhyState::IDLE} // IDLE just after the transmission ends
2878 },
2879 {});
2880 delay += Seconds(1);
2881
2882 //----------------------------------------------------------------------------------------------------------------------------------
2883 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 80 MHz PPDU
2884 // with received power above the CCA sensitivity threshold occupies S80
2886 delay,
2888 this,
2889 "Reception of a 80 MHz PPDU that occupies S80 above CCA sensitivity threshold");
2890 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 4, 4, ppduDurations.at(80));
2891 ScheduleTest(delay,
2892 {},
2893 {{dBm_u{-65}, MicroSeconds(0), S80_CENTER_FREQUENCY, MHz_u{80}}},
2894 {
2895 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2896 {ppduDurations.at(MHz_u{80}) - smallDelta,
2897 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2898 {ppduDurations.at(MHz_u{80}) + smallDelta,
2899 WifiPhyState::IDLE} // IDLE just after the transmission ends
2900 },
2902 ppduDurations.at(MHz_u{80}),
2905 delay += Seconds(1);
2907
2909 {
2910 //----------------------------------------------------------------------------------------------------------------------------------
2911 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if only the
2912 // per20bitmap parameter changes
2914 delay,
2916 this,
2917 "Reception of a 20 MHz signal that generates a per20bitmap parameter "
2918 "change when previous CCA indication reports IDLE");
2921 delay,
2922 {{dBm_u{-60.0},
2923 MicroSeconds(0),
2924 MicroSeconds(100),
2926 MHz_u{20}}},
2927 {},
2928 {
2929 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2930 {MicroSeconds(100) - smallDelta,
2931 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2932 {MicroSeconds(100) + smallDelta,
2933 WifiPhyState::IDLE} // IDLE just after the transmission ends
2934 },
2936 Seconds(0),
2939 delay += Seconds(1);
2941
2942 //----------------------------------------------------------------------------------------------------------------------------------
2943 // Verify PHY state stays CCA_BUSY and CCA-BUSY indication is reported if only the
2944 // per20bitmap parameter changes
2945 Simulator::Schedule(delay,
2947 this,
2948 "Reception of a 20 MHz signal that generates a per20bitmap "
2949 "parameter change when "
2950 "previous CCA indication reports BUSY for the primary channel");
2951 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 4, MicroSeconds(100));
2952 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(1).begin(), 4, MicroSeconds(50));
2955 delay,
2956 {{dBm_u{-50.0},
2957 MicroSeconds(0),
2958 MicroSeconds(100),
2960 MHz_u{80}},
2961 {dBm_u{-60.0},
2962 MicroSeconds(50),
2963 MicroSeconds(200),
2965 MHz_u{20}}},
2966 {},
2967 {
2968 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
2969 {MicroSeconds(100) - smallDelta,
2970 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2971 {MicroSeconds(100) + smallDelta,
2972 WifiPhyState::IDLE} // IDLE just after the transmission ends
2973 },
2975 MicroSeconds(100),
2978 {MicroSeconds(50) +
2979 aCcaTimeWithDelta, // notification upon reception of the second signal
2980 MicroSeconds(100),
2983 delay += Seconds(1);
2985 }
2986 }
2987
2988 if (m_channelWidth > 160)
2989 {
2990 //----------------------------------------------------------------------------------------------------------------------------------
2991 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2992 // the energy detection threshold occupies the first 20 MHz subchannel of the S160
2993 Simulator::Schedule(delay,
2995 this,
2996 "Reception of a 20 MHz signal that occupies the first subchannel of "
2997 "S160 below ED threshold");
2998 ScheduleTest(delay,
2999 {{-65.0,
3000 MicroSeconds(0),
3001 MicroSeconds(100),
3003 MHz_u{20}}},
3004 {},
3005 {
3006 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3007 {MicroSeconds(100) - smallDelta,
3008 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3009 {MicroSeconds(100) + smallDelta,
3010 WifiPhyState::IDLE} // IDLE just after the transmission ends
3011 },
3012 {});
3013 delay += Seconds(1.0);
3014
3015 //----------------------------------------------------------------------------------------------------------------------------------
3016 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3017 // energy detection threshold occupies the first 20 MHz subchannel of the S160.
3018 // 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at or above a
3019 // threshold of –62 dBm. (...)
3020 Simulator::Schedule(delay,
3022 this,
3023 "Reception of a 20 MHz signal that occupies the first subchannel of "
3024 "S160 above ED threshold");
3026 ScheduleTest(delay,
3027 {{-61.0,
3028 MicroSeconds(0),
3029 MicroSeconds(100),
3031 MHz_u{20}}},
3032 {},
3033 {
3034 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3035 {MicroSeconds(100) - smallDelta,
3036 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3037 {MicroSeconds(100) + smallDelta,
3038 WifiPhyState::IDLE} // IDLE just after the transmission ends
3039 },
3040 {{MicroSeconds(100) - smallDelta,
3041 MicroSeconds(100),
3044 delay += Seconds(1.0);
3046
3047 //----------------------------------------------------------------------------------------------------------------------------------
3048 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
3049 // the energy detection threshold occupies the second 20 MHz subchannel of the S80
3050 Simulator::Schedule(delay,
3052 this,
3053 "Reception of a 20 MHz signal that occupies the second subchannel of "
3054 "S160 below ED threshold");
3055 ScheduleTest(delay,
3056 {{-65.0,
3057 MicroSeconds(0),
3058 MicroSeconds(100),
3060 MHz_u{20}}},
3061 {},
3062 {
3063 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3064 {MicroSeconds(100) - smallDelta,
3065 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3066 {MicroSeconds(100) + smallDelta,
3067 WifiPhyState::IDLE} // IDLE just after the transmission ends
3068 },
3069 {});
3070 delay += Seconds(1.0);
3071
3072 //----------------------------------------------------------------------------------------------------------------------------------
3073 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3074 // energy detection threshold occupies the second 20 MHz subchannel of the
3075 // S160 27.3.20.6.4: 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at
3076 // or above a threshold of –62 dBm. (...)
3077 Simulator::Schedule(delay,
3079 this,
3080 "Reception of a 20 MHz signal that occupies the second subchannel of "
3081 "S160 above ED threshold");
3083 ScheduleTest(delay,
3084 {{-61.0,
3085 MicroSeconds(0),
3086 MicroSeconds(100),
3088 MHz_u{20}}},
3089 {},
3090 {
3091 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3092 {MicroSeconds(100) - smallDelta,
3093 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3094 {MicroSeconds(100) + smallDelta,
3095 WifiPhyState::IDLE} // IDLE just after the transmission ends
3096 },
3097 {{MicroSeconds(100) - smallDelta,
3098 MicroSeconds(100),
3101 delay += Seconds(1.0);
3103
3104 //----------------------------------------------------------------------------------------------------------------------------------
3105 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
3106 // the energy detection threshold occupies the third 20 MHz subchannel of the S80
3107 Simulator::Schedule(delay,
3109 this,
3110 "Reception of a 20 MHz signal that occupies the third subchannel of "
3111 "S160 below ED threshold");
3112 ScheduleTest(delay,
3113 {{-65.0,
3114 MicroSeconds(0),
3115 MicroSeconds(100),
3117 MHz_u{20}}},
3118 {},
3119 {
3120 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3121 {MicroSeconds(100) - smallDelta,
3122 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3123 {MicroSeconds(100) + smallDelta,
3124 WifiPhyState::IDLE} // IDLE just after the transmission ends
3125 },
3126 {});
3127 delay += Seconds(1.0);
3128
3129 //----------------------------------------------------------------------------------------------------------------------------------
3130 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3131 // energy detection threshold occupies the third 20 MHz subchannel of the
3132 // S160 27.3.20.6.4: 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at
3133 // or above a threshold of –62 dBm. (...)
3134 Simulator::Schedule(delay,
3136 this,
3137 "Reception of a 20 MHz signal that occupies the third subchannel of "
3138 "S160 above ED threshold");
3140 ScheduleTest(delay,
3141 {{-61.0,
3142 MicroSeconds(0),
3143 MicroSeconds(100),
3145 MHz_u{20}}},
3146 {},
3147 {
3148 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3149 {MicroSeconds(100) - smallDelta,
3150 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3151 {MicroSeconds(100) + smallDelta,
3152 WifiPhyState::IDLE} // IDLE just after the transmission ends
3153 },
3154 {{MicroSeconds(100) - smallDelta,
3155 MicroSeconds(100),
3158 delay += Seconds(1.0);
3160
3161 //----------------------------------------------------------------------------------------------------------------------------------
3162 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
3163 // the energy detection threshold occupies the fourth 20 MHz subchannel of the S80
3164 Simulator::Schedule(delay,
3166 this,
3167 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
3168 "S160 below ED threshold");
3169 ScheduleTest(delay,
3170 {{-65.0,
3171 MicroSeconds(0),
3172 MicroSeconds(100),
3174 MHz_u{20}}},
3175 {},
3176 {
3177 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3178 {MicroSeconds(100) - smallDelta,
3179 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3180 {MicroSeconds(100) + smallDelta,
3181 WifiPhyState::IDLE} // IDLE just after the transmission ends
3182 },
3183 {});
3184 delay += Seconds(1.0);
3185
3186 //----------------------------------------------------------------------------------------------------------------------------------
3187 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3188 // energy detection threshold occupies the fourth 20 MHz subchannel of the
3189 // S160 27.3.20.6.4: 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at
3190 // or above a threshold of –62 dBm. (...)
3191 Simulator::Schedule(delay,
3193 this,
3194 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
3195 "S160 above ED threshold");
3197 ScheduleTest(delay,
3198 {{-61.0,
3199 MicroSeconds(0),
3200 MicroSeconds(100),
3202 MHz_u{20}}},
3203 {},
3204 {
3205 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3206 {MicroSeconds(100) - smallDelta,
3207 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3208 {MicroSeconds(100) + smallDelta,
3209 WifiPhyState::IDLE} // IDLE just after the transmission ends
3210 },
3211 {{MicroSeconds(100) - smallDelta,
3212 MicroSeconds(100),
3215 delay += Seconds(1.0);
3217
3218 //----------------------------------------------------------------------------------------------------------------------------------
3219 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3220 // occupies the fifth and sixth 20 MHz subchannels of the S160 with received power below
3221 // the energy detection threshold for all occupied 20 MHz subchannels
3222 Simulator::Schedule(delay,
3224 this,
3225 "Reception of a 40 MHz signal that occupies the fifth and sixth "
3226 "subchannels of S160 below ED threshold");
3227 ScheduleTest(delay,
3228 {{-60.0,
3229 MicroSeconds(0),
3230 MicroSeconds(100),
3232 MHz_u{40}}},
3233 {},
3234 {
3235 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3236 {MicroSeconds(100) - smallDelta,
3237 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3238 {MicroSeconds(100) + smallDelta,
3239 WifiPhyState::IDLE} // IDLE just after the transmission ends
3240 },
3241 {});
3242 delay += Seconds(1.0);
3243
3244 //----------------------------------------------------------------------------------------------------------------------------------
3245 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3246 // occupies the fifth and sixth 20 MHz subchannels of the S160 with received power above
3247 // the energy detection threshold for any occupied 20 MHz subchannels
3248 Simulator::Schedule(delay,
3250 this,
3251 "Reception of a 40 MHz signal that occupies the fifth and sixth "
3252 "subchannels of S160 above ED threshold");
3253 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 12, 2, MicroSeconds(100));
3254 ScheduleTest(delay,
3255 {{-58.0,
3256 MicroSeconds(0),
3257 MicroSeconds(100),
3259 MHz_u{40}}},
3260 {},
3261 {
3262 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3263 {MicroSeconds(100) - smallDelta,
3264 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3265 {MicroSeconds(100) + smallDelta,
3266 WifiPhyState::IDLE} // IDLE just after the transmission ends
3267 },
3268 {{MicroSeconds(100) - smallDelta,
3269 MicroSeconds(100),
3272 delay += Seconds(1.0);
3274
3275 //----------------------------------------------------------------------------------------------------------------------------------
3276 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3277 // occupies the seventh and eighth 20 MHz subchannels of the S160 with received power
3278 // below the energy detection threshold for all occupied 20 MHz subchannels
3279 Simulator::Schedule(delay,
3281 this,
3282 "Reception of a 40 MHz signal that occupies the seventh and eighth "
3283 "subchannels of S160 below ED threshold");
3284 ScheduleTest(delay,
3285 {{-60.0,
3286 MicroSeconds(0),
3287 MicroSeconds(100),
3289 MHz_u{40}}},
3290 {},
3291 {
3292 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3293 {MicroSeconds(100) - smallDelta,
3294 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3295 {MicroSeconds(100) + smallDelta,
3296 WifiPhyState::IDLE} // IDLE just after the transmission ends
3297 },
3298 {});
3299 delay += Seconds(1.0);
3300
3301 //----------------------------------------------------------------------------------------------------------------------------------
3302 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3303 // occupies the seventh and eighth 20 MHz subchannels of the S160 with received power
3304 // above the energy detection threshold for any occupied 20 MHz subchannels
3305 Simulator::Schedule(delay,
3307 this,
3308 "Reception of a 40 MHz signal that occupies the seventh and eighth "
3309 "subchannels of S160 above ED threshold");
3310 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 14, 2, MicroSeconds(100));
3311 ScheduleTest(delay,
3312 {{-58.0,
3313 MicroSeconds(0),
3314 MicroSeconds(100),
3316 MHz_u{40}}},
3317 {},
3318 {
3319 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3320 {MicroSeconds(100) - smallDelta,
3321 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3322 {MicroSeconds(100) + smallDelta,
3323 WifiPhyState::IDLE} // IDLE just after the transmission ends
3324 },
3325 {{MicroSeconds(100) - smallDelta,
3326 MicroSeconds(100),
3329 delay += Seconds(1.0);
3331
3332 //----------------------------------------------------------------------------------------------------------------------------------
3333 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3334 // occupies the first four 20 MHz subchannels of the S160 with received power below the
3335 // energy detection threshold for all occupied 20 MHz subchannels
3336 Simulator::Schedule(delay,
3338 this,
3339 "Reception of a 80 MHz signal that occupies the first four "
3340 "subchannels of S160 below ED threshold");
3341 ScheduleTest(delay,
3342 {{-57.0,
3343 MicroSeconds(0),
3344 MicroSeconds(100),
3346 MHz_u{80}}},
3347 {},
3348 {
3349 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3350 {MicroSeconds(100) - smallDelta,
3351 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3352 {MicroSeconds(100) + smallDelta,
3353 WifiPhyState::IDLE} // IDLE just after the transmission ends
3354 },
3355 {});
3356 delay += Seconds(1.0);
3357
3358 //----------------------------------------------------------------------------------------------------------------------------------
3359 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3360 // occupies the first four 20 MHz subchannels of the S160 with received power above the
3361 // energy detection threshold for any occupied 20 MHz subchannels
3362 Simulator::Schedule(delay,
3364 this,
3365 "Reception of a 80 MHz signal that occupies the first four "
3366 "subchannels of S160 above ED threshold");
3367 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 8, 4, MicroSeconds(100));
3368 ScheduleTest(delay,
3369 {{-55.0,
3370 MicroSeconds(0),
3371 MicroSeconds(100),
3373 MHz_u{80}}},
3374 {},
3375 {
3376 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3377 {MicroSeconds(100) - smallDelta,
3378 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3379 {MicroSeconds(100) + smallDelta,
3380 WifiPhyState::IDLE} // IDLE just after the transmission ends
3381 },
3382 {{MicroSeconds(100) - smallDelta,
3383 MicroSeconds(100),
3386 delay += Seconds(1.0);
3388
3389 //----------------------------------------------------------------------------------------------------------------------------------
3390 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3391 // occupies the last four 20 MHz subchannels of the S160 with received power below the
3392 // energy detection threshold for all occupied 20 MHz subchannels
3393 Simulator::Schedule(delay,
3395 this,
3396 "Reception of a 80 MHz signal that occupies the last four "
3397 "subchannels of S160 below ED threshold");
3398 ScheduleTest(delay,
3399 {{-57.0,
3400 MicroSeconds(0),
3401 MicroSeconds(100),
3403 MHz_u{80}}},
3404 {},
3405 {
3406 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3407 {MicroSeconds(100) - smallDelta,
3408 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3409 {MicroSeconds(100) + smallDelta,
3410 WifiPhyState::IDLE} // IDLE just after the transmission ends
3411 },
3412 {});
3413 delay += Seconds(1.0);
3414
3415 //----------------------------------------------------------------------------------------------------------------------------------
3416 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3417 // occupies the last four 20 MHz subchannels of the S160 with received power above the
3418 // energy detection threshold for any occupied 20 MHz subchannels
3419 Simulator::Schedule(delay,
3421 this,
3422 "Reception of a 80 MHz signal that occupies the last four "
3423 "subchannels of S160 above ED threshold");
3424 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 12, 4, MicroSeconds(100));
3425 ScheduleTest(delay,
3426 {{-55.0,
3427 MicroSeconds(0),
3428 MicroSeconds(100),
3430 MHz_u{80}}},
3431 {},
3432 {
3433 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3434 {MicroSeconds(100) - smallDelta,
3435 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3436 {MicroSeconds(100) + smallDelta,
3437 WifiPhyState::IDLE} // IDLE just after the transmission ends
3438 },
3439 {{MicroSeconds(100) - smallDelta,
3440 MicroSeconds(100),
3443 delay += Seconds(1.0);
3445
3446 //----------------------------------------------------------------------------------------------------------------------------------
3447 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3448 // occupies the whole S160 with received power below the energy detection threshold for
3449 // all occupied 20 MHz subchannels
3451 delay,
3453 this,
3454 "Reception of a 160 MHz signal that occupies the whole S160 below ED threshold");
3456 delay,
3457 {{-54.0, MicroSeconds(0), MicroSeconds(100), S160_CENTER_FREQUENCY, MHz_u{160}}},
3458 {},
3459 {
3460 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3461 {MicroSeconds(100) - smallDelta,
3462 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3463 {MicroSeconds(100) + smallDelta,
3464 WifiPhyState::IDLE} // IDLE just after the transmission ends
3465 },
3466 {});
3467 delay += Seconds(1.0);
3468
3469 //----------------------------------------------------------------------------------------------------------------------------------
3470 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3471 // occupies the whole S160 with received power above the energy detection threshold for
3472 // any occupied 20 MHz subchannels
3474 delay,
3476 this,
3477 "Reception of a 160 MHz signal that occupies the whole S160 above ED threshold");
3478 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 8, 8, MicroSeconds(100));
3480 delay,
3481 {{-52.0, MicroSeconds(0), MicroSeconds(100), S160_CENTER_FREQUENCY, MHz_u{160}}},
3482 {},
3483 {
3484 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3485 {MicroSeconds(100) - smallDelta,
3486 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3487 {MicroSeconds(100) + smallDelta,
3488 WifiPhyState::IDLE} // IDLE just after the transmission ends
3489 },
3490 {{MicroSeconds(100) - smallDelta,
3491 MicroSeconds(100),
3494 delay += Seconds(1.0);
3496
3497 //----------------------------------------------------------------------------------------------------------------------------------
3498 // Verify PHY state stays IDLE as long as a 320 MHz signal below the energy detection
3499 // threshold occupies the whole band
3501 delay,
3503 this,
3504 "Reception of a 320 MHz signal that occupies the whole band below ED threshold");
3506 delay,
3507 {{-51.0, MicroSeconds(0), MicroSeconds(100), P320_CENTER_FREQUENCY, MHz_u{320}}},
3508 {},
3509 {
3510 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3511 {MicroSeconds(100) - smallDelta,
3512 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3513 {MicroSeconds(100) + smallDelta,
3514 WifiPhyState::IDLE} // IDLE just after the transmission ends
3515 },
3516 {});
3517
3518 delay += Seconds(1.0);
3519
3520 //----------------------------------------------------------------------------------------------------------------------------------
3521 // Verify PHY state is CCA-BUSY as long as a 320 MHz signal above the energy detection
3522 // threshold occupies the whole band
3524 delay,
3526 this,
3527 "Reception of a 320 MHz signal that occupies the whole band above ED threshold");
3528 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 16, MicroSeconds(100));
3530 delay,
3531 {{-49.0, MicroSeconds(0), MicroSeconds(100), P320_CENTER_FREQUENCY, MHz_u{320}}},
3532 {},
3533 {
3534 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
3535 {MicroSeconds(100) - smallDelta,
3536 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
3537 {MicroSeconds(100) + smallDelta,
3538 WifiPhyState::IDLE} // IDLE just after the transmission ends
3539 },
3540 {{MicroSeconds(100) - smallDelta,
3541 MicroSeconds(100),
3544 delay += Seconds(1.0);
3546
3547 //----------------------------------------------------------------------------------------------------------------------------------
3548 // Verify PHY notifies CCA-BUSY for the P20 channel while the S160 channel was already
3549 // in CCA-BUSY state
3550 Simulator::Schedule(delay,
3552 this,
3553 "Reception of a 20 MHz signal that occupies S160 followed by the "
3554 "reception of another 20 MHz signal that occupies P20");
3559 delay,
3560 {{-52.0,
3561 MicroSeconds(0),
3562 MicroSeconds(100),
3564 MHz_u{20}},
3565 {-52.0, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
3566 {},
3567 {
3569 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3571 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
3572 // aCcaTimeWithDelta that followed the second
3573 // transmission
3574 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
3575 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
3576 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
3577 WifiPhyState::IDLE} // IDLE just after the transmission ends
3578 },
3579 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3580 MicroSeconds(100),
3583 {MicroSeconds(50) +
3584 aCcaTimeWithDelta, // notification upon reception of the second signal
3585 MicroSeconds(50) + MicroSeconds(100),
3588 delay += Seconds(1.0);
3590
3591 //----------------------------------------------------------------------------------------------------------------------------------
3592 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S80 channel while the S160
3593 // channel was already in CCA-BUSY state
3594 Simulator::Schedule(delay,
3596 this,
3597 "Reception of a signal that occupies S160 followed by the reception of "
3598 "another signal that occupies S80");
3603 delay,
3604 {{-52.0,
3605 MicroSeconds(0),
3606 MicroSeconds(100),
3608 MHz_u{20}},
3609 {-52.0,
3610 MicroSeconds(50),
3611 MicroSeconds(100),
3613 MHz_u{20}}},
3614 {},
3615 {
3617 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3619 WifiPhyState::IDLE}, // state of primary stays IDLE
3620 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
3621 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3622 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
3623 WifiPhyState::IDLE} // IDLE just after the transmission ends
3624 },
3625 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3626 MicroSeconds(100),
3629 {MicroSeconds(50) +
3630 aCcaTimeWithDelta, // notification upon reception of the second signal
3631 MicroSeconds(50) + MicroSeconds(100),
3634 delay += Seconds(1.0);
3636
3637 //----------------------------------------------------------------------------------------------------------------------------------
3638 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S40 channel while the S160
3639 // channel was already in CCA-BUSY state
3640 Simulator::Schedule(delay,
3642 this,
3643 "Reception of a signal that occupies S160 followed by the reception of "
3644 "another signal that occupies S40");
3649 delay,
3650 {{-52.0,
3651 MicroSeconds(0),
3652 MicroSeconds(100),
3654 MHz_u{20}},
3655 {-52.0,
3656 MicroSeconds(50),
3657 MicroSeconds(100),
3659 MHz_u{20}}},
3660 {},
3661 {
3663 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3665 WifiPhyState::IDLE}, // state of primary stays IDLE
3666 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
3667 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3668 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
3669 WifiPhyState::IDLE} // IDLE just after the transmission ends
3670 },
3671 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3672 MicroSeconds(100),
3675 {MicroSeconds(50) +
3676 aCcaTimeWithDelta, // notification upon reception of the second signal
3677 MicroSeconds(50) + MicroSeconds(100),
3680 delay += Seconds(1.0);
3682
3683 //----------------------------------------------------------------------------------------------------------------------------------
3684 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S160
3685 // channel was already in CCA-BUSY state
3686 Simulator::Schedule(delay,
3688 this,
3689 "Reception of a signal that occupies S160 followed by the reception of "
3690 "another signal that occupies S20");
3695 delay,
3696 {{-52.0,
3697 MicroSeconds(0),
3698 MicroSeconds(100),
3700 MHz_u{20}},
3701 {-52.0, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
3702 {},
3703 {
3705 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3707 WifiPhyState::IDLE}, // state of primary stays IDLE
3708 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
3709 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3710 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
3711 WifiPhyState::IDLE} // IDLE just after the transmission ends
3712 },
3713 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3714 MicroSeconds(100),
3717 {MicroSeconds(50) +
3718 aCcaTimeWithDelta, // notification upon reception of the second signal
3719 MicroSeconds(50) + MicroSeconds(100),
3722 delay += Seconds(1.0);
3724
3725 //----------------------------------------------------------------------------------------------------------------------------------
3726 // Verify PHY state stays IDLE when a 160 MHz PPDU that occupies S160 with received
3727 // power below the Per 20 MHz CCA threshold for all occupied 20 MHz subchannels
3729 delay,
3731 this,
3732 "Reception of a 160 MHz PPDU that occupies S160 below CCA sensitivity threshold");
3733 ScheduleTest(delay,
3734 {},
3735 {{-64.0, MicroSeconds(0), S160_CENTER_FREQUENCY, MHz_u{160}}},
3736 {
3737 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3738 {ppduDurations.at(160) - smallDelta,
3739 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3740 {ppduDurations.at(160) + smallDelta,
3741 WifiPhyState::IDLE} // IDLE just after the transmission ends
3742 },
3743 {});
3744 delay += Seconds(1.0);
3745
3746 //----------------------------------------------------------------------------------------------------------------------------------
3747 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 160 MHz PPDU
3748 // that occupies S160 with received power above the Per 20 MHz CCA threshold for any
3749 // occupied 20 MHz subchannels
3751 delay,
3753 this,
3754 "Reception of a 160 MHz PPDU that occupies S160 above CCA sensitivity threshold");
3755 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 8, 8, ppduDurations.at(160));
3756 ScheduleTest(delay,
3757 {},
3758 {{-62.0, MicroSeconds(0), S160_CENTER_FREQUENCY, MHz_u{160}}},
3759 {
3760 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3761 {ppduDurations.at(160) - smallDelta,
3762 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3763 {ppduDurations.at(160) + smallDelta,
3764 WifiPhyState::IDLE} // IDLE just after the transmission ends
3765 },
3767 ppduDurations.at(160),
3770 delay += Seconds(1.0);
3772 }
3773
3775}
3776
3777void
3805
3806void
3808{
3809 m_rxPhy->Dispose();
3810 m_rxPhy = nullptr;
3811 m_txPhy->Dispose();
3812 m_txPhy = nullptr;
3813 for (auto& signalGenerator : m_signalGenerators)
3814 {
3815 signalGenerator->Dispose();
3816 signalGenerator = nullptr;
3817 }
3818}
3819
3820/**
3821 * @ingroup wifi-test
3822 * @ingroup tests
3823 *
3824 * @brief Wi-Fi PHY CCA Test Suite
3825 */
3827{
3828 public:
3830};
3831
3839
3840static WifiPhyCcaTestSuite WifiPhyCcaTestSuite; ///< the test suite
void NotifyOn() override
Notify listeners that we went to switch on.
WifiChannelListType m_lastCcaBusyChannelType
Channel type indication for the last CCA-BUSY notification.
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
void NotifyRxEndError(const WifiTxVector &txVector) 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.
WifiStandard m_standard
The standard to use for the test.
void SendSuPpdu(dBm_u txPower, MHz_u frequency, MHz_u bandwidth)
Send a HE or EHT SU PPDU.
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.
std::vector< std::vector< Time > > m_expectedPer20MhzCcaBusyDurations
expected Per 20Mhz CCA durations per check
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state.
void ResetExpectedPer20MhzCcaBusyDurations()
Reset the expected Per 20 MHz CCA durations.
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.
WifiPhyCcaIndicationTest(WifiStandard standard)
Constructor.
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.
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.
void VerifyCcaThreshold(const std::shared_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< EhtConfiguration > m_ehtConfiguration
The EHT configuration.
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< EhtPpdu > CreateDummyEhtPpdu(MHz_u bandwidth, const WifiPhyOperatingChannel &channel)
Create a EHT PPDU.
dBm_u m_per20CcaSensitivity
The current CCA sensitivity threshold for Per 20MHz check.
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 GetEhtMcs0()
Return MCS 0 from EHT MCS values.
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
@ PSD_NON_HE_PORTION
Non-HE portion of an HE PPDU.
Definition he-ppdu.h:105
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.
Definition pointer.h:37
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
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
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:293
@ QUICK
Fast test.
Definition test.h:1054
TestCase(const TestCase &)=delete
Type
Type of test.
Definition test.h:1257
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:491
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
AttributeValue implementation for Time.
Definition nstime.h:1456
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.
WifiChannelConfig::SegmentWithoutUnits ChannelTuple
kept for backward compatibility, can be deprecated when using strong types
Definition wifi-phy.h:949
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=GetFrequencyChannels().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:439
#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:133
#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:499
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1393
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1405
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211ax
@ WIFI_PREAMBLE_LONG
@ WIFI_PREAMBLE_EHT_MU
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PREAMBLE_VHT_SU
@ WIFI_PREAMBLE_HT_MF
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17).
@ WIFI_MOD_CLASS_HT
HT (Clause 19).
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36).
@ 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_SECONDARY160
@ WIFI_CHANLIST_SECONDARY80
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyState
The state of the PHY layer.
@ IDLE
The PHY layer is IDLE.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ RX
The PHY layer is receiving a packet.
static constexpr uint8_t WIFI_MIN_TX_PWR_LEVEL
minimum TX power level value
std::vector< BandInfo > Bands
Container of BandInfo.
double MHz_u
MHz weak type.
Definition wifi-units.h:31
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:585
double dBm_u
dBm weak type
Definition wifi-units.h:27
@ WIFI_MAC_QOSDATA
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:32
Hz_u MHzToHz(MHz_u val)
Convert from MHz to Hz.
Definition wifi-utils.h:120
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
double dB_u
dB weak type
Definition wifi-units.h:28
STL namespace.
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
const Time aCcaTimeWithDelta
constexpr MHz_u P320_CENTER_FREQUENCY
constexpr MHz_u S80_CENTER_FREQUENCY
constexpr MHz_u S20_CENTER_FREQUENCY
constexpr MHz_u P20_CENTER_FREQUENCY
constexpr MHz_u S160_CENTER_FREQUENCY
const Time phyHeaderDuration
constexpr MHz_u S40_CENTER_FREQUENCY
const std::map< MHz_u, Time > ehtPpduDurations
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 > hePpduDurations