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 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},
171 m_secondaryCcaSensitivityThresholds{dBm_u{-72}, dBm_u{-72}, dBm_u{-69}},
172 m_obssPdLevel{-82.0},
173 m_per20CcaSensitivity{-72.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{
191 0,
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{
207 0,
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{
224 0,
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{
240 0,
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{
257 0,
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
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
978 WifiPhyState expectedPhyState{WifiPhyState::IDLE}; //!< expected PHY state
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},
1046 m_numSignalGenerators{2},
1047 m_frequency{P20_CENTER_FREQUENCY},
1048 m_channelWidth{MHz_u{20}}
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 =
1100 WifiTxVector txVector{mcs, 0, preamble, NanoSeconds(800), 1, 1, 0, bandwidth, false};
1101 Ptr<Packet> pkt = Create<Packet>(1000);
1102 WifiMacHeader hdr;
1104 hdr.SetQosTid(0);
1105 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
1106
1107 m_txPhy->SetTxPowerStart(txPower);
1108 m_txPhy->SetTxPowerEnd(txPower);
1109
1110 m_txPhy->Send(psdu, txVector);
1111}
1112
1113void
1115{
1116 // This is needed to make sure PHY state will be checked as the last event if a state change
1117 // occurred at the exact same time as the check
1119}
1120
1121void
1123{
1124 WifiPhyState currentState;
1125 PointerValue ptr;
1126 m_rxPhy->GetAttribute("State", ptr);
1128 currentState = state->GetState();
1129 NS_TEST_ASSERT_MSG_EQ(currentState,
1130 expectedState,
1131 "PHY State " << currentState << " does not match expected state "
1132 << expectedState << " at " << Simulator::Now());
1133}
1134
1135void
1137 Time expectedEndTime,
1138 WifiChannelListType expectedChannelType,
1139 const std::vector<Time>& expectedPer20MhzDurations)
1140{
1142 expectedEndTime,
1143 "PHY CCA end time " << m_rxPhyStateListener->m_endCcaBusy
1144 << " does not match expected time " << expectedEndTime
1145 << " at " << Simulator::Now());
1147 expectedChannelType,
1148 "PHY CCA-BUSY for " << m_rxPhyStateListener->m_lastCcaBusyChannelType
1149 << " does not match expected channel type "
1150 << expectedChannelType << " at " << Simulator::Now());
1152 expectedPer20MhzDurations.size(),
1153 "PHY CCA-BUSY per-20 MHz durations does not match expected vector"
1154 << " at " << Simulator::Now());
1155 for (std::size_t i = 0; i < expectedPer20MhzDurations.size(); ++i)
1156 {
1158 expectedPer20MhzDurations.at(i),
1159 "PHY CCA-BUSY per-20 MHz duration at index "
1160 << i << " does not match expected duration at "
1161 << Simulator::Now());
1162 }
1163}
1164
1165void
1166WifiPhyCcaIndicationTest::LogScenario(const std::string& log) const
1167{
1168 NS_LOG_INFO(log);
1169}
1170
1171void
1173 const std::vector<TxSignalInfo>& generatedSignals,
1174 const std::vector<TxPpduInfo>& generatedPpdus,
1175 const std::vector<StateCheckPoint>& stateCheckpoints,
1176 const std::vector<CcaCheckPoint>& ccaCheckpoints)
1177{
1178 for (const auto& generatedPpdu : generatedPpdus)
1179 {
1180 Simulator::Schedule(delay + generatedPpdu.startTime,
1182 this,
1183 generatedPpdu.power,
1184 generatedPpdu.centerFreq,
1185 generatedPpdu.bandwidth);
1186 }
1187
1188 std::size_t index = 0;
1189 for (const auto& generatedSignal : generatedSignals)
1190 {
1191 Simulator::Schedule(delay + generatedSignal.startTime,
1193 this,
1194 m_signalGenerators.at(index++),
1195 generatedSignal.power,
1196 generatedSignal.centerFreq,
1197 generatedSignal.bandwidth,
1198 generatedSignal.duration);
1199 }
1200
1201 for (const auto& checkpoint : ccaCheckpoints)
1202 {
1203 Simulator::Schedule(delay + checkpoint.timePoint,
1205 this,
1206 Simulator::Now() + delay + checkpoint.expectedCcaEndTime,
1207 checkpoint.expectedChannelListType,
1208 checkpoint.expectedPer20MhzDurations);
1209 }
1210
1211 for (const auto& checkpoint : stateCheckpoints)
1212 {
1213 Simulator::Schedule(delay + checkpoint.timePoint,
1215 this,
1216 checkpoint.expectedPhyState);
1217 }
1218
1220}
1221
1222void
1227
1228void
1230{
1232 switch (static_cast<uint16_t>(m_channelWidth))
1233 {
1234 case 20:
1235 default:
1236 // no Per-20 MHz CCA
1239 break;
1240 case 40:
1243 break;
1244 case 80:
1246 MicroSeconds(0),
1247 MicroSeconds(0),
1248 MicroSeconds(0),
1249 MicroSeconds(0),
1250 });
1252 MicroSeconds(0),
1253 MicroSeconds(0),
1254 MicroSeconds(0),
1255 MicroSeconds(0),
1256 });
1257 break;
1258 case 160:
1260 MicroSeconds(0),
1261 MicroSeconds(0),
1262 MicroSeconds(0),
1263 MicroSeconds(0),
1264 MicroSeconds(0),
1265 MicroSeconds(0),
1266 MicroSeconds(0),
1267 MicroSeconds(0),
1268 });
1270 MicroSeconds(0),
1271 MicroSeconds(0),
1272 MicroSeconds(0),
1273 MicroSeconds(0),
1274 MicroSeconds(0),
1275 MicroSeconds(0),
1276 MicroSeconds(0),
1277 MicroSeconds(0),
1278 });
1279 break;
1280 case 320:
1282 MicroSeconds(0),
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 });
1300 MicroSeconds(0),
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 });
1317 break;
1318 }
1319}
1320
1321void
1323{
1324 // WifiHelper::EnableLogComponents ();
1325 // LogComponentEnable ("WifiPhyCcaTest", LOG_LEVEL_ALL);
1326
1328
1329 Ptr<Node> rxNode = CreateObject<Node>();
1331 rxDev->SetStandard(m_standard);
1332 auto vhtConfiguration = CreateObject<VhtConfiguration>();
1333 rxDev->SetVhtConfiguration(vhtConfiguration);
1335 {
1336 auto ehtConfiguration = CreateObject<EhtConfiguration>();
1337 rxDev->SetEhtConfiguration(ehtConfiguration);
1338 }
1340 m_rxPhyStateListener = std::make_unique<CcaTestPhyListener>();
1341 m_rxPhy->RegisterListener(m_rxPhyStateListener);
1343 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
1345 m_rxPhy->SetErrorRateModel(rxErrorModel);
1346 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
1348 m_rxPhy->SetPreambleDetectionModel(preambleDetectionModel);
1349 m_rxPhy->AddChannel(spectrumChannel);
1350 m_rxPhy->ConfigureStandard(m_standard);
1351 m_rxPhy->SetDevice(rxDev);
1352 rxDev->SetPhy(m_rxPhy);
1353 rxNode->AddDevice(rxDev);
1354
1355 Ptr<Node> txNode = CreateObject<Node>();
1358 m_txPhy->SetAttribute("ChannelSwitchDelay", TimeValue(Seconds(0)));
1360 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
1362 m_txPhy->SetErrorRateModel(txErrorModel);
1363 m_txPhy->AddChannel(spectrumChannel);
1364 m_txPhy->ConfigureStandard(m_standard);
1365 m_txPhy->SetDevice(txDev);
1366 txDev->SetPhy(m_txPhy);
1367 txNode->AddDevice(txDev);
1368
1369 for (std::size_t i = 0; i < m_numSignalGenerators; ++i)
1370 {
1371 Ptr<Node> signalGeneratorNode = CreateObject<Node>();
1372 Ptr<NonCommunicatingNetDevice> signalGeneratorDev =
1375 signalGenerator->SetDevice(signalGeneratorDev);
1376 signalGenerator->SetChannel(spectrumChannel);
1377 signalGenerator->SetDutyCycle(1);
1378 signalGeneratorNode->AddDevice(signalGeneratorDev);
1379 m_signalGenerators.push_back(signalGenerator);
1380 }
1381}
1382
1383void
1385{
1388 int64_t streamNumber = 0;
1389 m_rxPhy->AssignStreams(streamNumber);
1390 m_txPhy->AssignStreams(streamNumber);
1391
1392 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
1395 m_standard,
1397 ->number;
1398
1399 m_rxPhy->SetOperatingChannel(
1401 m_txPhy->SetOperatingChannel(
1403
1404 const auto& ppduDurations =
1406
1407 Time delay;
1409 delay += Seconds(1);
1410
1412
1413 //----------------------------------------------------------------------------------------------------------------------------------
1414 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal below
1415 // the energy detection threshold occupies P20
1416 Simulator::Schedule(delay,
1418 this,
1419 "Reception of a signal that occupies P20 below ED threshold");
1421 delay,
1422 {{dBm_u{-65}, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
1423 {},
1424 {
1425 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1426 {MicroSeconds(100) - smallDelta,
1427 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1428 {MicroSeconds(100) + smallDelta,
1429 WifiPhyState::IDLE} // IDLE just after the transmission ends
1430 },
1431 {});
1432 delay += Seconds(1);
1433
1434 //----------------------------------------------------------------------------------------------------------------------------------
1435 // Verify PHY state is CCA-BUSY as long as a 20 MHz signal above the energy detection
1436 // threshold occupies P20
1437 Simulator::Schedule(delay,
1439 this,
1440 "Reception of signal that occupies P20 above ED threshold");
1441 if (m_channelWidth > 20)
1442 {
1444 }
1446 delay,
1447 {{dBm_u{-60.0}, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
1448 {},
1449 {
1450 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1451 {MicroSeconds(100) - smallDelta,
1452 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1453 {MicroSeconds(100) + smallDelta,
1454 WifiPhyState::IDLE} // IDLE just after the transmission ends
1455 },
1456 {{MicroSeconds(100) - smallDelta,
1457 MicroSeconds(100),
1460 delay += Seconds(1);
1462
1463 //----------------------------------------------------------------------------------------------------------------------------------
1464 // Verify PHY state is CCA-BUSY as long as the sum of 20 MHz signals occupying P20 is above
1465 // the energy detection threshold
1466 Simulator::Schedule(delay,
1468 this,
1469 "Reception of two 20 MHz signals that occupies P20 below ED threshold with "
1470 "sum above ED threshold");
1471 if (m_channelWidth > 20)
1472 {
1474 }
1475 ScheduleTest(delay,
1476 {{-64.0, MicroSeconds(0), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}},
1477 {-65.0, MicroSeconds(50), MicroSeconds(200), P20_CENTER_FREQUENCY, MHz_u{20}}},
1478 {},
1479 {
1481 WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1482 {MicroSeconds(100) - smallDelta,
1483 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1484 {MicroSeconds(100) + smallDelta,
1485 WifiPhyState::IDLE} // IDLE just after the transmission ends
1486 },
1487 {{MicroSeconds(100) - smallDelta,
1488 MicroSeconds(100),
1491 delay += Seconds(1);
1493
1494 //----------------------------------------------------------------------------------------------------------------------------------
1495 // Verify PHY state stays IDLE when a 20 MHz PPDU with received power below the
1496 // corresponding CCA sensitivity threshold occupies P20
1498 delay,
1500 this,
1501 "Reception of a 20 MHz PPDU that occupies P20 below CCA sensitivity threshold");
1502 ScheduleTest(delay,
1503 {},
1504 {{dBm_u{-85}, MicroSeconds(0), P20_CENTER_FREQUENCY, MHz_u{20}}},
1505 {
1506 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1507 {ppduDurations.at(MHz_u{20}) - smallDelta,
1508 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1509 {ppduDurations.at(MHz_u{20}) + smallDelta,
1510 WifiPhyState::IDLE} // IDLE just after the transmission ends
1511 },
1512 {});
1513 delay += Seconds(1);
1514
1515 //----------------------------------------------------------------------------------------------------------------------------------
1516 // Verify PHY state transitions to CCA-BUSY when an PPDU with received power above the CCA
1517 // sensitivity threshold occupies P20. The per20Bitmap should indicate idle on the primary
1518 // 20 MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1520 delay,
1522 this,
1523 "Reception of a 20 MHz PPDU that occupies P20 above CCA sensitivity threshold");
1525 delay,
1526 {},
1527 {{dBm_u{-80}, MicroSeconds(0), P20_CENTER_FREQUENCY, MHz_u{20}}},
1528 {
1529 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1530 {ppduDurations.at(MHz_u{20}) - smallDelta,
1531 WifiPhyState::RX}, // RX just before the transmission ends
1532 {ppduDurations.at(MHz_u{20}) + smallDelta,
1533 WifiPhyState::IDLE} // IDLE just after the transmission ends
1534 },
1536 MicroSeconds(16),
1539 delay += Seconds(1);
1540
1541 //----------------------------------------------------------------------------------------------------------------------------------
1542 // Verify PHY state stays IDLE when a 40 MHz PPDU with received power below the CCA
1543 // sensitivity threshold occupies P40
1545 delay,
1547 this,
1548 "Reception of a 40 MHz PPDU that occupies P20 below CCA sensitivity threshold");
1549 ScheduleTest(delay,
1550 {},
1551 {{dBm_u{-80}, MicroSeconds(0), P40_CENTER_FREQUENCY, MHz_u{40}}},
1552 {
1553 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1554 {ppduDurations.at(MHz_u{40}) - smallDelta,
1555 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1556 {ppduDurations.at(MHz_u{40}) + smallDelta,
1557 WifiPhyState::IDLE} // IDLE just after the transmission ends
1558 },
1559 {});
1560 delay += Seconds(1);
1561
1562 //----------------------------------------------------------------------------------------------------------------------------------
1563 // Verify PHY state transitions to CCA-BUSY when an PPDU with received power above the CCA
1564 // sensitivity threshold occupies P40. The per20Bitmap should indicate idle on the primary
1565 // 20 MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1567 delay,
1569 this,
1570 "Reception of a 40 MHz PPDU that occupies P40 above CCA sensitivity threshold");
1572 delay,
1573 {},
1574 {{dBm_u{-75}, MicroSeconds(0), P40_CENTER_FREQUENCY, MHz_u{40}}},
1575 {
1576 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1577 {ppduDurations.at(MHz_u{40}) - smallDelta,
1578 (m_channelWidth > MHz_u{20})
1579 ? WifiPhyState::RX
1580 : WifiPhyState::CCA_BUSY}, // RX or IDLE just before the transmission ends
1581 {ppduDurations.at(MHz_u{40}) + smallDelta,
1582 WifiPhyState::IDLE} // IDLE just after the transmission ends
1583 },
1585 MicroSeconds(16),
1588 delay += Seconds(1);
1589
1590 if (m_channelWidth > MHz_u{20})
1591 {
1592 //----------------------------------------------------------------------------------------------------------------------------------
1593 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a 20 MHz
1594 // signal below the energy detection threshold occupies S20
1595 Simulator::Schedule(delay,
1597 this,
1598 "Reception of a 20 MHz signal that occupies S20 below ED threshold");
1600 delay,
1601 {{dBm_u{-65}, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
1602 {},
1603 {
1604 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1605 {MicroSeconds(100) - smallDelta,
1606 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1607 {MicroSeconds(100) + smallDelta,
1608 WifiPhyState::IDLE} // IDLE just after the transmission ends
1609 },
1610 {});
1611 delay += Seconds(1);
1612
1613 //----------------------------------------------------------------------------------------------------------------------------------
1614 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz signal
1615 // above the energy detection threshold occupies S20
1616 Simulator::Schedule(delay,
1618 this,
1619 "Reception of a 20 MHz signal that occupies S20 above ED threshold");
1622 delay,
1623 {{dBm_u{-60}, MicroSeconds(0), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
1624 {},
1625 {
1626 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1627 {MicroSeconds(100) - smallDelta,
1628 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1629 {MicroSeconds(100) + smallDelta,
1630 WifiPhyState::IDLE} // IDLE just after the transmission ends
1631 },
1632 {{MicroSeconds(100) - smallDelta,
1633 MicroSeconds(100),
1636 delay += Seconds(1);
1638
1639 //----------------------------------------------------------------------------------------------------------------------------------
1640 // Verify PHY state is CCA-BUSY as long as a 40 MHz signal above the energy detection
1641 // threshold occupies P40
1642 Simulator::Schedule(delay,
1644 this,
1645 "Reception of a 40 MHz signal that occupies P40 above ED threshold");
1646 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 2, MicroSeconds(100));
1648 delay,
1649 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), P40_CENTER_FREQUENCY, MHz_u{40}}},
1650 {},
1651 {
1652 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1653 {MicroSeconds(100) - smallDelta,
1654 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1655 {MicroSeconds(100) + smallDelta,
1656 WifiPhyState::IDLE} // IDLE just after the transmission ends
1657 },
1658 {{MicroSeconds(100) - smallDelta,
1659 MicroSeconds(100),
1662 delay += Seconds(1);
1664
1665 //----------------------------------------------------------------------------------------------------------------------------------
1666 // Verify PHY notifies CCA-BUSY for the primary channel while the secondary channel was
1667 // already in CCA-BUSY state
1668 Simulator::Schedule(delay,
1670 this,
1671 "Reception of a signal that occupies S20 followed by the reception of "
1672 "another signal that occupies P20");
1677 delay,
1679 {dBm_u{-60}, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
1680 {},
1681 {
1683 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
1685 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
1686 // aCcaTimeWithDelta that followed the second
1687 // transmission
1688 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
1689 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1690 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
1691 WifiPhyState::IDLE} // IDLE just after the transmission ends
1692 },
1693 {{aCcaTimeWithDelta, // notification upon reception of the first signal
1694 MicroSeconds(100),
1697 {MicroSeconds(50) +
1698 aCcaTimeWithDelta, // notification upon reception of the second signal
1699 MicroSeconds(50) + MicroSeconds(100),
1702 delay += Seconds(1);
1704
1705 //----------------------------------------------------------------------------------------------------------------------------------
1706 // Verify PHY updates per-20 MHz CCA durations if a signal arrives on the secondary
1707 // channel while primary is CCA-BUSY
1708 Simulator::Schedule(delay,
1710 this,
1711 "Reception of a signal that occupies P20 followed by the reception of "
1712 "another signal that occupies S20");
1717 delay,
1719 {dBm_u{-60}, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
1720 {},
1721 {
1722 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1724 WifiPhyState::CCA_BUSY}, // state of primary is still CCA-BUSY after
1725 // aCcaTimeWithDelta that followed the second
1726 // transmission
1727 {MicroSeconds(100) - smallDelta,
1728 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the first transmission ends
1729 {MicroSeconds(100) + smallDelta,
1730 WifiPhyState::IDLE} // IDLE just after the first transmission ends
1731 },
1732 {{aCcaTimeWithDelta, // notification upon reception of the first signal
1733 MicroSeconds(100),
1736 {MicroSeconds(50) +
1737 aCcaTimeWithDelta, // notification upon reception of the second signal
1738 MicroSeconds(100),
1741 delay += Seconds(1);
1743
1744 //----------------------------------------------------------------------------------------------------------------------------------
1745 // Verify PHY state stays IDLE when a 20 MHz PPDU with received power below the CCA
1746 // sensitivity threshold occupies S40
1748 delay,
1750 this,
1751 "Reception of a 20 MHz PPDU that occupies S20 below CCA sensitivity threshold");
1752 ScheduleTest(delay,
1753 {},
1754 {{dBm_u{-75}, MicroSeconds(0), S20_CENTER_FREQUENCY, MHz_u{20}}},
1755 {
1756 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1757 {ppduDurations.at(MHz_u{20}) - smallDelta,
1758 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1759 {ppduDurations.at(MHz_u{20}) + smallDelta,
1760 WifiPhyState::IDLE} // IDLE just after the transmission ends
1761 },
1762 {});
1763 delay += Seconds(1);
1764
1765 //----------------------------------------------------------------------------------------------------------------------------------
1766 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz PPDU
1767 // with received power above the CCA sensitivity threshold occupies S20
1769 delay,
1771 this,
1772 "Reception of a 20 MHz PPDU that occupies S20 above CCA sensitivity threshold");
1773 m_expectedPer20MhzCcaBusyDurations.at(0).at(1) = ppduDurations.at(MHz_u{20});
1774 ScheduleTest(delay,
1775 {},
1776 {{dBm_u{-70}, MicroSeconds(0), S20_CENTER_FREQUENCY, MHz_u{20}}},
1777 {
1778 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1779 {ppduDurations.at(MHz_u{20}) - smallDelta,
1780 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1781 {ppduDurations.at(MHz_u{20}) + smallDelta,
1782 WifiPhyState::IDLE} // IDLE just after the transmission ends
1783 },
1785 ppduDurations.at(MHz_u{20}),
1788 delay += Seconds(1);
1790
1791 //----------------------------------------------------------------------------------------------------------------------------------
1792 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a
1793 // signal above the energy detection threshold occupies the S20 while a 40 MHz PPDU
1794 // below the CCA sensitivity threshold is received on P40.
1795 Simulator::Schedule(delay,
1797 this,
1798 "Reception of a 20 MHz signal that occupies S20 above ED threshold "
1799 "followed by a 40 "
1800 "MHz PPDU that occupies P40 below CCA sensitivity threshold");
1804 delay,
1805 {{dBm_u{-60},
1806 MicroSeconds(0),
1807 MicroSeconds(100),
1809 MHz_u{20}}}, // signal on S20 above threshold
1810 {{dBm_u{-80},
1811 MicroSeconds(50),
1813 MHz_u{40}}}, // PPDU on P40 below threshold
1814 {
1815 {MicroSeconds(50) + aCcaTimeWithDelta, WifiPhyState::IDLE}, // PHY state stays IDLE
1816 },
1817 {{MicroSeconds(50) - smallDelta,
1818 MicroSeconds(100),
1821 {MicroSeconds(100) - smallDelta,
1822 MicroSeconds(100),
1825 delay += Seconds(1);
1827 }
1828
1829 if (m_channelWidth > MHz_u{40})
1830 {
1831 //----------------------------------------------------------------------------------------------------------------------------------
1832 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal
1833 // below the energy detection threshold occupies S40
1834 Simulator::Schedule(delay,
1836 this,
1837 "Reception of a 20 MHz signal that occupies the first subchannel of "
1838 "S40 below ED threshold");
1839 ScheduleTest(delay,
1840 {{dBm_u{-65},
1841 MicroSeconds(0),
1842 MicroSeconds(100),
1844 MHz_u{20}}},
1845 {},
1846 {
1847 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1848 {MicroSeconds(100) - smallDelta,
1849 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1850 {MicroSeconds(100) + smallDelta,
1851 WifiPhyState::IDLE} // IDLE just after the transmission ends
1852 },
1853 {});
1854 delay += Seconds(1);
1855
1856 //----------------------------------------------------------------------------------------------------------------------------------
1857 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy
1858 // detection threshold occupies the first 20 MHz subchannel of the S40: 27.3.20.6.4: Any
1859 // signal within the secondary 40 MHz channel at or above a threshold of –59 dBm within
1860 // a period of aCcaTimeWithDelta after the signal arrives at the receiver’s antenna(s).
1861 Simulator::Schedule(delay,
1863 this,
1864 "Reception of a 20 MHz signal that occupies the first subchannel of "
1865 "S40 above ED threshold");
1867 ScheduleTest(delay,
1868 {{dBm_u{-55},
1869 MicroSeconds(0),
1870 MicroSeconds(100),
1872 MHz_u{20}}},
1873 {},
1874 {
1875 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1876 {MicroSeconds(100) - smallDelta,
1877 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1878 {MicroSeconds(100) + smallDelta,
1879 WifiPhyState::IDLE} // IDLE just after the transmission ends
1880 },
1881 {{MicroSeconds(100) - smallDelta,
1882 MicroSeconds(100),
1885 delay += Seconds(1);
1887
1888 //----------------------------------------------------------------------------------------------------------------------------------
1889 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection
1890 // threshold occupies the second 20 MHz subchannel of the S40
1891 Simulator::Schedule(delay,
1893 this,
1894 "Reception of a 20 MHz signal that occupies the second subchannel of "
1895 "S40 below ED threshold");
1896 ScheduleTest(delay,
1897 {{dBm_u{-65},
1898 MicroSeconds(0),
1899 MicroSeconds(100),
1901 MHz_u{20}}},
1902 {},
1903 {
1904 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1905 {MicroSeconds(100) - smallDelta,
1906 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1907 {MicroSeconds(100) + smallDelta,
1908 WifiPhyState::IDLE} // IDLE just after the transmission ends
1909 },
1910 {});
1911 delay += Seconds(1);
1912
1913 //----------------------------------------------------------------------------------------------------------------------------------
1914 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy
1915 // detection threshold occupies the second 20 MHz subchannel of the S40: 27.3.20.6.4:
1916 // Any signal within the secondary 40 MHz channel at or above a threshold of –59 dBm
1917 // within a period of aCcaTimeWithDelta after the signal arrives at the receiver's
1918 // antenna(s).
1919 Simulator::Schedule(delay,
1921 this,
1922 "Reception of a 20 MHz signal that occupies the second subchannel of "
1923 "S40 above ED threshold");
1925 ScheduleTest(delay,
1926 {{dBm_u{-55},
1927 MicroSeconds(0),
1928 MicroSeconds(100),
1930 MHz_u{20}}},
1931 {},
1932 {
1933 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1934 {MicroSeconds(100) - smallDelta,
1935 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1936 {MicroSeconds(100) + smallDelta,
1937 WifiPhyState::IDLE} // IDLE just after the transmission ends
1938 },
1939 {{MicroSeconds(100) - smallDelta,
1940 MicroSeconds(100),
1943 delay += Seconds(1);
1945
1946 //----------------------------------------------------------------------------------------------------------------------------------
1947 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection
1948 // threshold occupies S40
1949 Simulator::Schedule(delay,
1951 this,
1952 "Reception of a 40 MHz signal that occupies S40 below ED threshold");
1954 delay,
1955 {{dBm_u{-60}, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY, MHz_u{40}}},
1956 {},
1957 {
1958 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1959 {MicroSeconds(100) - smallDelta,
1960 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1961 {MicroSeconds(100) + smallDelta,
1962 WifiPhyState::IDLE} // IDLE just after the transmission ends
1963 },
1964 {});
1965 delay += Seconds(1);
1966
1967 //----------------------------------------------------------------------------------------------------------------------------------
1968 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy
1969 // detection threshold occupies S40: 27.3.20.6.4: Any signal within the secondary 40 MHz
1970 // channel at or above a threshold of –59 dBm within a period of aCcaTimeWithDelta after
1971 // the signal arrives at the receiver's antenna(s).
1972 Simulator::Schedule(delay,
1974 this,
1975 "Reception of a 20 MHz signal that occupies the second subchannel of "
1976 "S40 above ED threshold");
1977 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 2, 2, MicroSeconds(100));
1979 delay,
1980 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), S40_CENTER_FREQUENCY, MHz_u{40}}},
1981 {},
1982 {
1983 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1984 {MicroSeconds(100) - smallDelta,
1985 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1986 {MicroSeconds(100) + smallDelta,
1987 WifiPhyState::IDLE} // IDLE just after the transmission ends
1988 },
1989 {{MicroSeconds(100) - smallDelta,
1990 MicroSeconds(100),
1993 delay += Seconds(1);
1995
1996 //----------------------------------------------------------------------------------------------------------------------------------
1997 // Verify PHY state is CCA-BUSY as long as a 80 MHz signal above the energy detection
1998 // threshold occupies P80
1999 Simulator::Schedule(delay,
2001 this,
2002 "Reception of a 80 MHz signal that occupies P80 above ED threshold");
2003 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 4, MicroSeconds(100));
2005 delay,
2006 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), P80_CENTER_FREQUENCY, MHz_u{80}}},
2007 {},
2008 {
2009 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
2010 {MicroSeconds(100) - smallDelta,
2011 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2012 {MicroSeconds(100) + smallDelta,
2013 WifiPhyState::IDLE} // IDLE just after the transmission ends
2014 },
2015 {{MicroSeconds(100) - smallDelta,
2016 MicroSeconds(100),
2019 delay += Seconds(1);
2021
2022 //----------------------------------------------------------------------------------------------------------------------------------
2023 // Verify PHY notifies CCA-BUSY for the P20 channel while the S40 channel was already in
2024 // CCA-BUSY state
2025 Simulator::Schedule(delay,
2027 this,
2028 "Reception of a 20 MHz signal that occupies S40 followed by the "
2029 "reception of another 20 MHz signal that occupies P20");
2034 delay,
2035 {{dBm_u{-55},
2036 MicroSeconds(0),
2037 MicroSeconds(100),
2039 MHz_u{20}},
2040 {dBm_u{-55}, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
2041 {},
2042 {
2044 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2046 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
2047 // aCcaTimeWithDelta that followed the second
2048 // transmission
2049 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2050 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2051 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2052 WifiPhyState::IDLE} // IDLE just after the transmission ends
2053 },
2054 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2055 MicroSeconds(100),
2058 {MicroSeconds(50) +
2059 aCcaTimeWithDelta, // notification upon reception of the second signal
2060 MicroSeconds(50) + MicroSeconds(100),
2063 delay += Seconds(1);
2065
2066 //----------------------------------------------------------------------------------------------------------------------------------
2067 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S40
2068 // channel was already in CCA-BUSY state
2069 Simulator::Schedule(delay,
2071 this,
2072 "Reception of a signal that occupies S40 followed by the reception of "
2073 "another signal that occupies S20");
2078 delay,
2079 {{dBm_u{-55},
2080 MicroSeconds(0),
2081 MicroSeconds(100),
2083 MHz_u{20}},
2084 {dBm_u{-55}, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
2085 {},
2086 {
2088 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2090 WifiPhyState::IDLE}, // state of primary stays IDLE
2091 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2092 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2093 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2094 WifiPhyState::IDLE} // IDLE just after the transmission ends
2095 },
2096 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2097 MicroSeconds(100),
2100 {MicroSeconds(50) +
2101 aCcaTimeWithDelta, // notification upon reception of the second signal
2102 MicroSeconds(50) + MicroSeconds(100),
2105 delay += Seconds(1);
2107
2108 //----------------------------------------------------------------------------------------------------------------------------------
2109 // Verify PHY state stays IDLE when a 40 MHz PPDU with received power below the CCA
2110 // sensitivity threshold occupies S40
2112 delay,
2114 this,
2115 "Reception of a 40 MHz PPDU that occupies S40 below CCA sensitivity threshold");
2116 ScheduleTest(delay,
2117 {},
2118 {{dBm_u{-75}, MicroSeconds(0), S40_CENTER_FREQUENCY, MHz_u{40}}},
2119 {
2120 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2121 {ppduDurations.at(MHz_u{40}) - smallDelta,
2122 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2123 {ppduDurations.at(MHz_u{40}) + smallDelta,
2124 WifiPhyState::IDLE} // IDLE just after the transmission ends
2125 },
2126 {});
2127 delay += Seconds(1);
2128
2129 //----------------------------------------------------------------------------------------------------------------------------------
2130 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 40 MHz PPDU
2131 // with received power above the CCA sensitivity threshold occupies S40
2132 const dBm_u rxPower{(m_standard == WIFI_STANDARD_80211ax) ? -70.0 : -67.0};
2134 delay,
2136 this,
2137 "Reception of a 40 MHz PPDU that occupies S40 above CCA sensitivity threshold");
2138 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 2,
2139 2,
2140 ppduDurations.at(MHz_u{40}));
2141 ScheduleTest(delay,
2142 {},
2143 {{rxPower, MicroSeconds(0), S40_CENTER_FREQUENCY, MHz_u{40}}},
2144 {
2145 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2146 {ppduDurations.at(MHz_u{40}) - smallDelta,
2147 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2148 {ppduDurations.at(MHz_u{40}) + smallDelta,
2149 WifiPhyState::IDLE} // IDLE just after the transmission ends
2150 },
2152 ppduDurations.at(MHz_u{40}),
2155 delay += Seconds(1);
2157
2158 //----------------------------------------------------------------------------------------------------------------------------------
2159 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a
2160 // signal above the energy detection threshold occupies the S40 while a 80 MHz PPDU
2161 // below the CCA sensitivity threshold is received on P80.
2162 Simulator::Schedule(delay,
2164 this,
2165 "Reception of a 40 MHz signal that occupies S40 above ED threshold "
2166 "followed by a 80 "
2167 "MHz PPDU that occupies P80 below CCA sensitivity threshold");
2168 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 2, 2, MicroSeconds(100));
2169 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(1).begin() + 2, 2, MicroSeconds(46));
2171 delay,
2172 {{dBm_u{-55},
2173 MicroSeconds(0),
2174 MicroSeconds(100),
2176 MHz_u{40}}}, // signal on S40 above threshold
2177 {{dBm_u{-80},
2178 MicroSeconds(50),
2180 MHz_u{80}}}, // PPDU on P80 below threshold
2181 {
2182 {MicroSeconds(50) + aCcaTimeWithDelta, WifiPhyState::IDLE}, // PHY state stays IDLE
2183 },
2184 {{MicroSeconds(50) - smallDelta,
2185 MicroSeconds(100),
2188 {MicroSeconds(100) - smallDelta,
2189 MicroSeconds(100),
2192 delay += Seconds(1);
2194 }
2195 else // 20 or 40 MHz receiver
2196 {
2197 //----------------------------------------------------------------------------------------------------------------------------------
2198 // Verify PHY notifies CCA-BUSY when a 80 MHz PPDU with received power above the CCA
2199 // sensitivity threshold occupies P40 The per20Bitmap should indicate idle for all
2200 // subchannels because received power is below -62 dBm (27.3.20.6.5).
2201 Simulator::Schedule(delay,
2203 this,
2204 "Reception of a 80 MHz PPDU that occupies the 40 MHz band above CCA "
2205 "sensitivity threshold");
2207 delay,
2208 {},
2209 {{dBm_u{-70}, MicroSeconds(0), P80_CENTER_FREQUENCY, MHz_u{80}}},
2210 {
2211 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCcaTimeWithDelta
2212 {ppduDurations.at(MHz_u{80}) - smallDelta,
2213 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2214 {ppduDurations.at(MHz_u{80}) + smallDelta,
2215 WifiPhyState::IDLE} // IDLE just after the transmission ends
2216 },
2218 MicroSeconds(16),
2221 {ppduDurations.at(MHz_u{80}) - smallDelta,
2222 ppduDurations.at(MHz_u{80}),
2225 delay += Seconds(1);
2227
2228 //----------------------------------------------------------------------------------------------------------------------------------
2229 // Verify PHY notifies CCA-BUSY when a 80 MHz PPDU with received power above the CCA
2230 // sensitivity threshold occupies P40 The per20Bitmap should indicate CCA_BUSY for all
2231 // subchannels because received power is above -62 dBm (27.3.20.6.5).
2232 Simulator::Schedule(delay,
2234 this,
2235 "Reception of a 80 MHz PPDU that occupies the 40 MHz band above CCA "
2236 "sensitivity threshold");
2237 if (m_channelWidth > 20)
2238 {
2239 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(),
2240 2,
2241 ppduDurations.at(80) - aCcaTime);
2242 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(1).begin(),
2243 2,
2244 ppduDurations.at(80) - phyHeaderDuration);
2245 }
2247 delay,
2248 {},
2249 {{dBm_u{-55}, MicroSeconds(0), P80_CENTER_FREQUENCY, MHz_u{80}}},
2250 {
2251 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCcaTimeWithDelta
2252 {ppduDurations.at(MHz_u{80}) - smallDelta,
2253 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2254 {ppduDurations.at(MHz_u{80}) + smallDelta,
2255 WifiPhyState::IDLE} // IDLE just after the transmission ends
2256 },
2258 MicroSeconds(16),
2261 {ppduDurations.at(MHz_u{80}) - smallDelta,
2262 ppduDurations.at(MHz_u{80}),
2265 delay += Seconds(1);
2267
2268 //----------------------------------------------------------------------------------------------------------------------------------
2269 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal not
2270 // occupying the operational channel is being received
2272 delay,
2274 this,
2275 "Reception of a 40 MHz PPDU that does not occupy the operational channel");
2276 ScheduleTest(delay,
2277 {},
2278 {{dBm_u{-50}, MicroSeconds(0), S40_CENTER_FREQUENCY, MHz_u{40}}},
2279 {
2280 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2281 {ppduDurations.at(MHz_u{20}) - smallDelta,
2282 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2283 {ppduDurations.at(MHz_u{20}) + smallDelta,
2284 WifiPhyState::IDLE} // IDLE just after the transmission ends
2285 },
2286 {});
2287 delay += Seconds(1);
2288 }
2289
2290 if (m_channelWidth > MHz_u{80})
2291 {
2292 //----------------------------------------------------------------------------------------------------------------------------------
2293 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2294 // the energy detection threshold occupies the first 20 MHz subchannel of the S80
2295 Simulator::Schedule(delay,
2297 this,
2298 "Reception of a 20 MHz signal that occupies the first subchannel of "
2299 "S80 below ED threshold");
2300 ScheduleTest(delay,
2301 {{dBm_u{-65},
2302 MicroSeconds(0),
2303 MicroSeconds(100),
2305 MHz_u{20}}},
2306 {},
2307 {
2308 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2309 {MicroSeconds(100) - smallDelta,
2310 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2311 {MicroSeconds(100) + smallDelta,
2312 WifiPhyState::IDLE} // IDLE just after the transmission ends
2313 },
2314 {});
2315 delay += Seconds(1);
2316
2317 //----------------------------------------------------------------------------------------------------------------------------------
2318 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2319 // energy detection threshold occupies the first 20 MHz subchannel of the
2320 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2321 Simulator::Schedule(delay,
2323 this,
2324 "Reception of a 20 MHz signal that occupies the first subchannel of "
2325 "S80 above ED threshold");
2327 ScheduleTest(delay,
2328 {{dBm_u{-55},
2329 MicroSeconds(0),
2330 MicroSeconds(100),
2332 MHz_u{20}}},
2333 {},
2334 {
2335 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2336 {MicroSeconds(100) - smallDelta,
2337 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2338 {MicroSeconds(100) + smallDelta,
2339 WifiPhyState::IDLE} // IDLE just after the transmission ends
2340 },
2341 {{MicroSeconds(100) - smallDelta,
2342 MicroSeconds(100),
2345 delay += Seconds(1);
2347
2348 //----------------------------------------------------------------------------------------------------------------------------------
2349 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2350 // the energy detection threshold occupies the second 20 MHz subchannel of the S80
2351 Simulator::Schedule(delay,
2353 this,
2354 "Reception of a 20 MHz signal that occupies the second subchannel of "
2355 "S80 below ED threshold");
2356 ScheduleTest(delay,
2357 {{dBm_u{-65},
2358 MicroSeconds(0),
2359 MicroSeconds(100),
2361 MHz_u{20}}},
2362 {},
2363 {
2364 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2365 {MicroSeconds(100) - smallDelta,
2366 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2367 {MicroSeconds(100) + smallDelta,
2368 WifiPhyState::IDLE} // IDLE just after the transmission ends
2369 },
2370 {});
2371 delay += Seconds(1);
2372
2373 //----------------------------------------------------------------------------------------------------------------------------------
2374 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2375 // energy detection threshold occupies the second 20 MHz subchannel of the
2376 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2377 Simulator::Schedule(delay,
2379 this,
2380 "Reception of a 20 MHz signal that occupies the second subchannel of "
2381 "S80 above ED threshold");
2383 ScheduleTest(delay,
2384 {{dBm_u{-55},
2385 MicroSeconds(0),
2386 MicroSeconds(100),
2388 MHz_u{20}}},
2389 {},
2390 {
2391 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2392 {MicroSeconds(100) - smallDelta,
2393 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2394 {MicroSeconds(100) + smallDelta,
2395 WifiPhyState::IDLE} // IDLE just after the transmission ends
2396 },
2397 {{MicroSeconds(100) - smallDelta,
2398 MicroSeconds(100),
2401 delay += Seconds(1);
2403
2404 //----------------------------------------------------------------------------------------------------------------------------------
2405 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2406 // the energy detection threshold occupies the third 20 MHz subchannel of the S80
2407 Simulator::Schedule(delay,
2409 this,
2410 "Reception of a 20 MHz signal that occupies the third subchannel of "
2411 "S80 below ED threshold");
2412 ScheduleTest(delay,
2413 {{dBm_u{-65},
2414 MicroSeconds(0),
2415 MicroSeconds(100),
2417 MHz_u{20}}},
2418 {},
2419 {
2420 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2421 {MicroSeconds(100) - smallDelta,
2422 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2423 {MicroSeconds(100) + smallDelta,
2424 WifiPhyState::IDLE} // IDLE just after the transmission ends
2425 },
2426 {});
2427 delay += Seconds(1);
2428
2429 //----------------------------------------------------------------------------------------------------------------------------------
2430 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2431 // energy detection threshold occupies the third 20 MHz subchannel of the
2432 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2433 Simulator::Schedule(delay,
2435 this,
2436 "Reception of a 20 MHz signal that occupies the third subchannel of "
2437 "S80 above ED threshold");
2439 ScheduleTest(delay,
2440 {{dBm_u{-55},
2441 MicroSeconds(0),
2442 MicroSeconds(100),
2444 MHz_u{20}}},
2445 {},
2446 {
2447 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2448 {MicroSeconds(100) - smallDelta,
2449 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2450 {MicroSeconds(100) + smallDelta,
2451 WifiPhyState::IDLE} // IDLE just after the transmission ends
2452 },
2453 {{MicroSeconds(100) - smallDelta,
2454 MicroSeconds(100),
2457 delay += Seconds(1);
2459
2460 //----------------------------------------------------------------------------------------------------------------------------------
2461 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2462 // the energy detection threshold occupies the fourth 20 MHz subchannel of the S80
2463 Simulator::Schedule(delay,
2465 this,
2466 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
2467 "S80 below ED threshold");
2468 ScheduleTest(delay,
2469 {{dBm_u{-65},
2470 MicroSeconds(0),
2471 MicroSeconds(100),
2473 MHz_u{20}}},
2474 {},
2475 {
2476 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2477 {MicroSeconds(100) - smallDelta,
2478 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2479 {MicroSeconds(100) + smallDelta,
2480 WifiPhyState::IDLE} // IDLE just after the transmission ends
2481 },
2482 {});
2483 delay += Seconds(1);
2484
2485 //----------------------------------------------------------------------------------------------------------------------------------
2486 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2487 // energy detection threshold occupies the fourth 20 MHz subchannel of the
2488 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2489 Simulator::Schedule(delay,
2491 this,
2492 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
2493 "S80 above ED threshold");
2495 ScheduleTest(delay,
2496 {{dBm_u{-55},
2497 MicroSeconds(0),
2498 MicroSeconds(100),
2500 MHz_u{20}}},
2501 {},
2502 {
2503 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2504 {MicroSeconds(100) - smallDelta,
2505 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2506 {MicroSeconds(100) + smallDelta,
2507 WifiPhyState::IDLE} // IDLE just after the transmission ends
2508 },
2509 {{MicroSeconds(100) - smallDelta,
2510 MicroSeconds(100),
2513 delay += Seconds(1);
2515
2516 //----------------------------------------------------------------------------------------------------------------------------------
2517 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2518 // the energy detection threshold occupies the first and second 20 MHz subchannels of
2519 // the S80
2520 Simulator::Schedule(delay,
2522 this,
2523 "Reception of a 40 MHz signal that occupies the first and second "
2524 "subchannels of S80 below ED threshold");
2525 ScheduleTest(delay,
2526 {{dBm_u{-65},
2527 MicroSeconds(0),
2528 MicroSeconds(100),
2530 MHz_u{40}}},
2531 {},
2532 {
2533 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2534 {MicroSeconds(100) - smallDelta,
2535 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2536 {MicroSeconds(100) + smallDelta,
2537 WifiPhyState::IDLE} // IDLE just after the transmission ends
2538 },
2539 {});
2540 delay += Seconds(1);
2541
2542 //----------------------------------------------------------------------------------------------------------------------------------
2543 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2544 // energy detection threshold occupies the first and second 20 MHz subchannels of the
2545 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2546 Simulator::Schedule(delay,
2548 this,
2549 "Reception of a 40 MHz signal that occupies the first and second "
2550 "subchannels of S80 above ED threshold");
2551 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 4, 2, MicroSeconds(100));
2552 ScheduleTest(delay,
2553 {{dBm_u{-55},
2554 MicroSeconds(0),
2555 MicroSeconds(100),
2557 MHz_u{40}}},
2558 {},
2559 {
2560 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2561 {MicroSeconds(100) - smallDelta,
2562 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2563 {MicroSeconds(100) + smallDelta,
2564 WifiPhyState::IDLE} // IDLE just after the transmission ends
2565 },
2566 {{MicroSeconds(100) - smallDelta,
2567 MicroSeconds(100),
2570 delay += Seconds(1);
2572
2573 //----------------------------------------------------------------------------------------------------------------------------------
2574 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2575 // the energy detection threshold occupies the third and fourth 20 MHz subchannels of
2576 // the S80
2577 Simulator::Schedule(delay,
2579 this,
2580 "Reception of a 40 MHz signal that occupies the third and fourth "
2581 "subchannels of S80 below ED threshold");
2582 ScheduleTest(delay,
2583 {{dBm_u{-65},
2584 MicroSeconds(0),
2585 MicroSeconds(100),
2587 MHz_u{40}}},
2588 {},
2589 {
2590 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2591 {MicroSeconds(100) - smallDelta,
2592 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2593 {MicroSeconds(100) + smallDelta,
2594 WifiPhyState::IDLE} // IDLE just after the transmission ends
2595 },
2596 {});
2597 delay += Seconds(1);
2598
2599 //----------------------------------------------------------------------------------------------------------------------------------
2600 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2601 // energy detection threshold occupies the third and fourth 20 MHz subchannels of the
2602 // S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or above –56 dBm.
2603 Simulator::Schedule(delay,
2605 this,
2606 "Reception of a 40 MHz signal that occupies the third and fourth "
2607 "subchannels of S80 above ED threshold");
2608 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 6, 2, MicroSeconds(100));
2609 ScheduleTest(delay,
2610 {{dBm_u{-55},
2611 MicroSeconds(0),
2612 MicroSeconds(100),
2614 MHz_u{40}}},
2615 {},
2616 {
2617 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2618 {MicroSeconds(100) - smallDelta,
2619 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2620 {MicroSeconds(100) + smallDelta,
2621 WifiPhyState::IDLE} // IDLE just after the transmission ends
2622 },
2623 {{MicroSeconds(100) - smallDelta,
2624 MicroSeconds(100),
2627 delay += Seconds(1);
2629
2630 //----------------------------------------------------------------------------------------------------------------------------------
2631 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2632 // the energy detection threshold occupies the S80
2633 Simulator::Schedule(delay,
2635 this,
2636 "Reception of a 80 MHz signal that occupies S80 below ED threshold");
2638 delay,
2639 {{dBm_u{-65}, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY, MHz_u{80}}},
2640 {},
2641 {
2642 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2643 {MicroSeconds(100) - smallDelta,
2644 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2645 {MicroSeconds(100) + smallDelta,
2646 WifiPhyState::IDLE} // IDLE just after the transmission ends
2647 },
2648 {});
2649 delay += Seconds(1);
2650
2651 //----------------------------------------------------------------------------------------------------------------------------------
2652 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2653 // energy detection threshold occupies the S80 27.3.20.6.4: Any signal within the
2654 // secondary 80 MHz channel at or above –56 dBm.
2655 Simulator::Schedule(delay,
2657 this,
2658 "Reception of a 80 MHz signal that occupies S80 above ED threshold");
2659 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 4, 4, MicroSeconds(100));
2661 delay,
2662 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), S80_CENTER_FREQUENCY, MHz_u{80}}},
2663 {},
2664 {
2665 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2666 {MicroSeconds(100) - smallDelta,
2667 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2668 {MicroSeconds(100) + smallDelta,
2669 WifiPhyState::IDLE} // IDLE just after the transmission ends
2670 },
2671 {{MicroSeconds(100) - smallDelta,
2672 MicroSeconds(100),
2675 delay += Seconds(1);
2677
2678 //----------------------------------------------------------------------------------------------------------------------------------
2679 // Verify PHY state stays IDLE as long as a 160 MHz signal below the energy detection
2680 // threshold occupies the whole band
2682 delay,
2684 this,
2685 "Reception of a 160 MHz signal that occupies the whole band below ED threshold");
2687 delay,
2688 {{dBm_u{-55}, MicroSeconds(0), MicroSeconds(100), P160_CENTER_FREQUENCY, MHz_u{160}}},
2689 {},
2690 {
2691 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2692 {MicroSeconds(100) - smallDelta,
2693 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2694 {MicroSeconds(100) + smallDelta,
2695 WifiPhyState::IDLE} // IDLE just after the transmission ends
2696 },
2697 {});
2698
2699 delay += Seconds(1);
2700
2701 //----------------------------------------------------------------------------------------------------------------------------------
2702 // Verify PHY state is CCA-BUSY as long as a 160 MHz signal above the energy detection
2703 // threshold occupies the whole band
2705 delay,
2707 this,
2708 "Reception of a 160 MHz signal that occupies the whole band above ED threshold");
2709 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 8, MicroSeconds(100));
2711 delay,
2712 {{dBm_u{-50}, MicroSeconds(0), MicroSeconds(100), P160_CENTER_FREQUENCY, MHz_u{160}}},
2713 {},
2714 {
2715 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
2716 {MicroSeconds(100) - smallDelta,
2717 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2718 {MicroSeconds(100) + smallDelta,
2719 WifiPhyState::IDLE} // IDLE just after the transmission ends
2720 },
2721 {{MicroSeconds(100) - smallDelta,
2722 MicroSeconds(100),
2725 delay += Seconds(1);
2727
2728 //----------------------------------------------------------------------------------------------------------------------------------
2729 // Verify PHY notifies CCA-BUSY for the P20 channel while the S80 channel was already in
2730 // CCA-BUSY state
2731 Simulator::Schedule(delay,
2733 this,
2734 "Reception of a 20 MHz signal that occupies S80 followed by the "
2735 "reception of another 20 MHz signal that occupies P20");
2740 delay,
2741 {{dBm_u{-55},
2742 MicroSeconds(0),
2743 MicroSeconds(100),
2745 MHz_u{20}},
2746 {dBm_u{-55}, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
2747 {},
2748 {
2750 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2752 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
2753 // aCcaTimeWithDelta that followed the second
2754 // transmission
2755 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2756 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2757 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2758 WifiPhyState::IDLE} // IDLE just after the transmission ends
2759 },
2760 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2761 MicroSeconds(100),
2764 {MicroSeconds(50) +
2765 aCcaTimeWithDelta, // notification upon reception of the second signal
2766 MicroSeconds(50) + MicroSeconds(100),
2769 delay += Seconds(1);
2771
2772 //----------------------------------------------------------------------------------------------------------------------------------
2773 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S40 channel while the S80
2774 // channel was already in CCA-BUSY state
2775 Simulator::Schedule(delay,
2777 this,
2778 "Reception of a signal that occupies S80 followed by the reception of "
2779 "another signal that occupies S40");
2784 delay,
2785 {{dBm_u{-55},
2786 MicroSeconds(0),
2787 MicroSeconds(100),
2789 MHz_u{20}},
2790 {dBm_u{-55},
2791 MicroSeconds(50),
2792 MicroSeconds(100),
2794 MHz_u{20}}},
2795 {},
2796 {
2798 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2800 WifiPhyState::IDLE}, // state of primary stays IDLE
2801 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2802 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2803 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2804 WifiPhyState::IDLE} // IDLE just after the transmission ends
2805 },
2806 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2807 MicroSeconds(100),
2810 {MicroSeconds(50) +
2811 aCcaTimeWithDelta, // notification upon reception of the second signal
2812 MicroSeconds(50) + MicroSeconds(100),
2815 delay += Seconds(1);
2817
2818 //----------------------------------------------------------------------------------------------------------------------------------
2819 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S80
2820 // channel was already in CCA-BUSY state
2821 Simulator::Schedule(delay,
2823 this,
2824 "Reception of a signal that occupies S80 followed by the reception of "
2825 "another signal that occupies S20");
2830 delay,
2831 {{dBm_u{-55},
2832 MicroSeconds(0),
2833 MicroSeconds(100),
2835 MHz_u{20}},
2836 {dBm_u{-55}, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
2837 {},
2838 {
2840 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2842 WifiPhyState::IDLE}, // state of primary stays IDLE
2843 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
2844 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2845 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
2846 WifiPhyState::IDLE} // IDLE just after the transmission ends
2847 },
2848 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2849 MicroSeconds(100),
2852 {MicroSeconds(50) +
2853 aCcaTimeWithDelta, // notification upon reception of the second signal
2854 MicroSeconds(50) + MicroSeconds(100),
2857 delay += Seconds(1);
2859
2860 //----------------------------------------------------------------------------------------------------------------------------------
2861 // Verify PHY state stays IDLE when a 80 MHz PPDU with received power below the CCA
2862 // sensitivity threshold occupies S80
2864 delay,
2866 this,
2867 "Reception of a 80 MHz PPDU that occupies S80 below CCA sensitivity threshold");
2868 ScheduleTest(delay,
2869 {},
2870 {{dBm_u{-70}, MicroSeconds(0), S80_CENTER_FREQUENCY, MHz_u{80}}},
2871 {
2872 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2873 {ppduDurations.at(MHz_u{80}) - smallDelta,
2874 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2875 {ppduDurations.at(MHz_u{80}) + smallDelta,
2876 WifiPhyState::IDLE} // IDLE just after the transmission ends
2877 },
2878 {});
2879 delay += Seconds(1);
2880
2881 //----------------------------------------------------------------------------------------------------------------------------------
2882 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 80 MHz PPDU
2883 // with received power above the CCA sensitivity threshold occupies S80
2885 delay,
2887 this,
2888 "Reception of a 80 MHz PPDU that occupies S80 above CCA sensitivity threshold");
2889 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 4, 4, ppduDurations.at(80));
2890 ScheduleTest(delay,
2891 {},
2892 {{dBm_u{-65}, MicroSeconds(0), S80_CENTER_FREQUENCY, MHz_u{80}}},
2893 {
2894 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2895 {ppduDurations.at(MHz_u{80}) - smallDelta,
2896 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2897 {ppduDurations.at(MHz_u{80}) + smallDelta,
2898 WifiPhyState::IDLE} // IDLE just after the transmission ends
2899 },
2901 ppduDurations.at(MHz_u{80}),
2904 delay += Seconds(1);
2906
2908 {
2909 //----------------------------------------------------------------------------------------------------------------------------------
2910 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if only the
2911 // per20bitmap parameter changes
2913 delay,
2915 this,
2916 "Reception of a 20 MHz signal that generates a per20bitmap parameter "
2917 "change when previous CCA indication reports IDLE");
2920 delay,
2921 {{dBm_u{-60.0},
2922 MicroSeconds(0),
2923 MicroSeconds(100),
2925 MHz_u{20}}},
2926 {},
2927 {
2928 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2929 {MicroSeconds(100) - smallDelta,
2930 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2931 {MicroSeconds(100) + smallDelta,
2932 WifiPhyState::IDLE} // IDLE just after the transmission ends
2933 },
2935 Seconds(0),
2938 delay += Seconds(1);
2940
2941 //----------------------------------------------------------------------------------------------------------------------------------
2942 // Verify PHY state stays CCA_BUSY and CCA-BUSY indication is reported if only the
2943 // per20bitmap parameter changes
2944 Simulator::Schedule(delay,
2946 this,
2947 "Reception of a 20 MHz signal that generates a per20bitmap "
2948 "parameter change when "
2949 "previous CCA indication reports BUSY for the primary channel");
2950 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 4, MicroSeconds(100));
2951 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(1).begin(), 4, MicroSeconds(50));
2954 delay,
2955 {{dBm_u{-50.0},
2956 MicroSeconds(0),
2957 MicroSeconds(100),
2959 MHz_u{80}},
2960 {dBm_u{-60.0},
2961 MicroSeconds(50),
2962 MicroSeconds(200),
2964 MHz_u{20}}},
2965 {},
2966 {
2967 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
2968 {MicroSeconds(100) - smallDelta,
2969 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2970 {MicroSeconds(100) + smallDelta,
2971 WifiPhyState::IDLE} // IDLE just after the transmission ends
2972 },
2974 MicroSeconds(100),
2977 {MicroSeconds(50) +
2978 aCcaTimeWithDelta, // notification upon reception of the second signal
2979 MicroSeconds(100),
2982 delay += Seconds(1);
2984 }
2985 }
2986
2987 if (m_channelWidth > 160)
2988 {
2989 //----------------------------------------------------------------------------------------------------------------------------------
2990 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
2991 // the energy detection threshold occupies the first 20 MHz subchannel of the S160
2992 Simulator::Schedule(delay,
2994 this,
2995 "Reception of a 20 MHz signal that occupies the first subchannel of "
2996 "S160 below ED threshold");
2997 ScheduleTest(delay,
2998 {{-65.0,
2999 MicroSeconds(0),
3000 MicroSeconds(100),
3002 MHz_u{20}}},
3003 {},
3004 {
3005 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3006 {MicroSeconds(100) - smallDelta,
3007 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3008 {MicroSeconds(100) + smallDelta,
3009 WifiPhyState::IDLE} // IDLE just after the transmission ends
3010 },
3011 {});
3012 delay += Seconds(1.0);
3013
3014 //----------------------------------------------------------------------------------------------------------------------------------
3015 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3016 // energy detection threshold occupies the first 20 MHz subchannel of the S160.
3017 // 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at or above a
3018 // threshold of –62 dBm. (...)
3019 Simulator::Schedule(delay,
3021 this,
3022 "Reception of a 20 MHz signal that occupies the first subchannel of "
3023 "S160 above ED threshold");
3025 ScheduleTest(delay,
3026 {{-61.0,
3027 MicroSeconds(0),
3028 MicroSeconds(100),
3030 MHz_u{20}}},
3031 {},
3032 {
3033 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3034 {MicroSeconds(100) - smallDelta,
3035 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3036 {MicroSeconds(100) + smallDelta,
3037 WifiPhyState::IDLE} // IDLE just after the transmission ends
3038 },
3039 {{MicroSeconds(100) - smallDelta,
3040 MicroSeconds(100),
3043 delay += Seconds(1.0);
3045
3046 //----------------------------------------------------------------------------------------------------------------------------------
3047 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
3048 // the energy detection threshold occupies the second 20 MHz subchannel of the S80
3049 Simulator::Schedule(delay,
3051 this,
3052 "Reception of a 20 MHz signal that occupies the second subchannel of "
3053 "S160 below ED threshold");
3054 ScheduleTest(delay,
3055 {{-65.0,
3056 MicroSeconds(0),
3057 MicroSeconds(100),
3059 MHz_u{20}}},
3060 {},
3061 {
3062 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3063 {MicroSeconds(100) - smallDelta,
3064 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3065 {MicroSeconds(100) + smallDelta,
3066 WifiPhyState::IDLE} // IDLE just after the transmission ends
3067 },
3068 {});
3069 delay += Seconds(1.0);
3070
3071 //----------------------------------------------------------------------------------------------------------------------------------
3072 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3073 // energy detection threshold occupies the second 20 MHz subchannel of the
3074 // S160 27.3.20.6.4: 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at
3075 // or above a threshold of –62 dBm. (...)
3076 Simulator::Schedule(delay,
3078 this,
3079 "Reception of a 20 MHz signal that occupies the second subchannel of "
3080 "S160 above ED threshold");
3082 ScheduleTest(delay,
3083 {{-61.0,
3084 MicroSeconds(0),
3085 MicroSeconds(100),
3087 MHz_u{20}}},
3088 {},
3089 {
3090 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3091 {MicroSeconds(100) - smallDelta,
3092 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3093 {MicroSeconds(100) + smallDelta,
3094 WifiPhyState::IDLE} // IDLE just after the transmission ends
3095 },
3096 {{MicroSeconds(100) - smallDelta,
3097 MicroSeconds(100),
3100 delay += Seconds(1.0);
3102
3103 //----------------------------------------------------------------------------------------------------------------------------------
3104 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
3105 // the energy detection threshold occupies the third 20 MHz subchannel of the S80
3106 Simulator::Schedule(delay,
3108 this,
3109 "Reception of a 20 MHz signal that occupies the third subchannel of "
3110 "S160 below ED threshold");
3111 ScheduleTest(delay,
3112 {{-65.0,
3113 MicroSeconds(0),
3114 MicroSeconds(100),
3116 MHz_u{20}}},
3117 {},
3118 {
3119 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3120 {MicroSeconds(100) - smallDelta,
3121 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3122 {MicroSeconds(100) + smallDelta,
3123 WifiPhyState::IDLE} // IDLE just after the transmission ends
3124 },
3125 {});
3126 delay += Seconds(1.0);
3127
3128 //----------------------------------------------------------------------------------------------------------------------------------
3129 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3130 // energy detection threshold occupies the third 20 MHz subchannel of the
3131 // S160 27.3.20.6.4: 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at
3132 // or above a threshold of –62 dBm. (...)
3133 Simulator::Schedule(delay,
3135 this,
3136 "Reception of a 20 MHz signal that occupies the third subchannel of "
3137 "S160 above ED threshold");
3139 ScheduleTest(delay,
3140 {{-61.0,
3141 MicroSeconds(0),
3142 MicroSeconds(100),
3144 MHz_u{20}}},
3145 {},
3146 {
3147 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3148 {MicroSeconds(100) - smallDelta,
3149 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3150 {MicroSeconds(100) + smallDelta,
3151 WifiPhyState::IDLE} // IDLE just after the transmission ends
3152 },
3153 {{MicroSeconds(100) - smallDelta,
3154 MicroSeconds(100),
3157 delay += Seconds(1.0);
3159
3160 //----------------------------------------------------------------------------------------------------------------------------------
3161 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below
3162 // the energy detection threshold occupies the fourth 20 MHz subchannel of the S80
3163 Simulator::Schedule(delay,
3165 this,
3166 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
3167 "S160 below ED threshold");
3168 ScheduleTest(delay,
3169 {{-65.0,
3170 MicroSeconds(0),
3171 MicroSeconds(100),
3173 MHz_u{20}}},
3174 {},
3175 {
3176 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3177 {MicroSeconds(100) - smallDelta,
3178 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3179 {MicroSeconds(100) + smallDelta,
3180 WifiPhyState::IDLE} // IDLE just after the transmission ends
3181 },
3182 {});
3183 delay += Seconds(1.0);
3184
3185 //----------------------------------------------------------------------------------------------------------------------------------
3186 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3187 // energy detection threshold occupies the fourth 20 MHz subchannel of the
3188 // S160 27.3.20.6.4: 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at
3189 // or above a threshold of –62 dBm. (...)
3190 Simulator::Schedule(delay,
3192 this,
3193 "Reception of a 20 MHz signal that occupies the fourth subchannel of "
3194 "S160 above ED threshold");
3196 ScheduleTest(delay,
3197 {{-61.0,
3198 MicroSeconds(0),
3199 MicroSeconds(100),
3201 MHz_u{20}}},
3202 {},
3203 {
3204 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3205 {MicroSeconds(100) - smallDelta,
3206 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3207 {MicroSeconds(100) + smallDelta,
3208 WifiPhyState::IDLE} // IDLE just after the transmission ends
3209 },
3210 {{MicroSeconds(100) - smallDelta,
3211 MicroSeconds(100),
3214 delay += Seconds(1.0);
3216
3217 //----------------------------------------------------------------------------------------------------------------------------------
3218 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3219 // occupies the fifth and sixth 20 MHz subchannels of the S160 with received power below
3220 // the energy detection threshold for all occupied 20 MHz subchannels
3221 Simulator::Schedule(delay,
3223 this,
3224 "Reception of a 40 MHz signal that occupies the fifth and sixth "
3225 "subchannels of S160 below ED threshold");
3226 ScheduleTest(delay,
3227 {{-60.0,
3228 MicroSeconds(0),
3229 MicroSeconds(100),
3231 MHz_u{40}}},
3232 {},
3233 {
3234 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3235 {MicroSeconds(100) - smallDelta,
3236 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3237 {MicroSeconds(100) + smallDelta,
3238 WifiPhyState::IDLE} // IDLE just after the transmission ends
3239 },
3240 {});
3241 delay += Seconds(1.0);
3242
3243 //----------------------------------------------------------------------------------------------------------------------------------
3244 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3245 // occupies the fifth and sixth 20 MHz subchannels of the S160 with received power above
3246 // the energy detection threshold for any occupied 20 MHz subchannels
3247 Simulator::Schedule(delay,
3249 this,
3250 "Reception of a 40 MHz signal that occupies the fifth and sixth "
3251 "subchannels of S160 above ED threshold");
3252 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 12, 2, MicroSeconds(100));
3253 ScheduleTest(delay,
3254 {{-58.0,
3255 MicroSeconds(0),
3256 MicroSeconds(100),
3258 MHz_u{40}}},
3259 {},
3260 {
3261 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3262 {MicroSeconds(100) - smallDelta,
3263 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3264 {MicroSeconds(100) + smallDelta,
3265 WifiPhyState::IDLE} // IDLE just after the transmission ends
3266 },
3267 {{MicroSeconds(100) - smallDelta,
3268 MicroSeconds(100),
3271 delay += Seconds(1.0);
3273
3274 //----------------------------------------------------------------------------------------------------------------------------------
3275 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3276 // occupies the seventh and eighth 20 MHz subchannels of the S160 with received power
3277 // below the energy detection threshold for all occupied 20 MHz subchannels
3278 Simulator::Schedule(delay,
3280 this,
3281 "Reception of a 40 MHz signal that occupies the seventh and eighth "
3282 "subchannels of S160 below ED threshold");
3283 ScheduleTest(delay,
3284 {{-60.0,
3285 MicroSeconds(0),
3286 MicroSeconds(100),
3288 MHz_u{40}}},
3289 {},
3290 {
3291 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3292 {MicroSeconds(100) - smallDelta,
3293 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3294 {MicroSeconds(100) + smallDelta,
3295 WifiPhyState::IDLE} // IDLE just after the transmission ends
3296 },
3297 {});
3298 delay += Seconds(1.0);
3299
3300 //----------------------------------------------------------------------------------------------------------------------------------
3301 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3302 // occupies the seventh and eighth 20 MHz subchannels of the S160 with received power
3303 // above the energy detection threshold for any occupied 20 MHz subchannels
3304 Simulator::Schedule(delay,
3306 this,
3307 "Reception of a 40 MHz signal that occupies the seventh and eighth "
3308 "subchannels of S160 above ED threshold");
3309 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 14, 2, MicroSeconds(100));
3310 ScheduleTest(delay,
3311 {{-58.0,
3312 MicroSeconds(0),
3313 MicroSeconds(100),
3315 MHz_u{40}}},
3316 {},
3317 {
3318 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3319 {MicroSeconds(100) - smallDelta,
3320 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3321 {MicroSeconds(100) + smallDelta,
3322 WifiPhyState::IDLE} // IDLE just after the transmission ends
3323 },
3324 {{MicroSeconds(100) - smallDelta,
3325 MicroSeconds(100),
3328 delay += Seconds(1.0);
3330
3331 //----------------------------------------------------------------------------------------------------------------------------------
3332 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3333 // occupies the first four 20 MHz subchannels of the S160 with received power below the
3334 // energy detection threshold for all occupied 20 MHz subchannels
3335 Simulator::Schedule(delay,
3337 this,
3338 "Reception of a 80 MHz signal that occupies the first four "
3339 "subchannels of S160 below ED threshold");
3340 ScheduleTest(delay,
3341 {{-57.0,
3342 MicroSeconds(0),
3343 MicroSeconds(100),
3345 MHz_u{80}}},
3346 {},
3347 {
3348 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3349 {MicroSeconds(100) - smallDelta,
3350 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3351 {MicroSeconds(100) + smallDelta,
3352 WifiPhyState::IDLE} // IDLE just after the transmission ends
3353 },
3354 {});
3355 delay += Seconds(1.0);
3356
3357 //----------------------------------------------------------------------------------------------------------------------------------
3358 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3359 // occupies the first four 20 MHz subchannels of the S160 with received power above the
3360 // energy detection threshold for any occupied 20 MHz subchannels
3361 Simulator::Schedule(delay,
3363 this,
3364 "Reception of a 80 MHz signal that occupies the first four "
3365 "subchannels of S160 above ED threshold");
3366 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 8, 4, MicroSeconds(100));
3367 ScheduleTest(delay,
3368 {{-55.0,
3369 MicroSeconds(0),
3370 MicroSeconds(100),
3372 MHz_u{80}}},
3373 {},
3374 {
3375 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3376 {MicroSeconds(100) - smallDelta,
3377 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3378 {MicroSeconds(100) + smallDelta,
3379 WifiPhyState::IDLE} // IDLE just after the transmission ends
3380 },
3381 {{MicroSeconds(100) - smallDelta,
3382 MicroSeconds(100),
3385 delay += Seconds(1.0);
3387
3388 //----------------------------------------------------------------------------------------------------------------------------------
3389 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3390 // occupies the last four 20 MHz subchannels of the S160 with received power below the
3391 // energy detection threshold for all occupied 20 MHz subchannels
3392 Simulator::Schedule(delay,
3394 this,
3395 "Reception of a 80 MHz signal that occupies the last four "
3396 "subchannels of S160 below ED threshold");
3397 ScheduleTest(delay,
3398 {{-57.0,
3399 MicroSeconds(0),
3400 MicroSeconds(100),
3402 MHz_u{80}}},
3403 {},
3404 {
3405 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3406 {MicroSeconds(100) - smallDelta,
3407 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3408 {MicroSeconds(100) + smallDelta,
3409 WifiPhyState::IDLE} // IDLE just after the transmission ends
3410 },
3411 {});
3412 delay += Seconds(1.0);
3413
3414 //----------------------------------------------------------------------------------------------------------------------------------
3415 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3416 // occupies the last four 20 MHz subchannels of the S160 with received power above the
3417 // energy detection threshold for any occupied 20 MHz subchannels
3418 Simulator::Schedule(delay,
3420 this,
3421 "Reception of a 80 MHz signal that occupies the last four "
3422 "subchannels of S160 above ED threshold");
3423 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 12, 4, MicroSeconds(100));
3424 ScheduleTest(delay,
3425 {{-55.0,
3426 MicroSeconds(0),
3427 MicroSeconds(100),
3429 MHz_u{80}}},
3430 {},
3431 {
3432 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3433 {MicroSeconds(100) - smallDelta,
3434 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3435 {MicroSeconds(100) + smallDelta,
3436 WifiPhyState::IDLE} // IDLE just after the transmission ends
3437 },
3438 {{MicroSeconds(100) - smallDelta,
3439 MicroSeconds(100),
3442 delay += Seconds(1.0);
3444
3445 //----------------------------------------------------------------------------------------------------------------------------------
3446 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3447 // occupies the whole S160 with received power below the energy detection threshold for
3448 // all occupied 20 MHz subchannels
3450 delay,
3452 this,
3453 "Reception of a 160 MHz signal that occupies the whole S160 below ED threshold");
3455 delay,
3456 {{-54.0, MicroSeconds(0), MicroSeconds(100), S160_CENTER_FREQUENCY, MHz_u{160}}},
3457 {},
3458 {
3459 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3460 {MicroSeconds(100) - smallDelta,
3461 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3462 {MicroSeconds(100) + smallDelta,
3463 WifiPhyState::IDLE} // IDLE just after the transmission ends
3464 },
3465 {});
3466 delay += Seconds(1.0);
3467
3468 //----------------------------------------------------------------------------------------------------------------------------------
3469 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3470 // occupies the whole S160 with received power above the energy detection threshold for
3471 // any occupied 20 MHz subchannels
3473 delay,
3475 this,
3476 "Reception of a 160 MHz signal that occupies the whole S160 above ED threshold");
3477 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 8, 8, MicroSeconds(100));
3479 delay,
3480 {{-52.0, MicroSeconds(0), MicroSeconds(100), S160_CENTER_FREQUENCY, MHz_u{160}}},
3481 {},
3482 {
3483 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3484 {MicroSeconds(100) - smallDelta,
3485 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3486 {MicroSeconds(100) + smallDelta,
3487 WifiPhyState::IDLE} // IDLE just after the transmission ends
3488 },
3489 {{MicroSeconds(100) - smallDelta,
3490 MicroSeconds(100),
3493 delay += Seconds(1.0);
3495
3496 //----------------------------------------------------------------------------------------------------------------------------------
3497 // Verify PHY state stays IDLE as long as a 320 MHz signal below the energy detection
3498 // threshold occupies the whole band
3500 delay,
3502 this,
3503 "Reception of a 320 MHz signal that occupies the whole band below ED threshold");
3505 delay,
3506 {{-51.0, MicroSeconds(0), MicroSeconds(100), P320_CENTER_FREQUENCY, MHz_u{320}}},
3507 {},
3508 {
3509 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3510 {MicroSeconds(100) - smallDelta,
3511 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3512 {MicroSeconds(100) + smallDelta,
3513 WifiPhyState::IDLE} // IDLE just after the transmission ends
3514 },
3515 {});
3516
3517 delay += Seconds(1.0);
3518
3519 //----------------------------------------------------------------------------------------------------------------------------------
3520 // Verify PHY state is CCA-BUSY as long as a 320 MHz signal above the energy detection
3521 // threshold occupies the whole band
3523 delay,
3525 this,
3526 "Reception of a 320 MHz signal that occupies the whole band above ED threshold");
3527 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 16, MicroSeconds(100));
3529 delay,
3530 {{-49.0, MicroSeconds(0), MicroSeconds(100), P320_CENTER_FREQUENCY, MHz_u{320}}},
3531 {},
3532 {
3533 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
3534 {MicroSeconds(100) - smallDelta,
3535 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
3536 {MicroSeconds(100) + smallDelta,
3537 WifiPhyState::IDLE} // IDLE just after the transmission ends
3538 },
3539 {{MicroSeconds(100) - smallDelta,
3540 MicroSeconds(100),
3543 delay += Seconds(1.0);
3545
3546 //----------------------------------------------------------------------------------------------------------------------------------
3547 // Verify PHY notifies CCA-BUSY for the P20 channel while the S160 channel was already
3548 // in CCA-BUSY state
3549 Simulator::Schedule(delay,
3551 this,
3552 "Reception of a 20 MHz signal that occupies S160 followed by the "
3553 "reception of another 20 MHz signal that occupies P20");
3558 delay,
3559 {{-52.0,
3560 MicroSeconds(0),
3561 MicroSeconds(100),
3563 MHz_u{20}},
3564 {-52.0, MicroSeconds(50), MicroSeconds(100), P20_CENTER_FREQUENCY, MHz_u{20}}},
3565 {},
3566 {
3568 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3570 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
3571 // aCcaTimeWithDelta that followed the second
3572 // transmission
3573 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
3574 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
3575 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
3576 WifiPhyState::IDLE} // IDLE just after the transmission ends
3577 },
3578 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3579 MicroSeconds(100),
3582 {MicroSeconds(50) +
3583 aCcaTimeWithDelta, // notification upon reception of the second signal
3584 MicroSeconds(50) + MicroSeconds(100),
3587 delay += Seconds(1.0);
3589
3590 //----------------------------------------------------------------------------------------------------------------------------------
3591 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S80 channel while the S160
3592 // channel was already in CCA-BUSY state
3593 Simulator::Schedule(delay,
3595 this,
3596 "Reception of a signal that occupies S160 followed by the reception of "
3597 "another signal that occupies S80");
3602 delay,
3603 {{-52.0,
3604 MicroSeconds(0),
3605 MicroSeconds(100),
3607 MHz_u{20}},
3608 {-52.0,
3609 MicroSeconds(50),
3610 MicroSeconds(100),
3612 MHz_u{20}}},
3613 {},
3614 {
3616 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3618 WifiPhyState::IDLE}, // state of primary stays IDLE
3619 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
3620 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3621 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
3622 WifiPhyState::IDLE} // IDLE just after the transmission ends
3623 },
3624 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3625 MicroSeconds(100),
3628 {MicroSeconds(50) +
3629 aCcaTimeWithDelta, // notification upon reception of the second signal
3630 MicroSeconds(50) + MicroSeconds(100),
3633 delay += Seconds(1.0);
3635
3636 //----------------------------------------------------------------------------------------------------------------------------------
3637 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S40 channel while the S160
3638 // channel was already in CCA-BUSY state
3639 Simulator::Schedule(delay,
3641 this,
3642 "Reception of a signal that occupies S160 followed by the reception of "
3643 "another signal that occupies S40");
3648 delay,
3649 {{-52.0,
3650 MicroSeconds(0),
3651 MicroSeconds(100),
3653 MHz_u{20}},
3654 {-52.0,
3655 MicroSeconds(50),
3656 MicroSeconds(100),
3658 MHz_u{20}}},
3659 {},
3660 {
3662 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3664 WifiPhyState::IDLE}, // state of primary stays IDLE
3665 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
3666 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3667 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
3668 WifiPhyState::IDLE} // IDLE just after the transmission ends
3669 },
3670 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3671 MicroSeconds(100),
3674 {MicroSeconds(50) +
3675 aCcaTimeWithDelta, // notification upon reception of the second signal
3676 MicroSeconds(50) + MicroSeconds(100),
3679 delay += Seconds(1.0);
3681
3682 //----------------------------------------------------------------------------------------------------------------------------------
3683 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S160
3684 // channel was already in CCA-BUSY state
3685 Simulator::Schedule(delay,
3687 this,
3688 "Reception of a signal that occupies S160 followed by the reception of "
3689 "another signal that occupies S20");
3694 delay,
3695 {{-52.0,
3696 MicroSeconds(0),
3697 MicroSeconds(100),
3699 MHz_u{20}},
3700 {-52.0, MicroSeconds(50), MicroSeconds(100), S20_CENTER_FREQUENCY, MHz_u{20}}},
3701 {},
3702 {
3704 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3706 WifiPhyState::IDLE}, // state of primary stays IDLE
3707 {MicroSeconds(50) + MicroSeconds(100) - smallDelta,
3708 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3709 {MicroSeconds(50) + MicroSeconds(100) + smallDelta,
3710 WifiPhyState::IDLE} // IDLE just after the transmission ends
3711 },
3712 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3713 MicroSeconds(100),
3716 {MicroSeconds(50) +
3717 aCcaTimeWithDelta, // notification upon reception of the second signal
3718 MicroSeconds(50) + MicroSeconds(100),
3721 delay += Seconds(1.0);
3723
3724 //----------------------------------------------------------------------------------------------------------------------------------
3725 // Verify PHY state stays IDLE when a 160 MHz PPDU that occupies S160 with received
3726 // power below the Per 20 MHz CCA threshold for all occupied 20 MHz subchannels
3728 delay,
3730 this,
3731 "Reception of a 160 MHz PPDU that occupies S160 below CCA sensitivity threshold");
3732 ScheduleTest(delay,
3733 {},
3734 {{-64.0, MicroSeconds(0), S160_CENTER_FREQUENCY, MHz_u{160}}},
3735 {
3736 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3737 {ppduDurations.at(160) - smallDelta,
3738 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3739 {ppduDurations.at(160) + smallDelta,
3740 WifiPhyState::IDLE} // IDLE just after the transmission ends
3741 },
3742 {});
3743 delay += Seconds(1.0);
3744
3745 //----------------------------------------------------------------------------------------------------------------------------------
3746 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 160 MHz PPDU
3747 // that occupies S160 with received power above the Per 20 MHz CCA threshold for any
3748 // occupied 20 MHz subchannels
3750 delay,
3752 this,
3753 "Reception of a 160 MHz PPDU that occupies S160 above CCA sensitivity threshold");
3754 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 8, 8, ppduDurations.at(160));
3755 ScheduleTest(delay,
3756 {},
3757 {{-62.0, MicroSeconds(0), S160_CENTER_FREQUENCY, MHz_u{160}}},
3758 {
3759 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3760 {ppduDurations.at(160) - smallDelta,
3761 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3762 {ppduDurations.at(160) + smallDelta,
3763 WifiPhyState::IDLE} // IDLE just after the transmission ends
3764 },
3766 ppduDurations.at(160),
3769 delay += Seconds(1.0);
3771 }
3772
3774}
3775
3776void
3804
3805void
3807{
3808 m_rxPhy->Dispose();
3809 m_rxPhy = nullptr;
3810 m_txPhy->Dispose();
3811 m_txPhy = nullptr;
3812 for (auto& signalGenerator : m_signalGenerators)
3813 {
3814 signalGenerator->Dispose();
3815 signalGenerator = nullptr;
3816 }
3817}
3818
3819/**
3820 * @ingroup wifi-test
3821 * @ingroup tests
3822 *
3823 * @brief Wi-Fi PHY CCA Test Suite
3824 */
3826{
3827 public:
3829};
3830
3832 : TestSuite("wifi-phy-cca", Type::UNIT)
3833{
3834 AddTestCase(new WifiPhyCcaThresholdsTest, TestCase::Duration::QUICK);
3835 AddTestCase(new WifiPhyCcaIndicationTest(WIFI_STANDARD_80211ax), TestCase::Duration::QUICK);
3836 AddTestCase(new WifiPhyCcaIndicationTest(WIFI_STANDARD_80211be), TestCase::Duration::QUICK);
3837}
3838
3839static WifiPhyCcaTestSuite WifiPhyCcaTestSuite; ///< the test suite
PHY listener for CCA tests.
void NotifyOn() override
Notify listeners that we went to switch on.
WifiChannelListType m_lastCcaBusyChannelType
Channel type indication for the last CCA-BUSY notification.
void 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.
void VerifyCcaThreshold(const Ptr< PhyEntity > phy, const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType, dBm_u expectedCcaThreshold)
Function to verify the CCA threshold that is being reported by a given PHY entity upon reception of a...
Ptr< WifiNetDevice > m_device
The WifiNetDevice.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Ptr< SpectrumWifiPhy > m_phy
The spectrum PHY.
Ptr< ObssPdAlgorithm > m_obssPdAlgorithm
The OBSS-PD algorithm.
dBm_u m_obssPdLevel
The current OBSS-PD level.
Ptr< 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.
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:595
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
AttributeValue implementation for Time.
Definition nstime.h:1432
std::tuple< dBm_u, dBm_u, dBm_u > SecondaryCcaSensitivityThresholds
Tuple identifying CCA sensitivity thresholds for secondary channels.
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
Implements the IEEE 802.11 MAC header.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:937
receive notifications about PHY events.
Class that keeps track of all information about the current PHY operating channel.
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first frequency segment matching the specified parameters.
This objects implements the PHY state machine of the Wifi device.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h: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:134
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition test.h:500
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
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.
std::vector< BandInfo > Bands
Container of BandInfo.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:585
@ 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:113
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
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
static WifiPhyCcaTestSuite WifiPhyCcaTestSuite
the test suite
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