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
61// add small delta to be right after aCcaTime, since test checks are scheduled before wifi events
63const std::map<MHz_u, Time> hePpduDurations = {
64 {20, NanoSeconds(1009600)},
65 {40, NanoSeconds(533600)},
66 {80, NanoSeconds(275200)},
67};
68const std::map<MHz_u, Time> ehtPpduDurations = {
69 {20, NanoSeconds(1017600)},
70 {40, NanoSeconds(541600)},
71 {80, NanoSeconds(287200)},
72 {160, NanoSeconds(178400)},
73};
74
75/**
76 * @ingroup wifi-test
77 * @ingroup tests
78 *
79 * @brief PHY CCA thresholds test
80 */
82{
83 public:
85
86 private:
87 void DoSetup() override;
88 void DoTeardown() override;
89 void DoRun() override;
90
91 /**
92 * Run tests for given CCA attributes
93 */
94 void RunOne();
95
96 /**
97 * Create a dummy PSDU whose payload is 1000 bytes
98 * @return a dummy PSDU whose payload is 1000 bytes
99 */
101 /**
102 * Create a non-HT PPDU
103 * @param channel the operating channel of the PHY used for the transmission
104 * @return a non-HT PPDU
105 */
107 /**
108 * Create a HT PPDU
109 * @param bandwidth the bandwidth used for the transmission the PPDU
110 * @param channel the operating channel of the PHY used for the transmission
111 * @return a HT PPDU
112 */
114 /**
115 * Create a VHT PPDU
116 * @param bandwidth the bandwidth used for the transmission the PPDU
117 * @param channel the operating channel of the PHY used for the transmission
118 * @return a VHT PPDU
119 */
121 /**
122 * Create a HE PPDU
123 * @param bandwidth the bandwidth used for the transmission the PPDU
124 * @param channel the operating channel of the PHY used for the transmission
125 * @return a HE PPDU
126 */
128 /**
129 * Create a EHT PPDU
130 * @param bandwidth the bandwidth used for the transmission the PPDU
131 * @param channel the operating channel of the PHY used for the transmission
132 * @return a EHT PPDU
133 */
135
136 /**
137 * Function to verify the CCA threshold that is being reported by a given PHY entity upon
138 * reception of a signal or a PPDU
139 * @param phy the PHY entity to verify
140 * @param ppdu the incoming PPDU or signal (if nullptr)
141 * @param channelType the channel list type that indicates which channel the PPDU or the
142 * signal occupies
143 * @param expectedCcaThreshold the CCA threshold that is expected to be reported
144 */
145 void VerifyCcaThreshold(const std::shared_ptr<PhyEntity> phy,
146 const Ptr<const WifiPpdu> ppdu,
147 WifiChannelListType channelType,
148 dBm_u expectedCcaThreshold);
149
150 Ptr<WifiNetDevice> m_device; ///< The WifiNetDevice
151 Ptr<SpectrumWifiPhy> m_phy; ///< The spectrum PHY
152 Ptr<ObssPdAlgorithm> m_obssPdAlgorithm; ///< The OBSS-PD algorithm
153 Ptr<VhtConfiguration> m_vhtConfiguration; ///< The VHT configuration
154 Ptr<EhtConfiguration> m_ehtConfiguration; ///< The EHT configuration
155
156 dBm_u m_CcaEdThreshold; ///< The current CCA-ED threshold for a 20 MHz subchannel
157 dBm_u m_CcaSensitivity; ///< The current CCA sensitivity threshold for signals that occupy
158 ///< the primary 20 MHz channel
159
161 m_secondaryCcaSensitivityThresholds; ///< The current CCA sensitivity thresholds for
162 ///< signals that do not occupy the primary 20 MHz
163 ///< channel
164
165 dBm_u m_obssPdLevel; ///< The current OBSS-PD level
166 dBm_u m_per20CcaSensitivity; ///< The current CCA sensitivity threshold for Per 20MHz check
167};
168
170 : TestCase("Wi-Fi PHY CCA thresholds test"),
171 m_CcaEdThreshold{-62.0},
172 m_CcaSensitivity{-82.0},
174 m_obssPdLevel{-82.0},
176{
177}
178
181{
182 Ptr<Packet> pkt = Create<Packet>(1000);
183 WifiMacHeader hdr;
185 hdr.SetQosTid(0);
186 return Create<WifiPsdu>(pkt, hdr);
187}
188
191{
195 NanoSeconds(800),
196 1,
197 1,
198 0,
199 MHz_u{20},
200 false);
202 return Create<OfdmPpdu>(psdu, txVector, channel, 0);
203}
204
207{
211 NanoSeconds(800),
212 1,
213 1,
214 0,
215 bandwidth,
216 false);
218 return Create<HtPpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
219}
220
223 const WifiPhyOperatingChannel& channel)
224{
228 NanoSeconds(800),
229 1,
230 1,
231 0,
232 bandwidth,
233 false);
235 return Create<VhtPpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
236}
237
240{
244 NanoSeconds(800),
245 1,
246 1,
247 0,
248 bandwidth,
249 false);
251 return Create<HePpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
252}
253
256 const WifiPhyOperatingChannel& channel)
257{
261 NanoSeconds(800),
262 1,
263 1,
264 0,
265 bandwidth,
266 false};
267 WifiConstPsduMap psdus;
268 psdus.emplace(1, CreateDummyPsdu());
269 return Create<EhtPpdu>(psdus,
270 txVector,
271 channel,
272 MicroSeconds(100),
273 0,
275}
276
277void
278WifiPhyCcaThresholdsTest::VerifyCcaThreshold(const std::shared_ptr<PhyEntity> phy,
279 const Ptr<const WifiPpdu> ppdu,
280 WifiChannelListType channelType,
281 dBm_u expectedCcaThreshold)
282{
283 NS_LOG_FUNCTION(this << phy << channelType << expectedCcaThreshold);
284 const auto actualThreshold = phy->GetCcaThreshold(ppdu, channelType);
285 NS_LOG_INFO((ppdu == nullptr ? "any signal" : "a PPDU")
286 << " in " << channelType << " channel: " << actualThreshold << "dBm");
287 NS_TEST_EXPECT_MSG_EQ_TOL(actualThreshold,
288 expectedCcaThreshold,
289 dB_u{1e-6},
290 "Actual CCA threshold for "
291 << (ppdu == nullptr ? "any signal" : "a PPDU") << " in "
292 << channelType << " channel " << actualThreshold
293 << "dBm does not match expected threshold "
294 << expectedCcaThreshold << "dBm");
295}
296
297void
299{
300 // WifiHelper::EnableLogComponents ();
301 // LogComponentEnable ("WifiPhyCcaTest", LOG_LEVEL_ALL);
302
304 m_device->SetStandard(WIFI_STANDARD_80211be);
306 m_device->SetVhtConfiguration(m_vhtConfiguration);
308 m_device->SetEhtConfiguration(m_ehtConfiguration);
309
311 m_phy->SetDevice(m_device);
312 m_device->SetPhy(m_phy);
313 m_phy->SetInterferenceHelper(CreateObject<InterferenceHelper>());
315
316 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
317 MHz_u{0},
318 MHz_u{320},
321 ->number;
322 m_phy->SetOperatingChannel(WifiPhy::ChannelTuple{channelNum, 320, WIFI_PHY_BAND_6GHZ, 0});
323 m_phy->ConfigureStandard(WIFI_STANDARD_80211be);
324
326 m_device->AggregateObject(m_obssPdAlgorithm);
327 m_obssPdAlgorithm->ConnectWifiNetDevice(m_device);
328}
329
330void
332{
333 m_device->Dispose();
334 m_device = nullptr;
335}
336
337void
339{
340 m_phy->SetCcaEdThreshold(m_CcaEdThreshold);
341 m_phy->SetCcaSensitivityThreshold(m_CcaSensitivity);
342 m_vhtConfiguration->SetSecondaryCcaSensitivityThresholds(m_secondaryCcaSensitivityThresholds);
343 m_obssPdAlgorithm->SetObssPdLevel(m_obssPdLevel);
344 m_ehtConfiguration->m_per20CcaSensitivityThreshold = m_per20CcaSensitivity;
345
346 // OFDM PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
348 nullptr,
351
352 //-----------------------------------------------------------------------------------------------------------------------------------
353
354 // OFDM PHY: 20 MHz non-HT PPDU in primary channel (20 MHz) if power above CCA sensitivity
355 // threshold
357 CreateDummyNonHtPpdu(m_phy->GetOperatingChannel()),
360
361 //-----------------------------------------------------------------------------------------------------------------------------------
362
363 // HT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
365 nullptr,
368
369 // HT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
371 nullptr,
374
375 //-----------------------------------------------------------------------------------------------------------------------------------
376
377 // HT PHY: 20 MHz HT PPDU in primary channel (20 MHz) if power in primary above CCA
378 // sensitivity threshold
380 CreateDummyHtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
383
384 // HT PHY: 40 MHz HT PPDU in primary channel (20 MHz) if power in primary above CCA
385 // sensitivity threshold
387 CreateDummyHtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
390
391 //-----------------------------------------------------------------------------------------------------------------------------------
392
393 // VHT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
395 nullptr,
398
399 // VHT PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
401 nullptr,
404
405 // VHT PHY: any signal in secondary40 channel (40 MHz) if power above CCA-ED threshold + 3dB
407 nullptr,
409 m_CcaEdThreshold + dB_u{3.0});
410
411 // VHT PHY: any signal in secondary80 channel (80 MHz) if power above CCA-ED threshold + 6dB
413 nullptr,
415 m_CcaEdThreshold + dB_u{6.0});
416
417 //-----------------------------------------------------------------------------------------------------------------------------------
418
419 // VHT PHY: 20 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
420 // sensitivity threshold
422 CreateDummyVhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
425
426 // VHT PHY: 40 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
427 // sensitivity threshold
429 CreateDummyVhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
432
433 // VHT PHY: 80 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
434 // sensitivity threshold
436 CreateDummyVhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
439
440 // VHT PHY: 160 MHz VHT PPDU in primary channel (20 MHz) if power in primary above CCA
441 // sensitivity threshold
443 CreateDummyVhtPpdu(MHz_u{160}, m_phy->GetOperatingChannel()),
446
447 //-----------------------------------------------------------------------------------------------------------------------------------
448
449 // VHT PHY: 20 MHz VHT PPDU in secondary channel (20 MHz) if power above the CCA sensitivity
450 // threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20 MHz
452 CreateDummyVhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
455
456 // VHT PHY: 20 MHz VHT PPDU in secondary40 channel (40 MHz) if power above the CCA
457 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20
458 // MHz
460 CreateDummyVhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
463
464 // VHT PHY: 40 MHz VHT PPDU in secondary40 channel (40 MHz) if power above the CCA
465 // sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20
466 // MHz
468 CreateDummyVhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
471
472 // VHT PHY: 20 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA
473 // sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary 20
474 // MHz
476 CreateDummyVhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
479
480 // VHT PHY: 40 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA
481 // sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary 20
482 // MHz
484 CreateDummyVhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
487
488 // VHT PHY: 80 MHz VHT PPDU in secondary80 channel (80 MHz) if power above the CCA
489 // sensitivity threshold corresponding to a 80 MHz PPDU that does not occupy the primary 20
490 // MHz
492 CreateDummyVhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
495
496 //-----------------------------------------------------------------------------------------------------------------------------------
497
498 // HE PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
500 nullptr,
503
504 // HE PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
506 nullptr,
509
510 // HE PHY: any signal in secondary40 channel (40 MHz) if power above CCA-ED threshold + 3dB
512 nullptr,
514 m_CcaEdThreshold + dB_u{3.0});
515
516 // HE PHY: any signal in secondary80 channel (80 MHz) if power above CCA-ED threshold + 6dB
518 nullptr,
520 m_CcaEdThreshold + dB_u{6.0});
521
522 //-----------------------------------------------------------------------------------------------------------------------------------
523
524 // HE PHY: 20 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA
525 // sensitivity threshold
527 CreateDummyHePpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
530
531 // HE PHY: 40 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA
532 // sensitivity threshold
534 CreateDummyHePpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
537
538 // HE PHY: 80 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA
539 // sensitivity threshold
541 CreateDummyHePpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
544
545 // HE PHY: 160 MHz HE PPDU in primary channel (20 MHz) if power in primary above CCA
546 // sensitivity threshold
548 CreateDummyHePpdu(MHz_u{160}, m_phy->GetOperatingChannel()),
551
552 //-----------------------------------------------------------------------------------------------------------------------------------
553
554 // HE PHY: 20 MHz HE PPDU in secondary channel (20 MHz) if power above the max between the
555 // CCA sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary
556 // 20 MHz and the OBSS-PD level
558 CreateDummyHePpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
560 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
561
562 // HE PHY: 20 MHz HE PPDU in secondary40 channel (40 MHz) if power above the max between the
563 // CCA sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary
564 // 20 MHz and the OBSS-PD level
566 CreateDummyHePpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
568 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
569
570 // HE PHY: 40 MHz HE PPDU in secondary40 channel (40 MHz) if power above the max between the
571 // CCA sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary
572 // 20 MHz and the OBSS-PD level plus 3 dB
574 m_phy->GetPhyEntity(WIFI_MOD_CLASS_HE),
575 CreateDummyHePpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
577 std::max(m_obssPdLevel + dB_u{3.0}, std::get<1>(m_secondaryCcaSensitivityThresholds)));
578
579 // HE PHY: 20 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the
580 // CCA sensitivity threshold corresponding to a 20 MHz PPDU that does not occupy the primary
581 // 20 MHz and the OBSS-PD level
583 CreateDummyHePpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
585 std::max(m_obssPdLevel, std::get<0>(m_secondaryCcaSensitivityThresholds)));
586
587 // HE PHY: 40 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the
588 // CCA sensitivity threshold corresponding to a 40 MHz PPDU that does not occupy the primary
589 // 20 MHz and the OBSS-PD level plus 3 dB
591 m_phy->GetPhyEntity(WIFI_MOD_CLASS_HE),
592 CreateDummyHePpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
594 std::max(m_obssPdLevel + dB_u{3.0}, std::get<1>(m_secondaryCcaSensitivityThresholds)));
595
596 // HE PHY: 80 MHz HE PPDU in secondary80 channel (80 MHz) if power above the max between the
597 // CCA sensitivity threshold corresponding to a 80 MHz PPDU that does not occupy the primary
598 // 20 MHz and the OBSS-PD level plus 6 dB
600 m_phy->GetPhyEntity(WIFI_MOD_CLASS_HE),
601 CreateDummyHePpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
603 std::max(m_obssPdLevel + dB_u{6.0}, std::get<2>(m_secondaryCcaSensitivityThresholds)));
604
605 //-----------------------------------------------------------------------------------------------------------------------------------
606
607 // EHT PHY: any signal in primary channel (20 MHz) if power above CCA-ED threshold
609 nullptr,
612
613 // EHT PHY: any signal in secondary channel (20 MHz) if power above CCA-ED threshold
615 nullptr,
618
619 // EHT PHY: any signal in secondary40 channel (40 MHz) if power in any 20 MHz subchannel
620 // above CCA-ED threshold
622 nullptr,
625
626 // EHT PHY: any signal in secondary80 channel (80 MHz) if power in any 20 MHz subchannel
627 // above CCA-ED threshold
629 nullptr,
632
633 // EHT PHY: any signal in secondary160 channel (160 MHz) if power in any 20 MHz subchannel
634 // above CCA-ED threshold
636 nullptr,
639
640 //-----------------------------------------------------------------------------------------------------------------------------------
641 // EHT PHY: 20 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
642 // sensitivity threshold
644 CreateDummyEhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
647 // EHT PHY: 40 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
648 // sensitivity threshold
650 CreateDummyEhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
653
654 // EHT PHY: 80 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
655 // sensitivity threshold
657 CreateDummyEhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
660
661 // EHT PHY: 160 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
662 // sensitivity threshold
664 CreateDummyEhtPpdu(MHz_u{160}, m_phy->GetOperatingChannel()),
667
668 // EHT PHY: 320 MHz EHT PPDU in primary channel (20 MHz) if power in primary above CCA
669 // sensitivity threshold
671 CreateDummyEhtPpdu(MHz_u{320}, m_phy->GetOperatingChannel()),
674
675 //-----------------------------------------------------------------------------------------------------------------------------------
676
677 // EHT PHY: 20 MHz EHT PPDU in secondary channel (20 MHz) if power above the max between the
678 // CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
680 CreateDummyEhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
683
684 // EHT PHY: 20 MHz EHT PPDU in secondary40 channel (40 MHz) if power above the max between
685 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
687 CreateDummyEhtPpdu(MHz_u{20}, m_phy->GetOperatingChannel()),
690
691 // EHT PHY: 40 MHz EHT PPDU in secondary40 channel (40 MHz) if power above the max between
692 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
694 CreateDummyEhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
697
698 // EHT PHY: 20 MHz EHT PPDU in secondary80 channel (80 MHz) if power above the max between
699 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
701 CreateDummyEhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
704
705 // EHT PHY: 40 MHz EHT PPDU in secondary80 channel (80 MHz) if power above the max between
706 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
708 CreateDummyEhtPpdu(MHz_u{40}, m_phy->GetOperatingChannel()),
711
712 // EHT PHY: 80 MHz EHT PPDU in secondary80 channel (80 MHz) if power above the max between
713 // the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
715 CreateDummyEhtPpdu(MHz_u{80}, m_phy->GetOperatingChannel()),
718
719 // EHT PHY: 160 MHz EHT PPDU in secondary160 channel (160 MHz) if power above the max
720 // between the CCA sensitivity threshold for Per 20MHz check and the OBSS-PD level
722 CreateDummyEhtPpdu(160, m_phy->GetOperatingChannel()),
725}
726
727void
729{
730 // default attributes
731 m_CcaEdThreshold = dBm_u{-62};
732 m_CcaSensitivity = dBm_u{-82};
733 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
734 m_obssPdLevel = dBm_u{-82};
736 RunOne();
737
738 // default attributes with OBSS-PD level set to -80 dBm
739 m_CcaEdThreshold = dBm_u{-62};
740 m_CcaSensitivity = dBm_u{-82};
741 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
742 m_obssPdLevel = dBm_u{-80};
744 RunOne();
745
746 // default attributes with OBSS-PD level set to -70 dBm
747 m_CcaEdThreshold = dBm_u{-62};
748 m_CcaSensitivity = dBm_u{-82};
749 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
750 m_obssPdLevel = dBm_u{-70};
752 RunOne();
753
754 // CCA-ED set to -65 dBm
755 m_CcaEdThreshold = dBm_u{-65};
756 m_CcaSensitivity = dBm_u{-82};
757 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
758 m_obssPdLevel = dBm_u{-82};
760 RunOne();
761
762 // CCA sensitivity for signals in primary set to -75 dBm
763 m_CcaEdThreshold = dBm_u{-62};
764 m_CcaSensitivity = dBm_u{-75};
765 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-72}, dBm_u{-72}, dBm_u{-69});
766 m_obssPdLevel = dBm_u{-82};
768 RunOne();
769
770 // custom CCA sensitivities for signals not in primary
771 m_CcaEdThreshold = dBm_u{-62};
772 m_CcaSensitivity = dBm_u{-72};
773 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-70}, dBm_u{-70}, dBm_u{-70});
774 m_obssPdLevel = dBm_u{-82};
775 m_per20CcaSensitivity = -75.0;
776 RunOne();
777
778 // custom CCA sensitivities for signals not in primary with OBSS-PD level set to -80 dBm
779 m_CcaEdThreshold = dBm_u{-62};
780 m_CcaSensitivity = dBm_u{-72};
781 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-70}, dBm_u{-70}, dBm_u{-70});
782 m_obssPdLevel = dBm_u{-80};
783 m_per20CcaSensitivity = -69.0;
784 RunOne();
785
786 // custom CCA sensitivities for signals not in primary with OBSS-PD level set to -70 dBm
787 m_CcaEdThreshold = dBm_u{-62};
788 m_CcaSensitivity = dBm_u{-72};
789 m_secondaryCcaSensitivityThresholds = std::make_tuple(dBm_u{-70}, dBm_u{-70}, dBm_u{-70});
790 m_obssPdLevel = dBm_u{-70};
791 m_per20CcaSensitivity = -66.0;
792 RunOne();
793
795}
796
797/**
798 * @ingroup wifi-test
799 * @ingroup tests
800 *
801 * @brief PHY listener for CCA tests
802 */
804{
805 public:
807
808 void NotifyRxStart(Time duration) override
809 {
810 NS_LOG_FUNCTION(this << duration);
811 }
812
813 void NotifyRxEndOk() override
814 {
815 NS_LOG_FUNCTION(this);
816 }
817
818 void NotifyRxEndError(const WifiTxVector& txVector) override
819 {
820 NS_LOG_FUNCTION(this << txVector);
821 }
822
823 void NotifyTxStart(Time duration, dBm_u txPower) override
824 {
825 NS_LOG_FUNCTION(this << duration << txPower);
826 }
827
829 WifiChannelListType channelType,
830 const std::vector<Time>& per20MhzDurations) override
831 {
832 NS_LOG_FUNCTION(this << duration << channelType << per20MhzDurations.size());
833 NS_ASSERT(duration.IsPositive());
834 const auto now = Simulator::Now();
835 if (m_startCcaBusy.IsZero())
836 {
837 m_startCcaBusy = now;
838 }
839 m_endCcaBusy = now + duration;
840 m_lastCcaBusyChannelType = channelType;
841 m_lastPer20MhzCcaBusyDurations = per20MhzDurations;
843 }
844
845 void NotifySwitchingStart(Time duration) override
846 {
847 }
848
849 void NotifySleep() override
850 {
851 }
852
853 void NotifyOff() override
854 {
855 }
856
857 void NotifyWakeup() override
858 {
859 }
860
861 void NotifyOn() override
862 {
863 }
864
865 /**
866 * Reset function
867 */
876
877 std::size_t m_notifications{0}; ///< Number of CCA notifications
878 Time m_startCcaBusy{}; ///< Start of the CCA-BUSY duration
879 Time m_endCcaBusy{}; ///< End of the CCA-BUSY duration
881 WIFI_CHANLIST_PRIMARY}; ///< Channel type indication for the last CCA-BUSY notification
882 std::vector<Time>
883 m_lastPer20MhzCcaBusyDurations{}; ///< End of the CCA-BUSY durations per 20 MHz
884};
885
886/**
887 * @ingroup wifi-test
888 * @ingroup tests
889 *
890 * @brief Test CCA_BUSY indication provided by the PHY
891 *
892 * Many scenarios are being tested, where one or more PPDUs are being received and/or one or more
893 * (non-wifi) signals are being received. The tests verify the PHY states at different time
894 * points, and the CCA_BUSY indication at various point in time (amount of notifications, start and
895 * end of CCA_BUSY periods and per-20MHz bitmaps). The tests are run for all possible channel width
896 * and PPDU/signal widths combinations.
897 */
899{
900 public:
901 /**
902 * Constructor
903 *
904 * @param standard the standard to use for the test
905 */
907
908 private:
909 void DoSetup() override;
910 void DoRun() override;
911 void DoTeardown() override;
912
913 /**
914 * Send a HE or EHT SU PPDU
915 * @param txPower the transmit power
916 * @param frequency the center frequency the transmitter is operating on
917 * @param bandwidth the bandwidth to use for the transmission
918 */
919 void SendSuPpdu(dBm_u txPower, MHz_u frequency, MHz_u bandwidth);
920
921 /**
922 * Start to generate a signal
923 * @param signalGenerator the signal generator to use
924 * @param txPower the transmit power
925 * @param frequency the center frequency of the signal to send
926 * @param bandwidth the bandwidth of the signal to send
927 * @param duration the duration of the signal
928 */
929 void StartSignal(Ptr<WaveformGenerator> signalGenerator,
930 dBm_u txPower,
931 MHz_u frequency,
932 MHz_u bandwidth,
933 Time duration);
934 /**
935 * Stop to generate a signal
936 * @param signalGenerator the signal generator to use
937 */
938 void StopSignal(Ptr<WaveformGenerator> signalGenerator);
939
940 /**
941 * Update the CCA threshold of the PHY
942 * @param ccaThreshold the new CCA threshold value to be set
943 */
944 void UpdateCcaThreshold(dBm_u ccaThreshold);
945
946 /**
947 * Check the PHY state
948 * @param scenario the scenario under test
949 * @param expectedState the expected state of the PHY
950 */
951 void CheckPhyState(const std::string& scenario, WifiPhyState expectedState);
952 /// @copydoc CheckPhyState
953 void DoCheckPhyState(const std::string& scenario, WifiPhyState expectedState);
954
955 /**
956 * Check the CCA-BUSY notifications
957 * @param scenario the scenario under test
958 * @param expectedCcaNotifications the expected number of CCA_BUSY notifications
959 * @param expectedStartTime the expected CCA-BUSY start time
960 * @param expectedEndTime the expected CCA-BUSY end time
961 * @param expectedChannelType the expected channel type
962 * @param expectedPer20MhzDurations the expected per-20 MHz CCA-BUSY durations
963 */
964 void CheckCcaBusyNotifications(const std::string& scenario,
965 std::size_t expectedCcaNotifications,
966 Time expectedStartTime,
967 Time expectedEndTime,
968 WifiChannelListType expectedChannelType,
969 const std::vector<Time>& expectedPer20MhzDurations);
970 /// @copydoc CheckCcaBusyNotifications
971 void DoCheckCcaBusyNotifications(const std::string& scenario,
972 std::size_t expectedCcaNotifications,
973 Time expectedStartTime,
974 Time expectedEndTime,
975 WifiChannelListType expectedChannelType,
976 const std::vector<Time>& expectedPer20MhzDurations);
977 /**
978 * Log scenario description
979 *
980 * @param scenario the scenario description to add to log
981 */
982 void LogScenario(const std::string& scenario) const;
983
984 /**
985 * structure that holds information to generate signals
986 */
988 {
989 dBm_u power; //!< transmit power to use
990 Time startTime; //!< time at which transmission will be started
991 Time duration; //!< the duration of the transmission
992 MHz_u centerFreq; //!< center frequency to use
993 MHz_u bandwidth; //!< bandwidth to use
994 };
995
996 /**
997 * structure that holds information to generate PPDUs
998 */
1000 {
1001 dBm_u power; //!< transmit power to use
1002 Time startTime; //!< time at which transmission will be started
1003 MHz_u centerFreq; //!< center frequency to use
1004 MHz_u bandwidth; //!< bandwidth to use
1005 };
1006
1007 /**
1008 * structure that holds information to perform PHY state check
1009 */
1011 {
1012 Time timePoint; //!< time at which the check will performed
1014 };
1015
1016 /**
1017 * structure that holds information to perform CCA check
1018 */
1020 {
1021 Time timePoint; //!< time at which the check will performed
1022 std::size_t expectedCcaNotifications{0}; //!< expected number of CCA_BUSY notifications
1023 Time expectedCcaStartTime; //!< expected CCA_BUSY start time
1024 Time expectedCcaEndTime; //!< expected CCA_BUSY end time
1027 std::vector<Time> expectedPer20MhzDurations; //!< expected per-20 MHz CCA duration
1028 };
1029
1030 /**
1031 * structure that holds information to perform CCA threshold update
1032 */
1034 {
1035 Time timePoint; //!< time at which the update will be performed
1036 dBm_u ccaThreshold; //!< new CCA threshold value to be set
1037 };
1038
1039 /**
1040 * Schedule test to perform.
1041 * @param delay the reference delay to schedule the events
1042 * @param scenario description of the scenario to test
1043 * @param generatedSignals the vector of signals to be generated
1044 * @param generatedPpdus the vector of PPDUs to be generated
1045 * @param stateCheckpoints the vector of PHY state checks
1046 * @param ccaCheckpoints the vector of PHY CCA checks
1047 * @param ccaThresholdUpdates the vector of CCA threshold updates
1048 */
1049 void ScheduleTest(Time delay,
1050 const std::string& scenario,
1051 const std::vector<TxSignalInfo>& generatedSignals,
1052 const std::vector<TxPpduInfo>& generatedPpdus,
1053 const std::vector<StateCheckPoint>& stateCheckpoints,
1054 const std::vector<CcaCheckPoint>& ccaCheckpoints,
1055 const std::vector<CcaThresholdUpdatePoint>& ccaThresholdUpdates = {});
1056
1057 /**
1058 * Reset function
1059 */
1060 void Reset();
1061
1062 /**
1063 * Reset the expected Per 20 MHz CCA durations
1064 */
1066
1067 /**
1068 * Run one function
1069 */
1070 void RunOne();
1071
1072 WifiStandard m_standard; ///< The standard to use for the test
1073
1074 Ptr<SpectrumWifiPhy> m_rxPhy; ///< PHY object of the receiver
1075 Ptr<SpectrumWifiPhy> m_uxPhy; ///< PHY object of the transmitter
1076
1077 std::vector<Ptr<WaveformGenerator>> m_signalGenerators; ///< Generators of non-wifi signals
1078 std::size_t m_numSignalGenerators; ///< The number of non-wifi signals generators needed for
1079 ///< the test
1080
1081 std::shared_ptr<CcaTestPhyListener>
1082 m_rxPhyStateListener; ///< Listener for PHY state transitions
1083
1084 MHz_u m_frequency; ///< Operating frequency
1085 MHz_u m_channelWidth; ///< Operating channel width
1086
1087 std::vector<std::vector<Time>>
1088 m_expectedPer20MhzCcaBusyDurations{}; ///< expected Per 20Mhz CCA durations per check
1089};
1090
1092 : TestCase("Wi-Fi PHY CCA indication test for " + ((standard == WIFI_STANDARD_80211ax)
1093 ? std::string("802.11ax")
1094 : std::string("802.11be"))),
1095 m_standard{standard},
1099{
1100}
1101
1102void
1104 dBm_u txPower,
1105 MHz_u frequency,
1106 MHz_u bandwidth,
1107 Time duration)
1108{
1109 NS_LOG_FUNCTION(this << signalGenerator << txPower << frequency << bandwidth << duration);
1110
1111 BandInfo bandInfo;
1112 bandInfo.fc = MHzToHz(frequency);
1113 bandInfo.fl = bandInfo.fc - MHzToHz(bandwidth / 2);
1114 bandInfo.fh = bandInfo.fc + MHzToHz(bandwidth / 2);
1115 Bands bands;
1116 bands.push_back(bandInfo);
1117
1118 Ptr<SpectrumModel> spectrumSignal = Create<SpectrumModel>(bands);
1119 Ptr<SpectrumValue> signalPsd = Create<SpectrumValue>(spectrumSignal);
1120 *signalPsd = DbmToW(txPower) / MHzToHz(bandwidth);
1121
1122 signalGenerator->SetTxPowerSpectralDensity(signalPsd);
1123 signalGenerator->SetPeriod(duration);
1124 signalGenerator->Start();
1125 Simulator::Schedule(duration, &WifiPhyCcaIndicationTest::StopSignal, this, signalGenerator);
1126}
1127
1128void
1130{
1131 NS_LOG_FUNCTION(this << signalGenerator);
1132 signalGenerator->Stop();
1133}
1134
1135void
1137{
1138 NS_LOG_FUNCTION(this << txPower);
1139
1140 auto channelNum =
1142 ->number;
1143 m_uxPhy->SetOperatingChannel(
1144 WifiPhy::ChannelTuple{channelNum, bandwidth, WIFI_PHY_BAND_6GHZ, 0});
1145
1146 const auto mcs =
1148 const auto preamble =
1151 txVector{mcs, WIFI_MIN_TX_PWR_LEVEL, preamble, NanoSeconds(800), 1, 1, 0, bandwidth, false};
1152 Ptr<Packet> pkt = Create<Packet>(1000);
1153 WifiMacHeader hdr;
1155 hdr.SetQosTid(0);
1156 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
1157
1158 m_uxPhy->SetTxPowerStart(txPower);
1159 m_uxPhy->SetTxPowerEnd(txPower);
1160
1161 m_uxPhy->Send(psdu, txVector);
1162}
1163
1164void
1166{
1167 NS_LOG_FUNCTION(this << ccaThreshold);
1168 m_rxPhy->SetCcaEdThreshold(ccaThreshold);
1169}
1170
1171void
1172WifiPhyCcaIndicationTest::CheckPhyState(const std::string& scenario, WifiPhyState expectedState)
1173{
1174 NS_LOG_FUNCTION(this << expectedState);
1175 // This is needed to make sure PHY state will be checked as the last event if a state change
1176 // occurred at the exact same time as the check
1178 this,
1179 scenario,
1180 expectedState);
1181}
1182
1183void
1184WifiPhyCcaIndicationTest::DoCheckPhyState(const std::string& scenario, WifiPhyState expectedState)
1185{
1186 NS_LOG_FUNCTION(this << expectedState);
1187 WifiPhyState currentState;
1188 PointerValue ptr;
1189 m_rxPhy->GetAttribute("State", ptr);
1191 currentState = state->GetState();
1192 NS_TEST_ASSERT_MSG_EQ(currentState,
1193 expectedState,
1194 "PHY State " << currentState << " does not match expected state "
1195 << expectedState << " at " << Simulator::Now()
1196 << " for scenario: " << scenario << " (bw=" << m_channelWidth
1197 << ")");
1198}
1199
1200void
1202 const std::string& scenario,
1203 std::size_t expectedCcaNotifications,
1204 Time expectedStartTime,
1205 Time expectedEndTime,
1206 WifiChannelListType expectedChannelType,
1207 const std::vector<Time>& expectedPer20MhzDurations)
1208{
1210 this,
1211 scenario,
1212 expectedCcaNotifications,
1213 expectedStartTime,
1214 expectedEndTime,
1215 expectedChannelType,
1216 expectedPer20MhzDurations);
1217}
1218
1219void
1221 const std::string& scenario,
1222 std::size_t expectedCcaNotifications,
1223 Time expectedStartTime,
1224 Time expectedEndTime,
1225 WifiChannelListType expectedChannelType,
1226 const std::vector<Time>& expectedPer20MhzDurations)
1227{
1228 auto printPer20Bitmap = [](const std::vector<Time>& v) -> std::string {
1229 if (v.empty())
1230 {
1231 return "";
1232 }
1233 std::stringstream ss;
1234 for (const auto& t : v)
1235 {
1236 ss << t << " ";
1237 }
1238 return ss.str();
1239 };
1240 NS_LOG_FUNCTION(this << expectedCcaNotifications << expectedStartTime << expectedEndTime
1241 << expectedChannelType << printPer20Bitmap(expectedPer20MhzDurations));
1243 expectedCcaNotifications,
1244 "Number of CCA busy notifications "
1245 << m_rxPhyStateListener->m_notifications
1246 << " does not match expected number " << expectedCcaNotifications
1247 << " at " << Simulator::Now() << " for scenario: " << scenario
1248 << " (bw=" << m_channelWidth << ")");
1250 expectedStartTime,
1251 "PHY CCA start time " << m_rxPhyStateListener->m_startCcaBusy
1252 << " does not match expected time "
1253 << expectedStartTime << " at " << Simulator::Now()
1254 << " for scenario: " << scenario
1255 << " (bw=" << m_channelWidth << ")");
1257 expectedEndTime,
1258 "PHY CCA end time " << m_rxPhyStateListener->m_endCcaBusy
1259 << " does not match expected time " << expectedEndTime
1260 << " at " << Simulator::Now() << " for scenario: "
1261 << scenario << " (bw=" << m_channelWidth << ")");
1262 NS_TEST_ASSERT_MSG_EQ(m_rxPhyStateListener->m_lastCcaBusyChannelType,
1263 expectedChannelType,
1264 "PHY CCA-BUSY for " << m_rxPhyStateListener->m_lastCcaBusyChannelType
1265 << " does not match expected channel type "
1266 << expectedChannelType << " at " << Simulator::Now()
1267 << " for scenario: " << scenario
1268 << " (bw=" << m_channelWidth << ")");
1269 NS_TEST_ASSERT_MSG_EQ(m_rxPhyStateListener->m_lastPer20MhzCcaBusyDurations.size(),
1270 expectedPer20MhzDurations.size(),
1271 "PHY CCA-BUSY per-20 MHz durations does not match expected vector"
1272 << " at " << Simulator::Now() << " for scenario: " << scenario
1273 << " (bw=" << m_channelWidth << ")");
1274 for (std::size_t i = 0; i < expectedPer20MhzDurations.size(); ++i)
1275 {
1276 NS_TEST_ASSERT_MSG_EQ(m_rxPhyStateListener->m_lastPer20MhzCcaBusyDurations.at(i),
1277 expectedPer20MhzDurations.at(i),
1278 "PHY CCA-BUSY per-20 MHz duration at index "
1279 << i << " does not match expected duration at "
1280 << Simulator::Now() << " for scenario: " << scenario
1281 << " (bw=" << m_channelWidth << ")");
1282 }
1283}
1284
1285void
1286WifiPhyCcaIndicationTest::LogScenario(const std::string& scenario) const
1287{
1288 NS_LOG_INFO(scenario);
1289}
1290
1291void
1293 Time delay,
1294 const std::string& scenario,
1295 const std::vector<TxSignalInfo>& generatedSignals,
1296 const std::vector<TxPpduInfo>& generatedPpdus,
1297 const std::vector<StateCheckPoint>& stateCheckpoints,
1298 const std::vector<CcaCheckPoint>& ccaCheckpoints,
1299 const std::vector<CcaThresholdUpdatePoint>& ccaThresholdUpdates)
1300{
1302
1304
1305 for (const auto& generatedPpdu : generatedPpdus)
1306 {
1307 Simulator::Schedule(delay + generatedPpdu.startTime,
1309 this,
1310 generatedPpdu.power,
1311 generatedPpdu.centerFreq,
1312 generatedPpdu.bandwidth);
1313 }
1314
1315 std::size_t index = 0;
1316 for (const auto& generatedSignal : generatedSignals)
1317 {
1318 Simulator::Schedule(delay + generatedSignal.startTime,
1320 this,
1321 m_signalGenerators.at(index++),
1322 generatedSignal.power,
1323 generatedSignal.centerFreq,
1324 generatedSignal.bandwidth,
1325 generatedSignal.duration);
1326 }
1327
1328 if (ccaCheckpoints.empty())
1329 {
1330 Simulator::Schedule(delay + (testStep / 2),
1332 this,
1333 scenario,
1334 0,
1335 Time(),
1336 Time(),
1338 std::vector<Time>{});
1339 }
1340 else
1341 {
1342 for (const auto& checkpoint : ccaCheckpoints)
1343 {
1344 Simulator::Schedule(delay + checkpoint.timePoint,
1346 this,
1347 scenario,
1348 checkpoint.expectedCcaNotifications,
1349 Simulator::Now() + delay + checkpoint.expectedCcaStartTime,
1350 Simulator::Now() + delay + checkpoint.expectedCcaEndTime,
1351 checkpoint.expectedChannelListType,
1352 checkpoint.expectedPer20MhzDurations);
1353 }
1354 }
1355
1356 for (const auto& checkpoint : stateCheckpoints)
1357 {
1358 Simulator::Schedule(delay + checkpoint.timePoint,
1360 this,
1361 scenario,
1362 checkpoint.expectedPhyState);
1363 }
1364
1365 for (const auto& ccaThresholdUpdate : ccaThresholdUpdates)
1366 {
1367 Simulator::Schedule(delay + ccaThresholdUpdate.timePoint,
1369 this,
1370 ccaThresholdUpdate.ccaThreshold);
1371 }
1372}
1373
1374void
1376{
1377 NS_LOG_FUNCTION(this);
1378 m_rxPhy->ConfigureStandard(m_standard); // make sure to clear PHY states
1379 m_rxPhyStateListener->Reset();
1380 UpdateCcaThreshold(dBm_u{-62}); // restore default CCA threshold
1381}
1382
1383void
1385{
1387 switch (static_cast<uint16_t>(m_channelWidth))
1388 {
1389 case 20:
1390 default:
1391 // no Per-20 MHz CCA
1394 break;
1395 case 40:
1398 break;
1399 case 80:
1401 MicroSeconds(0),
1402 MicroSeconds(0),
1403 MicroSeconds(0),
1404 MicroSeconds(0),
1405 });
1407 MicroSeconds(0),
1408 MicroSeconds(0),
1409 MicroSeconds(0),
1410 MicroSeconds(0),
1411 });
1412 break;
1413 case 160:
1415 MicroSeconds(0),
1416 MicroSeconds(0),
1417 MicroSeconds(0),
1418 MicroSeconds(0),
1419 MicroSeconds(0),
1420 MicroSeconds(0),
1421 MicroSeconds(0),
1422 MicroSeconds(0),
1423 });
1425 MicroSeconds(0),
1426 MicroSeconds(0),
1427 MicroSeconds(0),
1428 MicroSeconds(0),
1429 MicroSeconds(0),
1430 MicroSeconds(0),
1431 MicroSeconds(0),
1432 MicroSeconds(0),
1433 });
1434 break;
1435 case 320:
1437 MicroSeconds(0),
1438 MicroSeconds(0),
1439 MicroSeconds(0),
1440 MicroSeconds(0),
1441 MicroSeconds(0),
1442 MicroSeconds(0),
1443 MicroSeconds(0),
1444 MicroSeconds(0),
1445 MicroSeconds(0),
1446 MicroSeconds(0),
1447 MicroSeconds(0),
1448 MicroSeconds(0),
1449 MicroSeconds(0),
1450 MicroSeconds(0),
1451 MicroSeconds(0),
1452 MicroSeconds(0),
1453 });
1455 MicroSeconds(0),
1456 MicroSeconds(0),
1457 MicroSeconds(0),
1458 MicroSeconds(0),
1459 MicroSeconds(0),
1460 MicroSeconds(0),
1461 MicroSeconds(0),
1462 MicroSeconds(0),
1463 MicroSeconds(0),
1464 MicroSeconds(0),
1465 MicroSeconds(0),
1466 MicroSeconds(0),
1467 MicroSeconds(0),
1468 MicroSeconds(0),
1469 MicroSeconds(0),
1470 MicroSeconds(0),
1471 });
1472 break;
1473 }
1474}
1475
1476void
1478{
1479 // WifiHelper::EnableLogComponents ();
1480 // LogComponentEnable("WifiPhyCcaTest", LOG_LEVEL_ALL);
1481
1483
1484 Ptr<Node> rxNode = CreateObject<Node>();
1486 rxDev->SetStandard(m_standard);
1487 auto vhtConfiguration = CreateObject<VhtConfiguration>();
1488 rxDev->SetVhtConfiguration(vhtConfiguration);
1490 {
1491 auto ehtConfiguration = CreateObject<EhtConfiguration>();
1492 rxDev->SetEhtConfiguration(ehtConfiguration);
1493 }
1495 m_rxPhyStateListener = std::make_unique<CcaTestPhyListener>();
1496 m_rxPhy->RegisterListener(m_rxPhyStateListener);
1498 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
1500 m_rxPhy->SetErrorRateModel(rxErrorModel);
1501 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
1503 m_rxPhy->SetPreambleDetectionModel(preambleDetectionModel);
1504 m_rxPhy->AddChannel(spectrumChannel);
1505 m_rxPhy->ConfigureStandard(m_standard);
1506 m_rxPhy->SetDevice(rxDev);
1507 rxDev->SetPhy(m_rxPhy);
1508 rxNode->AddDevice(rxDev);
1509
1510 Ptr<Node> txNode = CreateObject<Node>();
1513 m_uxPhy->SetAttribute("ChannelSwitchDelay", TimeValue(Seconds(0)));
1515 m_uxPhy->SetInterferenceHelper(txInterferenceHelper);
1517 m_uxPhy->SetErrorRateModel(txErrorModel);
1518 m_uxPhy->AddChannel(spectrumChannel);
1519 m_uxPhy->ConfigureStandard(m_standard);
1520 m_uxPhy->SetDevice(txDev);
1521 txDev->SetPhy(m_uxPhy);
1522 txNode->AddDevice(txDev);
1523
1524 for (std::size_t i = 0; i < m_numSignalGenerators; ++i)
1525 {
1526 Ptr<Node> signalGeneratorNode = CreateObject<Node>();
1527 Ptr<NonCommunicatingNetDevice> signalGeneratorDev =
1530 signalGenerator->SetDevice(signalGeneratorDev);
1531 signalGenerator->SetChannel(spectrumChannel);
1532 signalGenerator->SetDutyCycle(1);
1533 signalGeneratorNode->AddDevice(signalGeneratorDev);
1534 m_signalGenerators.push_back(signalGenerator);
1535 }
1536}
1537
1538void
1540{
1543 int64_t streamNumber = 0;
1544 m_rxPhy->AssignStreams(streamNumber);
1545 m_uxPhy->AssignStreams(streamNumber);
1546
1547 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
1550 m_standard,
1552 ->number;
1553
1554 m_rxPhy->SetOperatingChannel(
1556 m_uxPhy->SetOperatingChannel(
1558
1559 const auto phyHeaderDuration =
1561
1562 const auto& ppduDurations =
1564
1565 Time delay{Seconds(1.0)};
1567
1568 const auto tx1Start = MicroSeconds(0);
1569
1570 const auto txEndSignal1 = MicroSeconds(100);
1571 const auto txDuration1 = txEndSignal1 - tx1Start;
1572
1573 const auto tx2Start = MicroSeconds(50);
1574
1575 const auto txEndSignal2 = MicroSeconds(150);
1576 const auto txDuration2 = txEndSignal2 - tx2Start;
1577
1578 const auto txDiff = tx2Start - tx1Start;
1579
1580 const auto thresholdUpdateTime = MicroSeconds(75);
1581
1582 //----------------------------------------------------------------------------------------------------------------------------------
1583 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal below the
1584 // energy detection threshold occupies P20
1586 delay,
1587 "Reception of a signal that occupies P20 below ED threshold",
1588 {{dBm_u{-65}, tx1Start, txDuration1, P20_CENTER_FREQUENCY, MHz_u{20}}},
1589 {},
1590 {
1591 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1592 {txEndSignal1 - smallDelta,
1593 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1594 {txEndSignal1 + smallDelta, WifiPhyState::IDLE} // IDLE just after the transmission ends
1595 },
1596 {});
1597 delay += testStep;
1598
1599 //----------------------------------------------------------------------------------------------------------------------------------
1600 // Verify PHY state is CCA-BUSY as long as a 20 MHz signal above the energy detection threshold
1601 // occupies P20
1602 if (m_channelWidth > MHz_u{20})
1603 {
1604 m_expectedPer20MhzCcaBusyDurations.at(0).at(0) = txDuration1;
1605 }
1607 delay,
1608 "Reception of signal that occupies P20 above ED threshold",
1609 {{dBm_u{-60}, tx1Start, txDuration1, P20_CENTER_FREQUENCY, MHz_u{20}}},
1610 {},
1611 {
1612 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1613 {txEndSignal1 - smallDelta,
1614 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1615 {txEndSignal1 + smallDelta, WifiPhyState::IDLE} // IDLE just after the transmission ends
1616 },
1617 {{txEndSignal1 - smallDelta,
1618 1,
1619 tx1Start,
1620 txEndSignal1,
1623 delay += testStep;
1625
1626 //----------------------------------------------------------------------------------------------------------------------------------
1627 // Verify PHY state is CCA-BUSY as long as the sum of 20 MHz signals occupying P20 is above the
1628 // energy detection threshold
1629 if (m_channelWidth > MHz_u{20})
1630 {
1631 m_expectedPer20MhzCcaBusyDurations.at(0).at(0) = tx2Start - tx1Start;
1632 }
1634 delay,
1635 "Reception of two 20 MHz signals that occupies P20 below ED threshold with "
1636 "sum above ED threshold",
1637 {{dBm_u{-64}, tx1Start, txDuration1, P20_CENTER_FREQUENCY, MHz_u{20}},
1638 {dBm_u{-65}, tx2Start, txDuration2, P20_CENTER_FREQUENCY, MHz_u{20}}},
1639 {},
1640 {
1641 {tx2Start + aCcaTimeWithDelta,
1642 WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1643 {txEndSignal1 - smallDelta,
1644 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1645 {txEndSignal1 + smallDelta, WifiPhyState::IDLE} // IDLE just after the transmission ends
1646 },
1647 {{txEndSignal1 - smallDelta,
1648 1,
1649 tx2Start,
1650 txEndSignal1,
1653 delay += testStep;
1655
1656 //----------------------------------------------------------------------------------------------------------------------------------
1657 // Verify PHY state stays IDLE when a 20 MHz PPDU with received power below the
1658 // corresponding CCA sensitivity threshold occupies P20
1659 ScheduleTest(delay,
1660 "Reception of a 20 MHz PPDU that occupies P20 below CCA sensitivity threshold",
1661 {},
1662 {{dBm_u{-85}, tx1Start, P20_CENTER_FREQUENCY, MHz_u{20}}},
1663 {
1664 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1665 {ppduDurations.at(MHz_u{20}) - smallDelta,
1666 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1667 {ppduDurations.at(MHz_u{20}) + smallDelta,
1668 WifiPhyState::IDLE} // IDLE just after the transmission ends
1669 },
1670 {});
1671 delay += testStep;
1672
1673 //----------------------------------------------------------------------------------------------------------------------------------
1674 // Verify PHY state transitions to CCA-BUSY when an PPDU with received power above the CCA
1675 // sensitivity threshold occupies P20. The per20Bitmap should indicate idle on the primary 20
1676 // MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1678 delay,
1679 "Reception of a 20 MHz PPDU that occupies P20 above CCA sensitivity threshold",
1680 {},
1681 {{dBm_u{-80}, tx1Start, P20_CENTER_FREQUENCY, MHz_u{20}}},
1682 {
1683 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1684 {ppduDurations.at(MHz_u{20}) - smallDelta,
1685 WifiPhyState::RX}, // RX just before the transmission ends
1686 {ppduDurations.at(MHz_u{20}) + smallDelta,
1687 WifiPhyState::IDLE} // IDLE just after the transmission ends
1688 },
1690 1,
1691 aCcaTime,
1695 delay += testStep;
1696
1697 //----------------------------------------------------------------------------------------------------------------------------------
1698 // Verify PHY state stays IDLE when a 40 MHz PPDU with received power below the CCA
1699 // sensitivity threshold occupies P40
1700 ScheduleTest(delay,
1701 "Reception of a 40 MHz PPDU that occupies P20 below CCA sensitivity threshold",
1702 {},
1703 {{dBm_u{-80}, tx1Start, P40_CENTER_FREQUENCY, MHz_u{40}}},
1704 {
1705 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1706 {ppduDurations.at(MHz_u{40}) - smallDelta,
1707 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1708 {ppduDurations.at(MHz_u{40}) + smallDelta,
1709 WifiPhyState::IDLE} // IDLE just after the transmission ends
1710 },
1711 {});
1712 delay += testStep;
1713
1714 //----------------------------------------------------------------------------------------------------------------------------------
1715 // Verify PHY state transitions to CCA-BUSY when an PPDU with received power above the CCA
1716 // sensitivity threshold occupies P40. The per20Bitmap should indicate idle on the primary 20
1717 // MHz subchannel because received power is below -72 dBm (27.3.20.6.5).
1719 delay,
1720 "Reception of a 40 MHz PPDU that occupies P40 above CCA sensitivity threshold",
1721 {},
1722 {{dBm_u{-75}, tx1Start, P40_CENTER_FREQUENCY, MHz_u{40}}},
1723 {
1724 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1725 {ppduDurations.at(MHz_u{40}) - smallDelta,
1726 (m_channelWidth > MHz_u{20})
1728 : WifiPhyState::CCA_BUSY}, // RX or IDLE just before the transmission ends
1729 {ppduDurations.at(MHz_u{40}) + smallDelta,
1730 WifiPhyState::IDLE} // IDLE just after the transmission ends
1731 },
1733 1,
1734 aCcaTime,
1738 delay += testStep;
1739
1740 if (m_channelWidth > MHz_u{20})
1741 {
1742 //----------------------------------------------------------------------------------------------------------------------------------
1743 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a 20 MHz signal
1744 // below the energy detection threshold occupies S20
1745 ScheduleTest(delay,
1746 "Reception of a 20 MHz signal that occupies S20 below ED threshold",
1747 {{dBm_u{-65}, tx1Start, txDuration1, S20_CENTER_FREQUENCY, MHz_u{20}}},
1748 {},
1749 {
1750 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1751 {txEndSignal1 - smallDelta,
1752 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1753 {txEndSignal1 + smallDelta,
1754 WifiPhyState::IDLE} // IDLE just after the transmission ends
1755 },
1756 {});
1757 delay += testStep;
1758
1759 //----------------------------------------------------------------------------------------------------------------------------------
1760 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz signal
1761 // above the energy detection threshold occupies S20
1762 m_expectedPer20MhzCcaBusyDurations.at(0).at(1) = txDuration1;
1763 ScheduleTest(delay,
1764 "Reception of a 20 MHz signal that occupies S20 above ED threshold",
1765 {{dBm_u{-60}, tx1Start, txDuration1, S20_CENTER_FREQUENCY, MHz_u{20}}},
1766 {},
1767 {
1768 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1769 {txEndSignal1 - smallDelta,
1770 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1771 {txEndSignal1 + smallDelta,
1772 WifiPhyState::IDLE} // IDLE just after the transmission ends
1773 },
1774 {{txEndSignal1 - smallDelta,
1775 1,
1776 tx1Start,
1777 txEndSignal1,
1780 delay += testStep;
1782
1783 //----------------------------------------------------------------------------------------------------------------------------------
1784 // Verify PHY state is CCA-BUSY as long as a 40 MHz signal above the energy detection
1785 // threshold occupies P40
1786 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 2, txDuration1);
1788 delay,
1789 "Reception of a 40 MHz signal that occupies P40 above ED threshold",
1790 {{dBm_u{-55}, tx1Start, txDuration1, P40_CENTER_FREQUENCY, MHz_u{40}}},
1791 {},
1792 {
1793 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1794 {txEndSignal1 - smallDelta,
1795 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1796 {txEndSignal1 + smallDelta,
1797 WifiPhyState::IDLE} // IDLE just after the transmission ends
1798 },
1799 {{txEndSignal1 - smallDelta,
1800 1,
1801 tx1Start,
1802 txEndSignal1,
1805 delay += testStep;
1807
1808 //----------------------------------------------------------------------------------------------------------------------------------
1809 // Verify PHY notifies CCA-BUSY for the primary channel while the secondary channel was
1810 // already in CCA-BUSY state
1811 m_expectedPer20MhzCcaBusyDurations.at(0).at(1) = txDuration1;
1812 m_expectedPer20MhzCcaBusyDurations.at(1).at(0) = txDuration2;
1813 m_expectedPer20MhzCcaBusyDurations.at(1).at(1) = txDiff;
1815 delay,
1816 "Reception of a signal that occupies S20 followed by the reception of another signal "
1817 "that occupies P20",
1818 {{dBm_u{-60}, tx1Start, txDuration1, S20_CENTER_FREQUENCY, MHz_u{20}},
1819 {dBm_u{-60}, tx2Start, txDuration2, P20_CENTER_FREQUENCY, MHz_u{20}}},
1820 {},
1821 {
1823 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
1824 {tx2Start + aCcaTimeWithDelta,
1825 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after aCcaTimeWithDelta
1826 // that followed the second transmission
1827 {txEndSignal2 - smallDelta,
1828 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
1829 {txEndSignal2 + smallDelta,
1830 WifiPhyState::IDLE} // IDLE just after the transmission ends
1831 },
1832 {{aCcaTimeWithDelta, // notification upon reception of the first signal
1833 1,
1834 tx1Start,
1835 txEndSignal1,
1838 {tx2Start + aCcaTimeWithDelta, // notification upon reception of the second signal
1839 2,
1840 tx1Start,
1841 txEndSignal2,
1844 delay += testStep;
1846
1847 //----------------------------------------------------------------------------------------------------------------------------------
1848 // Verify PHY updates per-20 MHz CCA durations if a signal arrives on the secondary channel
1849 // while primary is CCA-BUSY
1850 m_expectedPer20MhzCcaBusyDurations.at(0).at(0) = txDuration1;
1851 m_expectedPer20MhzCcaBusyDurations.at(1).at(0) = txDiff;
1852 m_expectedPer20MhzCcaBusyDurations.at(1).at(1) = txDuration2;
1854 delay,
1855 "Reception of a signal that occupies P20 followed by the reception of another signal "
1856 "that occupies S20",
1857 {{dBm_u{-60}, tx1Start, txDuration1, P20_CENTER_FREQUENCY, MHz_u{20}},
1858 {dBm_u{-60}, tx2Start, txDuration2, S20_CENTER_FREQUENCY, MHz_u{20}}},
1859 {},
1860 {
1861 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
1862 {tx2Start + aCcaTimeWithDelta,
1863 WifiPhyState::CCA_BUSY}, // state of primary is still CCA-BUSY after
1864 // aCcaTimeWithDelta that followed the second transmission
1865 {txEndSignal1 - smallDelta,
1866 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the first transmission ends
1867 {txEndSignal1 + smallDelta,
1868 WifiPhyState::IDLE} // IDLE just after the first transmission ends
1869 },
1870 {{aCcaTimeWithDelta, // notification upon reception of the first signal
1871 1,
1872 tx1Start,
1873 txEndSignal1,
1876 {tx2Start + aCcaTimeWithDelta, // notification upon reception of the second signal
1877 2,
1878 tx1Start,
1879 txEndSignal1,
1882 delay += testStep;
1884
1885 //----------------------------------------------------------------------------------------------------------------------------------
1886 // Verify PHY state stays IDLE when a 20 MHz PPDU with received power below the CCA
1887 // sensitivity threshold occupies S40
1888 ScheduleTest(delay,
1889 "Reception of a 20 MHz PPDU that occupies S20 below CCA sensitivity threshold",
1890 {},
1891 {{dBm_u{-75}, tx1Start, S20_CENTER_FREQUENCY, MHz_u{20}}},
1892 {
1893 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1894 {ppduDurations.at(MHz_u{20}) - smallDelta,
1895 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1896 {ppduDurations.at(MHz_u{20}) + smallDelta,
1897 WifiPhyState::IDLE} // IDLE just after the transmission ends
1898 },
1899 {});
1900 delay += testStep;
1901
1902 //----------------------------------------------------------------------------------------------------------------------------------
1903 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 20 MHz PPDU
1904 // with received power above the CCA sensitivity threshold occupies S20
1905 m_expectedPer20MhzCcaBusyDurations.at(0).at(1) = ppduDurations.at(MHz_u{20});
1906 ScheduleTest(delay,
1907 "Reception of a 20 MHz PPDU that occupies S20 above CCA sensitivity threshold",
1908 {},
1909 {{dBm_u{-70}, tx1Start, S20_CENTER_FREQUENCY, MHz_u{20}}},
1910 {
1911 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1912 {ppduDurations.at(MHz_u{20}) - smallDelta,
1913 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1914 {ppduDurations.at(MHz_u{20}) + smallDelta,
1915 WifiPhyState::IDLE} // IDLE just after the transmission ends
1916 },
1918 1,
1919 tx1Start,
1920 ppduDurations.at(MHz_u{20}),
1923 delay += testStep;
1925
1926 //----------------------------------------------------------------------------------------------------------------------------------
1927 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a signal
1928 // above the energy detection threshold occupies the S20 while a 40 MHz PPDU below the CCA
1929 // sensitivity threshold is received on P40.
1930 m_expectedPer20MhzCcaBusyDurations.at(0).at(1) = txDuration1;
1931 m_expectedPer20MhzCcaBusyDurations.at(1).at(1) = txDiff - aCcaTime;
1933 delay,
1934 "Reception of a 20 MHz signal that occupies S20 above ED threshold followed by a 40 "
1935 "MHz PPDU that occupies P40 below CCA sensitivity threshold",
1936 {{dBm_u{-60},
1937 tx1Start,
1938 txDuration1,
1940 MHz_u{20}}}, // signal on S20 above threshold
1941 {{dBm_u{-80},
1942 tx2Start,
1944 MHz_u{40}}}, // PPDU on P40 below threshold
1945 {
1946 {tx2Start + aCcaTimeWithDelta, WifiPhyState::IDLE}, // PHY state stays IDLE
1947 },
1948 {{tx2Start - smallDelta,
1949 1,
1950 tx1Start,
1951 txEndSignal1,
1954 {txEndSignal1 - smallDelta,
1955 2,
1956 tx1Start,
1957 txEndSignal1,
1960 delay += testStep;
1962 }
1963
1964 if (m_channelWidth > MHz_u{40})
1965 {
1966 //----------------------------------------------------------------------------------------------------------------------------------
1967 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal below
1968 // the energy detection threshold occupies S40
1970 delay,
1971 "Reception of a signal that occupies P20 below ED threshold",
1972 {{dBm_u{-65}, tx1Start, txDuration1, S40_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}}},
1973 {},
1974 {
1975 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1976 {txEndSignal1 - smallDelta,
1977 WifiPhyState::IDLE}, // IDLE just before the transmission ends
1978 {txEndSignal1 + smallDelta,
1979 WifiPhyState::IDLE} // IDLE just after the transmission ends
1980 },
1981 {});
1982 delay += testStep;
1983
1984 //----------------------------------------------------------------------------------------------------------------------------------
1985 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy detection
1986 // threshold occupies the first 20 MHz subchannel of the S40: 27.3.20.6.4: Any signal within
1987 // the secondary 40 MHz channel at or above a threshold of –59 dBm within a period of
1988 // aCcaTimeWithDelta after the signal arrives at the receiver’s antenna(s).
1989 m_expectedPer20MhzCcaBusyDurations.at(0).at(2) = txDuration1;
1991 delay,
1992 "Reception of a 20 MHz signal that occupies the first subchannel of S40 above "
1993 "ED threshold",
1994 {{dBm_u{-55}, tx1Start, txDuration1, S40_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}}},
1995 {},
1996 {
1997 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
1998 {txEndSignal1 - smallDelta,
1999 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2000 {txEndSignal1 + smallDelta,
2001 WifiPhyState::IDLE} // IDLE just after the transmission ends
2002 },
2003 {{txEndSignal1 - smallDelta,
2004 1,
2005 tx1Start,
2006 txEndSignal1,
2009 delay += testStep;
2011
2012 //----------------------------------------------------------------------------------------------------------------------------------
2013 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection threshold
2014 // occupies the second 20 MHz subchannel of the S40
2016 delay,
2017 "Reception of a 20 MHz signal that occupies the second subchannel of "
2018 "S40 below ED threshold",
2019 {{dBm_u{-65}, tx1Start, txDuration1, S40_CENTER_FREQUENCY + MHz_u{10}, MHz_u{20}}},
2020 {},
2021 {
2022 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2023 {txEndSignal1 - smallDelta,
2024 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2025 {txEndSignal1 + smallDelta,
2026 WifiPhyState::IDLE} // IDLE just after the transmission ends
2027 },
2028 {});
2029 delay += testStep;
2030
2031 //----------------------------------------------------------------------------------------------------------------------------------
2032 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy detection
2033 // threshold occupies the second 20 MHz subchannel of the S40: 27.3.20.6.4: Any signal
2034 // within the secondary 40 MHz channel at or above a threshold of –59 dBm within a period of
2035 // aCcaTimeWithDelta after the signal arrives at the receiver's antenna(s).
2036 m_expectedPer20MhzCcaBusyDurations.at(0).at(3) = txDuration1;
2038 delay,
2039 "Reception of a 20 MHz signal that occupies the second subchannel of S40 "
2040 "above ED threshold",
2041 {{dBm_u{-55}, tx1Start, txDuration1, S40_CENTER_FREQUENCY + MHz_u{10}, MHz_u{20}}},
2042 {},
2043 {
2044 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2045 {txEndSignal1 - smallDelta,
2046 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2047 {txEndSignal1 + smallDelta,
2048 WifiPhyState::IDLE} // IDLE just after the transmission ends
2049 },
2050 {{txEndSignal1 - smallDelta,
2051 1,
2052 tx1Start,
2053 txEndSignal1,
2056 delay += testStep;
2058
2059 //----------------------------------------------------------------------------------------------------------------------------------
2060 // Verify PHY state stays IDLE for the S40 if a signal below the energy detection threshold
2061 // occupies S40
2062 ScheduleTest(delay,
2063 "Reception of a 40 MHz signal that occupies S40 below ED threshold",
2064 {{dBm_u{-60}, tx1Start, txDuration1, S40_CENTER_FREQUENCY, MHz_u{40}}},
2065 {},
2066 {
2067 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2068 {txEndSignal1 - smallDelta,
2069 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2070 {txEndSignal1 + smallDelta,
2071 WifiPhyState::IDLE} // IDLE just after the transmission ends
2072 },
2073 {});
2074 delay += testStep;
2075
2076 //----------------------------------------------------------------------------------------------------------------------------------
2077 // Verify PHY notifies CCA-BUSY for the S40 as long as a signal above the energy detection
2078 // threshold occupies S40: 27.3.20.6.4: Any signal within the secondary 40 MHz channel at or
2079 // above a threshold of –59 dBm within a period of aCcaTimeWithDelta after the signal
2080 // arrives at the receiver's antenna(s).
2081 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 2, 2, txDuration1);
2083 delay,
2084 "Reception of a 20 MHz signal that occupies the second subchannel of S40 above ED "
2085 "threshold",
2086 {{dBm_u{-55}, tx1Start, txDuration1, S40_CENTER_FREQUENCY, MHz_u{40}}},
2087 {},
2088 {
2089 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2090 {txEndSignal1 - smallDelta,
2091 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2092 {txEndSignal1 + smallDelta,
2093 WifiPhyState::IDLE} // IDLE just after the transmission ends
2094 },
2095 {{txEndSignal1 - smallDelta,
2096 1,
2097 tx1Start,
2098 txEndSignal1,
2101 delay += testStep;
2103
2104 //----------------------------------------------------------------------------------------------------------------------------------
2105 // Verify PHY state is CCA-BUSY as long as a 80 MHz signal above the energy detection
2106 // threshold occupies P80
2107 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 4, txDuration1);
2109 delay,
2110 "Reception of a 80 MHz signal that occupies P80 above ED threshold",
2111 {{dBm_u{-55}, tx1Start, txDuration1, P80_CENTER_FREQUENCY, MHz_u{80}}},
2112 {},
2113 {
2114 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
2115 {txEndSignal1 - smallDelta,
2116 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2117 {txEndSignal1 + smallDelta,
2118 WifiPhyState::IDLE} // IDLE just after the transmission ends
2119 },
2120 {{txEndSignal1 - smallDelta,
2121 1,
2122 tx1Start,
2123 txEndSignal1,
2126 delay += testStep;
2128
2129 //----------------------------------------------------------------------------------------------------------------------------------
2130 // Verify PHY notifies CCA-BUSY for the P20 channel while the S40 channel was already in
2131 // CCA-BUSY state
2132 m_expectedPer20MhzCcaBusyDurations.at(0).at(2) = txDuration1;
2133 m_expectedPer20MhzCcaBusyDurations.at(1).at(0) = txDuration2;
2134 m_expectedPer20MhzCcaBusyDurations.at(1).at(2) = txDiff;
2136 delay,
2137 "Reception of a 20 MHz signal that occupies S40 followed by the reception of another "
2138 "20 MHz signal that occupies P20",
2139 {{dBm_u{-55}, tx1Start, txDuration1, S40_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}},
2140 {dBm_u{-55}, tx2Start, txDuration2, P20_CENTER_FREQUENCY, MHz_u{20}}},
2141 {},
2142 {
2144 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2145 {tx2Start + aCcaTimeWithDelta,
2146 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after aCcaTimeWithDelta
2147 // that followed the second transmission
2148 {txEndSignal2 - smallDelta,
2149 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2150 {txEndSignal2 + txEndSignal1 + smallDelta,
2151 WifiPhyState::IDLE} // IDLE just after the transmission ends
2152 },
2153 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2154 1,
2155 tx1Start,
2156 txEndSignal1,
2159 {tx2Start + aCcaTimeWithDelta, // notification upon reception of the second signal
2160 2,
2161 tx1Start,
2162 txEndSignal2,
2165 delay += testStep;
2167
2168 //----------------------------------------------------------------------------------------------------------------------------------
2169 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S40
2170 // channel was already in CCA-BUSY state
2171 m_expectedPer20MhzCcaBusyDurations.at(0).at(2) = txDuration1;
2172 m_expectedPer20MhzCcaBusyDurations.at(1).at(1) = txDuration2;
2173 m_expectedPer20MhzCcaBusyDurations.at(1).at(2) = txDiff;
2175 delay,
2176 "Reception of a signal that occupies S40 followed by the reception of another signal "
2177 "that occupies S20",
2178 {{dBm_u{-55}, tx1Start, txDuration1, S40_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}},
2179 {dBm_u{-55}, tx2Start, txDuration2, S20_CENTER_FREQUENCY, MHz_u{20}}},
2180 {},
2181 {
2183 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
2184 {tx2Start + aCcaTimeWithDelta, WifiPhyState::IDLE}, // state of primary stays IDLE
2185 {txEndSignal2 - smallDelta,
2186 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2187 {txEndSignal2 + smallDelta,
2188 WifiPhyState::IDLE} // IDLE just after the transmission ends
2189 },
2190 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2191 1,
2192 tx1Start,
2193 txEndSignal1,
2196 {tx2Start + aCcaTimeWithDelta, // notification upon reception of the second signal
2197 2,
2198 tx1Start,
2199 txEndSignal2,
2202 delay += testStep;
2204
2205 //----------------------------------------------------------------------------------------------------------------------------------
2206 // Verify PHY state stays IDLE when a 40 MHz PPDU with received power below the CCA
2207 // sensitivity threshold occupies S40
2208 ScheduleTest(delay,
2209 "Reception of a 40 MHz PPDU that occupies S40 below CCA sensitivity threshold",
2210 {},
2211 {{dBm_u{-75}, tx1Start, S40_CENTER_FREQUENCY, MHz_u{40}}},
2212 {
2213 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2214 {ppduDurations.at(MHz_u{40}) - smallDelta,
2215 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2216 {ppduDurations.at(MHz_u{40}) + smallDelta,
2217 WifiPhyState::IDLE} // IDLE just after the transmission ends
2218 },
2219 {});
2220 delay += testStep;
2221
2222 //----------------------------------------------------------------------------------------------------------------------------------
2223 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 40 MHz PPDU
2224 // with received power above the CCA sensitivity threshold occupies S40
2225 const dBm_u rxPower{(m_standard == WIFI_STANDARD_80211ax) ? -70 : -67.0};
2226 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 2,
2227 2,
2228 ppduDurations.at(MHz_u{40}));
2229 ScheduleTest(delay,
2230 "Reception of a 40 MHz PPDU that occupies S40 above CCA sensitivity threshold",
2231 {},
2232 {{rxPower, tx1Start, S40_CENTER_FREQUENCY, MHz_u{40}}},
2233 {
2234 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2235 {ppduDurations.at(MHz_u{40}) - smallDelta,
2236 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2237 {ppduDurations.at(MHz_u{40}) + smallDelta,
2238 WifiPhyState::IDLE} // IDLE just after the transmission ends
2239 },
2241 1,
2242 tx1Start,
2243 ppduDurations.at(MHz_u{40}),
2246 delay += testStep;
2248
2249 //----------------------------------------------------------------------------------------------------------------------------------
2250 // Verify PHY state stays IDLE but CCA-BUSY indication is still reported as long as a signal
2251 // above the energy detection threshold occupies the S40 while a 80 MHz PPDU below the CCA
2252 // sensitivity threshold is received on P80.
2253 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 2, 2, txDuration1);
2254 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(1).begin() + 2, 2, txDiff - aCcaTime);
2256 delay,
2257 "Reception of a 40 MHz signal that occupies S40 above ED threshold followed by a 80 "
2258 "MHz PPDU that occupies P80 below CCA sensitivity threshold",
2259 {{dBm_u{-55},
2260 tx1Start,
2261 txDuration1,
2263 MHz_u{40}}}, // signal on S40 above threshold
2264 {{dBm_u{-80},
2265 tx2Start,
2267 MHz_u{80}}}, // PPDU on P80 below threshold
2268 {
2269 {tx2Start + aCcaTimeWithDelta, WifiPhyState::IDLE}, // PHY state stays IDLE
2270 },
2271 {{tx2Start - smallDelta,
2272 1,
2273 tx1Start,
2274 txEndSignal1,
2277 {txEndSignal1 - smallDelta,
2278 2,
2279 tx1Start,
2280 txEndSignal1,
2283 delay += testStep;
2285 }
2286 else // 20 or 40 MHz receiver
2287 {
2288 //----------------------------------------------------------------------------------------------------------------------------------
2289 // Verify PHY notifies CCA-BUSY when a 80 MHz PPDU with received power above the CCA
2290 // sensitivity threshold occupies P40 The per20Bitmap should indicate idle for all
2291 // subchannels because received power is below -62 dBm (27.3.20.6.5).
2293 delay,
2294 "Reception of a 80 MHz PPDU that occupies the 40 MHz band above CCA sensitivity "
2295 "threshold",
2296 {},
2297 {{dBm_u{-70}, tx1Start, P80_CENTER_FREQUENCY, MHz_u{80}}},
2298 {
2299 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCcaTimeWithDelta
2300 {ppduDurations.at(MHz_u{80}) - smallDelta,
2301 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2302 {ppduDurations.at(MHz_u{80}) + smallDelta,
2303 WifiPhyState::IDLE} // IDLE just after the transmission ends
2304 },
2306 1,
2307 aCcaTime,
2311 {ppduDurations.at(MHz_u{80}) - smallDelta,
2312 4, // 3 extra CCA_BUSY notifications during PHY header reception
2313 aCcaTime,
2314 ppduDurations.at(MHz_u{80}),
2317 delay += testStep;
2319
2320 //----------------------------------------------------------------------------------------------------------------------------------
2321 // Verify PHY notifies CCA-BUSY when a 80 MHz PPDU with received power above the CCA
2322 // sensitivity threshold occupies P40 The per20Bitmap should indicate CCA_BUSY for all
2323 // subchannels because received power is above -62 dBm (27.3.20.6.5).
2324 if (m_channelWidth > MHz_u{20})
2325 {
2326 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(),
2327 2,
2328 ppduDurations.at(80) - aCcaTime);
2329 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(1).begin(),
2330 2,
2331 ppduDurations.at(MHz_u{80}) - hePhyHeaderDuration);
2332 }
2334 delay,
2335 "Reception of a 80 MHz PPDU that occupies the 40 MHz band above CCA sensitivity "
2336 "threshold",
2337 {},
2338 {{dBm_u{-55}, tx1Start, P80_CENTER_FREQUENCY, MHz_u{80}}},
2339 {
2340 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA_BUSY after aCcaTimeWithDelta
2341 {ppduDurations.at(MHz_u{80}) - smallDelta,
2342 WifiPhyState::CCA_BUSY}, // CCA_BUSY just before the transmission ends
2343 {ppduDurations.at(MHz_u{80}) + smallDelta,
2344 WifiPhyState::IDLE} // IDLE just after the transmission ends
2345 },
2347 1,
2348 aCcaTime,
2352 {ppduDurations.at(MHz_u{80}) - smallDelta,
2353 4, // 3 extra CCA_BUSY notifications during PHY header reception
2354 aCcaTime,
2355 ppduDurations.at(MHz_u{80}),
2358 delay += testStep;
2360
2361 //----------------------------------------------------------------------------------------------------------------------------------
2362 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported when a signal not
2363 // occupying the operational channel is being received
2364 ScheduleTest(delay,
2365 "Reception of a 40 MHz PPDU that does not occupy the operational channel",
2366 {},
2367 {{dBm_u{-50}, tx1Start, S40_CENTER_FREQUENCY, MHz_u{40}}},
2368 {
2369 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2370 {ppduDurations.at(MHz_u{20}) - smallDelta,
2371 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2372 {ppduDurations.at(MHz_u{20}) + smallDelta,
2373 WifiPhyState::IDLE} // IDLE just after the transmission ends
2374 },
2375 {});
2376 delay += testStep;
2377 }
2378
2379 if (m_channelWidth > MHz_u{80})
2380 {
2381 //----------------------------------------------------------------------------------------------------------------------------------
2382 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2383 // energy detection threshold occupies the first 20 MHz subchannel of the S80
2385 delay,
2386 "Reception of a 20 MHz signal that occupies the first subchannel of S80 below "
2387 "ED threshold",
2388 {{dBm_u{-65}, tx1Start, txDuration1, S80_CENTER_FREQUENCY - MHz_u{30}, MHz_u{20}}},
2389 {},
2390 {
2391 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2392 {txEndSignal1 - smallDelta,
2393 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2394 {txEndSignal1 + smallDelta,
2395 WifiPhyState::IDLE} // IDLE just after the transmission ends
2396 },
2397 {});
2398 delay += testStep;
2399
2400 //----------------------------------------------------------------------------------------------------------------------------------
2401 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
2402 // energy detection threshold occupies the first 20 MHz subchannel of the S80 27.3.20.6.4:
2403 // Any signal within the secondary 80 MHz channel at or above –56 dBm.
2404 m_expectedPer20MhzCcaBusyDurations.at(0).at(4) = txDuration1;
2406 delay,
2407 "Reception of a 20 MHz signal that occupies the first subchannel of S80 above "
2408 "ED threshold",
2409 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY - MHz_u{30}, MHz_u{20}}},
2410 {},
2411 {
2412 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2413 {txEndSignal1 - smallDelta,
2414 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2415 {txEndSignal1 + smallDelta,
2416 WifiPhyState::IDLE} // IDLE just after the transmission ends
2417 },
2418 {{txEndSignal1 - smallDelta,
2419 1,
2420 tx1Start,
2421 txEndSignal1,
2424 delay += testStep;
2426
2427 //----------------------------------------------------------------------------------------------------------------------------------
2428 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a
2429 // signal below the energy detection threshold occupies the second 20 MHz
2430 // subchannel of the S80
2432 delay,
2433 "Reception of a 20 MHz signal that occupies the second subchannel of S80 "
2434 "below ED threshold",
2435 {{dBm_u{-65}, tx1Start, txDuration1, S80_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}}},
2436 {},
2437 {
2438 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2439 {txEndSignal1 - smallDelta,
2440 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2441 {txEndSignal1 + smallDelta,
2442 WifiPhyState::IDLE} // IDLE just after the transmission ends
2443 },
2444 {});
2445 delay += testStep;
2446
2447 //----------------------------------------------------------------------------------------------------------------------------------
2448 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal
2449 // above the energy detection threshold occupies the second 20 MHz subchannel
2450 // of the S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or
2451 // above –56 dBm.
2452 m_expectedPer20MhzCcaBusyDurations.at(0).at(5) = txDuration1;
2454 delay,
2455 "Reception of a 20 MHz signal that occupies the second subchannel of S80 "
2456 "above ED threshold",
2457 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}}},
2458 {},
2459 {
2460 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2461 {txEndSignal1 - smallDelta,
2462 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2463 {txEndSignal1 + smallDelta,
2464 WifiPhyState::IDLE} // IDLE just after the transmission ends
2465 },
2466 {{txEndSignal1 - smallDelta,
2467 1,
2468 tx1Start,
2469 txEndSignal1,
2472 delay += testStep;
2474
2475 //----------------------------------------------------------------------------------------------------------------------------------
2476 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a
2477 // signal below the energy detection threshold occupies the third 20 MHz
2478 // subchannel of the S80
2480 delay,
2481 "Reception of a 20 MHz signal that occupies the third subchannel of S80 "
2482 "below "
2483 "ED threshold",
2484 {{dBm_u{-65}, tx1Start, txDuration1, S80_CENTER_FREQUENCY + MHz_u{10}, MHz_u{20}}},
2485 {},
2486 {
2487 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2488 {txEndSignal1 - smallDelta,
2489 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2490 {txEndSignal1 + smallDelta,
2491 WifiPhyState::IDLE} // IDLE just after the transmission ends
2492 },
2493 {});
2494 delay += testStep;
2495
2496 //----------------------------------------------------------------------------------------------------------------------------------
2497 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal
2498 // above the energy detection threshold occupies the third 20 MHz subchannel of
2499 // the S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or
2500 // above –56 dBm.
2501 m_expectedPer20MhzCcaBusyDurations.at(0).at(6) = txDuration1;
2503 delay,
2504 "Reception of a 20 MHz signal that occupies the third subchannel of S80 "
2505 "above "
2506 "ED threshold",
2507 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY + MHz_u{10}, MHz_u{20}}},
2508 {},
2509 {
2510 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2511 {txEndSignal1 - smallDelta,
2512 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2513 {txEndSignal1 + smallDelta,
2514 WifiPhyState::IDLE} // IDLE just after the transmission ends
2515 },
2516 {{txEndSignal1 - smallDelta,
2517 1,
2518 tx1Start,
2519 txEndSignal1,
2522 delay += testStep;
2524
2525 //----------------------------------------------------------------------------------------------------------------------------------
2526 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a
2527 // signal below the energy detection threshold occupies the fourth 20 MHz
2528 // subchannel of the S80
2530 delay,
2531 "Reception of a 20 MHz signal that occupies the fourth subchannel of S80 "
2532 "below ED threshold",
2533 {{dBm_u{-65}, tx1Start, txDuration1, S80_CENTER_FREQUENCY + MHz_u{30}, MHz_u{20}}},
2534 {},
2535 {
2536 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2537 {txEndSignal1 - smallDelta,
2538 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2539 {txEndSignal1 + smallDelta,
2540 WifiPhyState::IDLE} // IDLE just after the transmission ends
2541 },
2542 {});
2543 delay += testStep;
2544
2545 //----------------------------------------------------------------------------------------------------------------------------------
2546 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal
2547 // above the energy detection threshold occupies the fourth 20 MHz subchannel
2548 // of the S80 27.3.20.6.4: Any signal within the secondary 80 MHz channel at or
2549 // above –56 dBm.
2550 m_expectedPer20MhzCcaBusyDurations.at(0).at(7) = txDuration1;
2552 delay,
2553 "Reception of a 20 MHz signal that occupies the fourth subchannel of S80 "
2554 "above ED threshold",
2555 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY + MHz_u{30}, MHz_u{20}}},
2556 {},
2557 {
2558 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2559 {txEndSignal1 - smallDelta,
2560 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2561 {txEndSignal1 + smallDelta,
2562 WifiPhyState::IDLE} // IDLE just after the transmission ends
2563 },
2564 {{txEndSignal1 - smallDelta,
2565 1,
2566 tx1Start,
2567 txEndSignal1,
2570 delay += testStep;
2572
2573 //----------------------------------------------------------------------------------------------------------------------------------
2574 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a
2575 // signal below the energy detection threshold occupies the first and second 20
2576 // MHz subchannels of the S80
2578 delay,
2579 "Reception of a 40 MHz signal that occupies the first and second "
2580 "subchannels "
2581 "of S80 below ED threshold",
2582 {{dBm_u{-65}, tx1Start, txDuration1, S80_CENTER_FREQUENCY - MHz_u{20}, MHz_u{40}}},
2583 {},
2584 {
2585 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2586 {txEndSignal1 - smallDelta,
2587 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2588 {txEndSignal1 + smallDelta,
2589 WifiPhyState::IDLE} // IDLE just after the transmission ends
2590 },
2591 {});
2592 delay += testStep;
2593
2594 //----------------------------------------------------------------------------------------------------------------------------------
2595 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal
2596 // above the energy detection threshold occupies the first and second 20 MHz
2597 // subchannels of the S80 27.3.20.6.4: Any signal within the secondary 80 MHz
2598 // channel at or above –56 dBm.
2599 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 4, 2, txDuration1);
2601 delay,
2602 "Reception of a 40 MHz signal that occupies the first and second "
2603 "subchannels "
2604 "of S80 above ED threshold",
2605 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY - MHz_u{20}, MHz_u{40}}},
2606 {},
2607 {
2608 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2609 {txEndSignal1 - smallDelta,
2610 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2611 {txEndSignal1 + smallDelta,
2612 WifiPhyState::IDLE} // IDLE just after the transmission ends
2613 },
2614 {{txEndSignal1 - smallDelta,
2615 1,
2616 tx1Start,
2617 txEndSignal1,
2620 delay += testStep;
2622
2623 //----------------------------------------------------------------------------------------------------------------------------------
2624 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a
2625 // signal below the energy detection threshold occupies the third and fourth 20
2626 // MHz subchannels of the S80
2628 delay,
2629 "Reception of a 40 MHz signal that occupies the third and fourth "
2630 "subchannels "
2631 "of S80 below ED threshold",
2632 {{dBm_u{-65}, tx1Start, txDuration1, S80_CENTER_FREQUENCY + MHz_u{20}, MHz_u{40}}},
2633 {},
2634 {
2635 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2636 {txEndSignal1 - smallDelta,
2637 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2638 {txEndSignal1 + smallDelta,
2639 WifiPhyState::IDLE} // IDLE just after the transmission ends
2640 },
2641 {});
2642 delay += testStep;
2643
2644 //----------------------------------------------------------------------------------------------------------------------------------
2645 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal
2646 // above the energy detection threshold occupies the third and fourth 20 MHz
2647 // subchannels of the S80 27.3.20.6.4: Any signal within the secondary 80 MHz
2648 // channel at or above –56 dBm.
2649 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 6, 2, txDuration1);
2651 delay,
2652 "Reception of a 40 MHz signal that occupies the third and fourth "
2653 "subchannels "
2654 "of S80 above ED threshold",
2655 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY + MHz_u{20}, MHz_u{40}}},
2656 {},
2657 {
2658 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2659 {txEndSignal1 - smallDelta,
2660 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2661 {txEndSignal1 + smallDelta,
2662 WifiPhyState::IDLE} // IDLE just after the transmission ends
2663 },
2664 {{txEndSignal1 - smallDelta,
2665 1,
2666 tx1Start,
2667 txEndSignal1,
2670 delay += testStep;
2672
2673 //----------------------------------------------------------------------------------------------------------------------------------
2674 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a
2675 // signal below the energy detection threshold occupies the S80
2676 ScheduleTest(delay,
2677 "Reception of a 80 MHz signal that occupies S80 below ED threshold",
2678 {{dBm_u{-65}, tx1Start, txDuration1, S80_CENTER_FREQUENCY, MHz_u{80}}},
2679 {},
2680 {
2681 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2682 {txEndSignal1 - smallDelta,
2683 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2684 {txEndSignal1 + smallDelta,
2685 WifiPhyState::IDLE} // IDLE just after the transmission ends
2686 },
2687 {});
2688 delay += testStep;
2689
2690 //----------------------------------------------------------------------------------------------------------------------------------
2691 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal
2692 // above the energy detection threshold occupies the S80 27.3.20.6.4: Any
2693 // signal within the secondary 80 MHz channel at or above –56 dBm.
2694 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 4, 4, txDuration1);
2695 ScheduleTest(delay,
2696 "Reception of a 80 MHz signal that occupies S80 above ED threshold",
2697 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY, MHz_u{80}}},
2698 {},
2699 {
2700 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2701 {txEndSignal1 - smallDelta,
2702 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2703 {txEndSignal1 + smallDelta,
2704 WifiPhyState::IDLE} // IDLE just after the transmission ends
2705 },
2706 {{txEndSignal1 - smallDelta,
2707 1,
2708 tx1Start,
2709 txEndSignal1,
2712 delay += testStep;
2714
2715 //----------------------------------------------------------------------------------------------------------------------------------
2716 // Verify PHY state stays IDLE as long as a 160 MHz signal below the energy
2717 // detection threshold occupies the whole band
2718 ScheduleTest(delay,
2719 "Reception of a 160 MHz signal that occupies the whole band below ED "
2720 "threshold",
2721 {{dBm_u{-55}, tx1Start, txDuration1, P160_CENTER_FREQUENCY, MHz_u{160}}},
2722 {},
2723 {
2724 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2725 {txEndSignal1 - smallDelta,
2726 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2727 {txEndSignal1 + smallDelta,
2728 WifiPhyState::IDLE} // IDLE just after the transmission ends
2729 },
2730 {});
2731
2732 delay += testStep;
2733
2734 //----------------------------------------------------------------------------------------------------------------------------------
2735 // Verify PHY state is CCA-BUSY as long as a 160 MHz signal above the energy
2736 // detection threshold occupies the whole band
2737 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 8, txDuration1);
2739 delay,
2740 "Reception of a 160 MHz signal that occupies the whole band above ED "
2741 "threshold",
2742 {{dBm_u{-50}, tx1Start, txDuration1, P160_CENTER_FREQUENCY, MHz_u{160}}},
2743 {},
2744 {
2745 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
2746 {txEndSignal1 - smallDelta,
2747 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2748 {txEndSignal1 + smallDelta,
2749 WifiPhyState::IDLE} // IDLE just after the transmission ends
2750 },
2751 {{txEndSignal1 - smallDelta,
2752 1,
2753 tx1Start,
2754 txEndSignal1,
2757 delay += testStep;
2759
2760 //----------------------------------------------------------------------------------------------------------------------------------
2761 // Verify PHY notifies CCA-BUSY for the P20 channel while the S80 channel was
2762 // already in CCA-BUSY state
2763 m_expectedPer20MhzCcaBusyDurations.at(0).at(6) = txDuration1;
2764 m_expectedPer20MhzCcaBusyDurations.at(1).at(0) = txDuration2;
2765 m_expectedPer20MhzCcaBusyDurations.at(1).at(6) = txDiff;
2767 delay,
2768 "Reception of a 20 MHz signal that occupies S80 followed by the reception "
2769 "of another "
2770 "20 MHz signal that occupies P20",
2771 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY + MHz_u{10}, MHz_u{20}},
2772 {dBm_u{-55}, tx2Start, txDuration2, P20_CENTER_FREQUENCY, MHz_u{20}}},
2773 {},
2774 {
2775 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // state of primary stays idle
2776 // after aCcaTimeWithDelta
2777 {tx2Start + aCcaTimeWithDelta,
2778 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
2779 // aCcaTimeWithDelta that followed the second
2780 // transmission
2781 {txEndSignal2 - smallDelta,
2782 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
2783 {txEndSignal2 + smallDelta,
2784 WifiPhyState::IDLE} // IDLE just after the transmission ends
2785 },
2786 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2787 1,
2788 tx1Start,
2789 txEndSignal1,
2792 {tx2Start + aCcaTimeWithDelta, // notification upon reception of
2793 // the second signal
2794 2,
2795 tx1Start,
2796 txEndSignal2,
2799 delay += testStep;
2801
2802 //----------------------------------------------------------------------------------------------------------------------------------
2803 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S40 channel while
2804 // the S80 channel was already in CCA-BUSY state
2805 m_expectedPer20MhzCcaBusyDurations.at(0).at(7) = txDuration1;
2806 m_expectedPer20MhzCcaBusyDurations.at(1).at(2) = txDuration2;
2807 m_expectedPer20MhzCcaBusyDurations.at(1).at(7) = txDiff;
2809 delay,
2810 "Reception of a signal that occupies S80 followed by the reception of "
2811 "another signal "
2812 "that occupies S40",
2813 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY + MHz_u{30}, MHz_u{20}},
2814 {dBm_u{-55}, tx2Start, txDuration2, S40_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}}},
2815 {},
2816 {
2817 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // state of primary stays idle
2818 // after aCcaTimeWithDelta
2819 {tx2Start + aCcaTimeWithDelta, WifiPhyState::IDLE}, // state of primary stays IDLE
2820 {txEndSignal2 - smallDelta,
2821 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2822 {txEndSignal2 + smallDelta,
2823 WifiPhyState::IDLE} // IDLE just after the transmission ends
2824 },
2825 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2826 1,
2827 tx1Start,
2828 txEndSignal1,
2831 {tx2Start + aCcaTimeWithDelta, // notification upon reception of
2832 // the second signal
2833 2,
2834 tx1Start,
2835 txEndSignal2,
2838 delay += testStep;
2840
2841 //----------------------------------------------------------------------------------------------------------------------------------
2842 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while
2843 // the S80 channel was already in CCA-BUSY state
2844 m_expectedPer20MhzCcaBusyDurations.at(0).at(4) = txDuration1;
2845 m_expectedPer20MhzCcaBusyDurations.at(1).at(1) = txDuration2;
2846 m_expectedPer20MhzCcaBusyDurations.at(1).at(4) = txDiff;
2848 delay,
2849 "Reception of a signal that occupies S80 followed by the reception of "
2850 "another signal "
2851 "that occupies S20",
2852 {{dBm_u{-55}, tx1Start, txDuration1, S80_CENTER_FREQUENCY - MHz_u{30}, MHz_u{20}},
2853 {dBm_u{-55}, tx2Start, txDuration2, S20_CENTER_FREQUENCY, MHz_u{20}}},
2854 {},
2855 {
2856 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // state of primary stays idle
2857 // after aCcaTimeWithDelta
2858 {tx2Start + aCcaTimeWithDelta, WifiPhyState::IDLE}, // state of primary stays IDLE
2859 {txEndSignal2 - smallDelta,
2860 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2861 {txEndSignal2 + smallDelta,
2862 WifiPhyState::IDLE} // IDLE just after the transmission ends
2863 },
2864 {{aCcaTimeWithDelta, // notification upon reception of the first signal
2865 1,
2866 tx1Start,
2867 txEndSignal1,
2870 {tx2Start + aCcaTimeWithDelta, // notification upon reception of
2871 // the second signal
2872 2,
2873 tx1Start,
2874 txEndSignal2,
2877 delay += testStep;
2879
2880 //----------------------------------------------------------------------------------------------------------------------------------
2881 // Verify PHY state stays IDLE when a 80 MHz PPDU with received power below the
2882 // CCA sensitivity threshold occupies S80
2883 ScheduleTest(delay,
2884 "Reception of a 80 MHz PPDU that occupies S80 below CCA sensitivity "
2885 "threshold",
2886 {},
2887 {{dBm_u{-70}, tx1Start, S80_CENTER_FREQUENCY, MHz_u{80}}},
2888 {
2889 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2890 {ppduDurations.at(MHz_u{80}) - smallDelta,
2891 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2892 {ppduDurations.at(MHz_u{80}) + smallDelta,
2893 WifiPhyState::IDLE} // IDLE just after the transmission ends
2894 },
2895 {});
2896 delay += testStep;
2897
2898 //----------------------------------------------------------------------------------------------------------------------------------
2899 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 80
2900 // MHz PPDU with received power above the CCA sensitivity threshold occupies
2901 // S80
2902 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 4,
2903 4,
2904 ppduDurations.at(MHz_u{80}));
2905 ScheduleTest(delay,
2906 "Reception of a 80 MHz PPDU that occupies S80 above CCA sensitivity "
2907 "threshold",
2908 {},
2909 {{dBm_u{-65}, tx1Start, S80_CENTER_FREQUENCY, MHz_u{80}}},
2910 {
2911 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2912 {ppduDurations.at(MHz_u{80}) - smallDelta,
2913 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2914 {ppduDurations.at(MHz_u{80}) + smallDelta,
2915 WifiPhyState::IDLE} // IDLE just after the transmission ends
2916 },
2918 1,
2919 tx1Start,
2920 ppduDurations.at(MHz_u{80}),
2923 delay += testStep;
2925
2927 {
2928 //----------------------------------------------------------------------------------------------------------------------------------
2929 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if only
2930 // the per20bitmap parameter changes
2931 m_expectedPer20MhzCcaBusyDurations.at(0).at(7) = txDuration1;
2933 delay,
2934 "Reception of a 20 MHz signal that generates a per20bitmap parameter "
2935 "change when previous CCA indication reports IDLE",
2936 {{dBm_u{-60}, tx1Start, txDuration1, S80_CENTER_FREQUENCY + MHz_u{30}, MHz_u{20}}},
2937 {},
2938 {
2939 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
2940 {txEndSignal1 - smallDelta,
2941 WifiPhyState::IDLE}, // IDLE just before the transmission ends
2942 {txEndSignal1 + smallDelta,
2943 WifiPhyState::IDLE} // IDLE just after the transmission ends
2944 },
2946 1,
2947 tx1Start,
2948 tx1Start,
2951 delay += testStep;
2953
2954 //----------------------------------------------------------------------------------------------------------------------------------
2955 // Verify PHY state stays CCA_BUSY and CCA-BUSY indication is reported if
2956 // only the per20bitmap parameter changes
2957 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 4, txDuration1);
2958 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(1).begin(), 4, txDiff);
2959 m_expectedPer20MhzCcaBusyDurations.at(1).at(7) = txDuration2;
2961 delay,
2962 "Reception of a 20 MHz signal that generates a per20bitmap parameter "
2963 "change when "
2964 "previous CCA indication reports BUSY for the primary channel",
2965 {{dBm_u{-50}, tx1Start, txDuration1, P80_CENTER_FREQUENCY, MHz_u{80}},
2966 {dBm_u{-60}, tx2Start, txDuration2, S80_CENTER_FREQUENCY + MHz_u{30}, MHz_u{20}}},
2967 {},
2968 {
2969 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
2970 {txEndSignal1 - smallDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the
2971 // transmission ends
2972 {txEndSignal1 + smallDelta,
2973 WifiPhyState::IDLE} // IDLE just after the transmission ends
2974 },
2976 1,
2977 tx1Start,
2978 txEndSignal1,
2981 {tx2Start + aCcaTimeWithDelta, // notification upon reception
2982 // of the second signal
2983 2,
2984 tx1Start,
2985 txEndSignal1,
2988 delay += testStep;
2990 }
2991 }
2992
2993 if (m_channelWidth > 160)
2994 {
2995 //----------------------------------------------------------------------------------------------------------------------------------
2996 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
2997 // energy detection threshold occupies the first 20 MHz subchannel of the S160
2999 delay,
3000 "Reception of a 20 MHz signal that occupies the first subchannel of S160 "
3001 "below ED threshold",
3002 {{dBm_u{-65}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{70}, MHz_u{20}}},
3003 {},
3004 {
3005 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3006 {txEndSignal1 - smallDelta,
3007 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3008 {txEndSignal1 + smallDelta,
3009 WifiPhyState::IDLE} // IDLE just after the transmission ends
3010 },
3011 {});
3012 delay += testStep;
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 threshold
3018 // of –62 dBm. (...)
3019 m_expectedPer20MhzCcaBusyDurations.at(0).at(8) = txDuration1;
3021 delay,
3022 "Reception of a 20 MHz signal that occupies the first subchannel of S160 "
3023 "above ED threshold",
3024 {{dBm_u{-61}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{70}, MHz_u{20}}},
3025 {},
3026 {
3027 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3028 {txEndSignal1 - smallDelta,
3029 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3030 {txEndSignal1 + smallDelta,
3031 WifiPhyState::IDLE} // IDLE just after the transmission ends
3032 },
3033 {{txEndSignal1 - smallDelta,
3034 1,
3035 tx1Start,
3036 txEndSignal1,
3039 delay += testStep;
3041
3042 //----------------------------------------------------------------------------------------------------------------------------------
3043 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
3044 // energy detection threshold occupies the second 20 MHz subchannel of the S80
3046 delay,
3047 "Reception of a 20 MHz signal that occupies the second subchannel of S160 "
3048 "below ED threshold",
3049 {{dBm_u{-65}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{50}, MHz_u{20}}},
3050 {},
3051 {
3052 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3053 {txEndSignal1 - smallDelta,
3054 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3055 {txEndSignal1 + smallDelta,
3056 WifiPhyState::IDLE} // IDLE just after the transmission ends
3057 },
3058 {});
3059 delay += testStep;
3060
3061 //----------------------------------------------------------------------------------------------------------------------------------
3062 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3063 // energy detection threshold occupies the second 20 MHz subchannel of the S160 27.3.20.6.4:
3064 // 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at or above a threshold
3065 // of –62 dBm. (...)
3066 m_expectedPer20MhzCcaBusyDurations.at(0).at(9) = txDuration1;
3068 delay,
3069 "Reception of a 20 MHz signal that occupies the second subchannel of S160 "
3070 "above ED threshold",
3071 {{dBm_u{-61}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{50}, MHz_u{20}}},
3072 {},
3073 {
3074 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3075 {txEndSignal1 - smallDelta,
3076 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3077 {txEndSignal1 + smallDelta,
3078 WifiPhyState::IDLE} // IDLE just after the transmission ends
3079 },
3080 {{txEndSignal1 - smallDelta,
3081 1,
3082 tx1Start,
3083 txEndSignal1,
3086 delay += testStep;
3088
3089 //----------------------------------------------------------------------------------------------------------------------------------
3090 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
3091 // energy detection threshold occupies the third 20 MHz subchannel of the S80
3093 delay,
3094 "Reception of a 20 MHz signal that occupies the third subchannel of S160 "
3095 "below ED threshold",
3096 {{dBm_u{-65}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{30}, MHz_u{20}}},
3097 {},
3098 {
3099 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3100 {txEndSignal1 - smallDelta,
3101 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3102 {txEndSignal1 + smallDelta,
3103 WifiPhyState::IDLE} // IDLE just after the transmission ends
3104 },
3105 {});
3106 delay += testStep;
3107
3108 //----------------------------------------------------------------------------------------------------------------------------------
3109 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3110 // energy detection threshold occupies the third 20 MHz subchannel of the S160 27.3.20.6.4:
3111 // 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at or above a threshold
3112 // of –62 dBm. (...)
3113 m_expectedPer20MhzCcaBusyDurations.at(0).at(10) = txDuration1;
3115 delay,
3116 "Reception of a 20 MHz signal that occupies the third subchannel of S160 "
3117 "above ED threshold",
3118 {{dBm_u{-61}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{30}, MHz_u{20}}},
3119 {},
3120 {
3121 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3122 {txEndSignal1 - smallDelta,
3123 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3124 {txEndSignal1 + smallDelta,
3125 WifiPhyState::IDLE} // IDLE just after the transmission ends
3126 },
3127 {{txEndSignal1 - smallDelta,
3128 1,
3129 tx1Start,
3130 txEndSignal1,
3133 delay += testStep;
3135
3136 //----------------------------------------------------------------------------------------------------------------------------------
3137 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal below the
3138 // energy detection threshold occupies the fourth 20 MHz subchannel of the S80
3140 delay,
3141 "Reception of a 20 MHz signal that occupies the fourth subchannel of S160 "
3142 "below ED threshold",
3143 {{dBm_u{-65}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}}},
3144 {},
3145 {
3146 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3147 {txEndSignal1 - smallDelta,
3148 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3149 {txEndSignal1 + smallDelta,
3150 WifiPhyState::IDLE} // IDLE just after the transmission ends
3151 },
3152 {});
3153 delay += testStep;
3154
3155 //----------------------------------------------------------------------------------------------------------------------------------
3156 // Verify PHY state stays IDLE and CCA-BUSY indication is reported if a signal above the
3157 // energy detection threshold occupies the fourth 20 MHz subchannel of the S160 27.3.20.6.4:
3158 // 36.3.21.6.4: (...) A signal is present on the 20 MHz subchannel at or above a threshold
3159 // of –62 dBm. (...)
3160 m_expectedPer20MhzCcaBusyDurations.at(0).at(11) = txDuration1;
3162 delay,
3163 "Reception of a 20 MHz signal that occupies the fourth subchannel of S160 "
3164 "above ED threshold",
3165 {{dBm_u{-61}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}}},
3166 {},
3167 {
3168 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3169 {txEndSignal1 - smallDelta,
3170 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3171 {txEndSignal1 + smallDelta,
3172 WifiPhyState::IDLE} // IDLE just after the transmission ends
3173 },
3174 {{txEndSignal1 - smallDelta,
3175 1,
3176 tx1Start,
3177 txEndSignal1,
3180 delay += testStep;
3182
3183 //----------------------------------------------------------------------------------------------------------------------------------
3184 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal occupies
3185 // the fifth and sixth 20 MHz subchannels of the S160 with received power below the energy
3186 // detection threshold for all occupied 20 MHz subchannels
3188 delay,
3189 "Reception of a 40 MHz signal that occupies the fifth and sixth subchannels "
3190 "of S160 below ED threshold",
3191 {{dBm_u{-60}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{20}, MHz_u{40}}},
3192 {},
3193 {
3194 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3195 {txEndSignal1 - smallDelta,
3196 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3197 {txEndSignal1 + smallDelta,
3198 WifiPhyState::IDLE} // IDLE just after the transmission ends
3199 },
3200 {});
3201 delay += testStep;
3202
3203 //----------------------------------------------------------------------------------------------------------------------------------
3204 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal occupies
3205 // the fifth and sixth 20 MHz subchannels of the S160 with received power above the energy
3206 // detection threshold for any occupied 20 MHz subchannels
3207 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 12, 2, txDuration1);
3209 delay,
3210 "Reception of a 40 MHz signal that occupies the fifth and sixth subchannels "
3211 "of S160 above ED threshold",
3212 {{dBm_u{-58}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{20}, MHz_u{40}}},
3213 {},
3214 {
3215 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3216 {txEndSignal1 - smallDelta,
3217 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3218 {txEndSignal1 + smallDelta,
3219 WifiPhyState::IDLE} // IDLE just after the transmission ends
3220 },
3221 {{txEndSignal1 - smallDelta,
3222 1,
3223 tx1Start,
3224 txEndSignal1,
3227 delay += testStep;
3229
3230 //----------------------------------------------------------------------------------------------------------------------------------
3231 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal occupies
3232 // the seventh and eighth 20 MHz subchannels of the S160 with received power below the
3233 // energy detection threshold for all occupied 20 MHz subchannels
3235 delay,
3236 "Reception of a 40 MHz signal that occupies the seventh and eighth "
3237 "subchannels of S160 below ED threshold",
3238 {{dBm_u{-60}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{60}, MHz_u{40}}},
3239 {},
3240 {
3241 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3242 {txEndSignal1 - smallDelta,
3243 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3244 {txEndSignal1 + smallDelta,
3245 WifiPhyState::IDLE} // IDLE just after the transmission ends
3246 },
3247 {});
3248 delay += testStep;
3249
3250 //----------------------------------------------------------------------------------------------------------------------------------
3251 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal occupies
3252 // the seventh and eighth 20 MHz subchannels of the S160 with received power above the
3253 // energy detection threshold for any occupied 20 MHz subchannels
3254 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 14, 2, txDuration1);
3256 delay,
3257 "Reception of a 40 MHz signal that occupies the seventh and eighth "
3258 "subchannels of S160 above ED threshold",
3259 {{dBm_u{-58}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{60}, MHz_u{40}}},
3260 {},
3261 {
3262 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3263 {txEndSignal1 - smallDelta,
3264 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3265 {txEndSignal1 + smallDelta,
3266 WifiPhyState::IDLE} // IDLE just after the transmission ends
3267 },
3268 {{txEndSignal1 - smallDelta,
3269 1,
3270 tx1Start,
3271 txEndSignal1,
3274 delay += testStep;
3276
3277 //----------------------------------------------------------------------------------------------------------------------------------
3278 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3279 // occupies the first four 20 MHz subchannels of the S160 with received power below the
3280 // energy detection threshold for all occupied 20 MHz subchannels
3282 delay,
3283 "Reception of a 80 MHz signal that occupies the first four subchannels of "
3284 "S160 below ED threshold",
3285 {{dBm_u{-57}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{40}, MHz_u{80}}},
3286 {},
3287 {
3288 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3289 {txEndSignal1 - smallDelta,
3290 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3291 {txEndSignal1 + smallDelta,
3292 WifiPhyState::IDLE} // IDLE just after the transmission ends
3293 },
3294 {});
3295 delay += testStep;
3296
3297 //----------------------------------------------------------------------------------------------------------------------------------
3298 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3299 // occupies the first four 20 MHz subchannels of the S160 with received power above the
3300 // energy detection threshold for any occupied 20 MHz subchannels
3301 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 8, 4, txDuration1);
3303 delay,
3304 "Reception of a 80 MHz signal that occupies the first four subchannels of "
3305 "S160 above ED threshold",
3306 {{dBm_u{-55}, tx1Start, txDuration1, S160_CENTER_FREQUENCY - MHz_u{40}, MHz_u{80}}},
3307 {},
3308 {
3309 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3310 {txEndSignal1 - smallDelta,
3311 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3312 {txEndSignal1 + smallDelta,
3313 WifiPhyState::IDLE} // IDLE just after the transmission ends
3314 },
3315 {{txEndSignal1 - smallDelta,
3316 1,
3317 tx1Start,
3318 txEndSignal1,
3321 delay += testStep;
3323
3324 //----------------------------------------------------------------------------------------------------------------------------------
3325 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3326 // occupies the last four 20 MHz subchannels of the S160 with received power below the
3327 // energy detection threshold for all occupied 20 MHz subchannels
3329 delay,
3330 "Reception of a 80 MHz signal that occupies the last four subchannels of S160 "
3331 "below ED threshold",
3332 {{dBm_u{-57}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{40}, MHz_u{80}}},
3333 {},
3334 {
3335 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3336 {txEndSignal1 - smallDelta,
3337 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3338 {txEndSignal1 + smallDelta,
3339 WifiPhyState::IDLE} // IDLE just after the transmission ends
3340 },
3341 {});
3342 delay += testStep;
3343
3344 //----------------------------------------------------------------------------------------------------------------------------------
3345 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal
3346 // occupies the last four 20 MHz subchannels of the S160 with received power above the
3347 // energy detection threshold for any occupied 20 MHz subchannels
3348 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 12, 4, txDuration1);
3350 delay,
3351 "Reception of a 80 MHz signal that occupies the last four subchannels of S160 "
3352 "above ED threshold",
3353 {{dBm_u{-55}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{40}, MHz_u{80}}},
3354 {},
3355 {
3356 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3357 {txEndSignal1 - smallDelta,
3358 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3359 {txEndSignal1 + smallDelta,
3360 WifiPhyState::IDLE} // IDLE just after the transmission ends
3361 },
3362 {{txEndSignal1 - smallDelta,
3363 1,
3364 tx1Start,
3365 txEndSignal1,
3368 delay += testStep;
3370
3371 //----------------------------------------------------------------------------------------------------------------------------------
3372 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal occupies
3373 // the whole S160 with received power below the energy detection threshold for all occupied
3374 // 20 MHz subchannels
3376 delay,
3377 "Reception of a 160 MHz signal that occupies the whole S160 below ED threshold",
3378 {{dBm_u{-54}, tx1Start, txDuration1, S160_CENTER_FREQUENCY, MHz_u{160}}},
3379 {},
3380 {
3381 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3382 {txEndSignal1 - smallDelta,
3383 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3384 {txEndSignal1 + smallDelta,
3385 WifiPhyState::IDLE} // IDLE just after the transmission ends
3386 },
3387 {});
3388 delay += testStep;
3389
3390 //----------------------------------------------------------------------------------------------------------------------------------
3391 // Verify PHY state stays IDLE and no CCA-BUSY indication is reported if a signal occupies
3392 // the whole S160 with received power above the energy detection threshold for any occupied
3393 // 20 MHz subchannels
3394 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 8, 8, txDuration1);
3396 delay,
3397 "Reception of a 160 MHz signal that occupies the whole S160 above ED threshold",
3398 {{dBm_u{-52}, tx1Start, txDuration1, S160_CENTER_FREQUENCY, MHz_u{160}}},
3399 {},
3400 {
3401 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3402 {txEndSignal1 - smallDelta,
3403 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3404 {txEndSignal1 + smallDelta,
3405 WifiPhyState::IDLE} // IDLE just after the transmission ends
3406 },
3407 {{txEndSignal1 - smallDelta,
3408 1,
3409 tx1Start,
3410 txEndSignal1,
3413 delay += testStep;
3415
3416 //----------------------------------------------------------------------------------------------------------------------------------
3417 // Verify PHY state stays IDLE as long as a 320 MHz signal below the energy detection
3418 // threshold occupies the whole band
3420 delay,
3421 "Reception of a 320 MHz signal that occupies the whole band below ED threshold",
3422 {{dBm_u{-51}, tx1Start, txDuration1, P320_CENTER_FREQUENCY, MHz_u{320}}},
3423 {},
3424 {
3425 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3426 {txEndSignal1 - smallDelta,
3427 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3428 {txEndSignal1 + smallDelta,
3429 WifiPhyState::IDLE} // IDLE just after the transmission ends
3430 },
3431 {});
3432 delay += testStep;
3433
3434 //----------------------------------------------------------------------------------------------------------------------------------
3435 // Verify PHY state is CCA-BUSY as long as a 320 MHz signal above the energy detection
3436 // threshold occupies the whole band
3437 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin(), 16, txDuration1);
3439 delay,
3440 "Reception of a 320 MHz signal that occupies the whole band above ED threshold",
3441 {{dBm_u{-49}, tx1Start, txDuration1, P320_CENTER_FREQUENCY, MHz_u{320}}},
3442 {},
3443 {
3444 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
3445 {txEndSignal1 - smallDelta,
3446 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
3447 {txEndSignal1 + smallDelta,
3448 WifiPhyState::IDLE} // IDLE just after the transmission ends
3449 },
3450 {{txEndSignal1 - smallDelta,
3451 1,
3452 tx1Start,
3453 txEndSignal1,
3456 delay += testStep;
3458
3459 //----------------------------------------------------------------------------------------------------------------------------------
3460 // Verify PHY notifies CCA-BUSY for the P20 channel while the S160 channel was already
3461 // in CCA-BUSY state
3462 m_expectedPer20MhzCcaBusyDurations.at(0).at(15) = txDuration1;
3463 m_expectedPer20MhzCcaBusyDurations.at(1).at(0) = txDuration2;
3464 m_expectedPer20MhzCcaBusyDurations.at(1).at(15) = txDiff;
3466 delay,
3467 "Reception of a 20 MHz signal that occupies S160 followed by the reception of another "
3468 "20 MHz signal that occupies P20",
3469 {{dBm_u{-52}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{70}, MHz_u{20}},
3470 {dBm_u{-52}, tx2Start, txDuration2, P20_CENTER_FREQUENCY, MHz_u{20}}},
3471 {},
3472 {
3474 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3475 {tx2Start + aCcaTimeWithDelta,
3476 WifiPhyState::CCA_BUSY}, // state of primary is CCA-BUSY after
3477 // aCcaTimeWithDelta that followed the second
3478 // transmission
3479 {txEndSignal2 - smallDelta,
3480 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
3481 {txEndSignal2 + smallDelta,
3482 WifiPhyState::IDLE} // IDLE just after the transmission ends
3483 },
3484 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3485 1,
3486 tx1Start,
3487 txEndSignal1,
3490 {tx2Start + aCcaTimeWithDelta, // notification upon reception of the second signal
3491 2,
3492 tx1Start,
3493 txEndSignal2,
3496 delay += testStep;
3498
3499 //----------------------------------------------------------------------------------------------------------------------------------
3500 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S80 channel while the S160
3501 // channel was already in CCA-BUSY state
3502 m_expectedPer20MhzCcaBusyDurations.at(0).at(14) = txDuration1;
3503 m_expectedPer20MhzCcaBusyDurations.at(1).at(5) = txDuration2;
3504 m_expectedPer20MhzCcaBusyDurations.at(1).at(14) = txDiff;
3506 delay,
3507 "Reception of a signal that occupies S160 followed by the reception of another signal "
3508 "that occupies S80",
3509 {{dBm_u{-52}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{50}, MHz_u{20}},
3510 {dBm_u{-52}, tx2Start, txDuration2, S80_CENTER_FREQUENCY - MHz_u{10}, MHz_u{20}}},
3511 {},
3512 {
3514 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3515 {tx2Start + aCcaTimeWithDelta, WifiPhyState::IDLE}, // state of primary stays IDLE
3516 {txEndSignal2 - smallDelta,
3517 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3518 {txEndSignal2 + smallDelta,
3519 WifiPhyState::IDLE} // IDLE just after the transmission ends
3520 },
3521 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3522 1,
3523 tx1Start,
3524 txEndSignal1,
3527 {tx2Start + aCcaTimeWithDelta, // notification upon reception of the second signal
3528 2,
3529 tx1Start,
3530 txEndSignal2,
3533 delay += testStep;
3535
3536 //----------------------------------------------------------------------------------------------------------------------------------
3537 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S40 channel while the S160
3538 // channel was already in CCA-BUSY state
3539 m_expectedPer20MhzCcaBusyDurations.at(0).at(13) = txDuration1;
3540 m_expectedPer20MhzCcaBusyDurations.at(1).at(3) = txDuration2;
3541 m_expectedPer20MhzCcaBusyDurations.at(1).at(13) = txDiff;
3543 delay,
3544 "Reception of a signal that occupies S160 followed by the reception of another signal "
3545 "that occupies S40",
3546 {{dBm_u{-52}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{30}, MHz_u{20}},
3547 {dBm_u{-52}, tx2Start, txDuration2, S40_CENTER_FREQUENCY + MHz_u{10}, MHz_u{20}}},
3548 {},
3549 {
3551 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3552 {tx2Start + aCcaTimeWithDelta, WifiPhyState::IDLE}, // state of primary stays IDLE
3553 {txEndSignal2 - smallDelta,
3554 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3555 {txEndSignal2 + smallDelta,
3556 WifiPhyState::IDLE} // IDLE just after the transmission ends
3557 },
3558 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3559 1,
3560 tx1Start,
3561 txEndSignal1,
3564 {tx2Start + aCcaTimeWithDelta, // notification upon reception of the second signal
3565 2,
3566 tx1Start,
3567 txEndSignal2,
3570 delay += testStep;
3572
3573 //----------------------------------------------------------------------------------------------------------------------------------
3574 // Verify PHY state stays IDLE but notifies CCA-BUSY for the S20 channel while the S160
3575 // channel was already in CCA-BUSY state
3576 m_expectedPer20MhzCcaBusyDurations.at(0).at(12) = txDuration1;
3577 m_expectedPer20MhzCcaBusyDurations.at(1).at(1) = txDuration2;
3578 m_expectedPer20MhzCcaBusyDurations.at(1).at(12) = txDiff;
3580 delay,
3581 "Reception of a signal that occupies S160 followed by the reception of another signal "
3582 "that occupies S20",
3583 {{dBm_u{-52}, tx1Start, txDuration1, S160_CENTER_FREQUENCY + MHz_u{10}, MHz_u{20}},
3584 {dBm_u{-52}, tx2Start, txDuration2, S20_CENTER_FREQUENCY, MHz_u{20}}},
3585 {},
3586 {
3588 WifiPhyState::IDLE}, // state of primary stays idle after aCcaTimeWithDelta
3589 {tx2Start + aCcaTimeWithDelta, WifiPhyState::IDLE}, // state of primary stays IDLE
3590 {txEndSignal2 - smallDelta,
3591 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3592 {txEndSignal2 + smallDelta,
3593 WifiPhyState::IDLE} // IDLE just after the transmission ends
3594 },
3595 {{aCcaTimeWithDelta, // notification upon reception of the first signal
3596 1,
3597 tx1Start,
3598 txEndSignal1,
3601 {tx2Start + aCcaTimeWithDelta, // notification upon reception of the second signal
3602 2,
3603 tx1Start,
3604 txEndSignal2,
3607 delay += testStep;
3609
3610 //----------------------------------------------------------------------------------------------------------------------------------
3611 // Verify PHY state stays IDLE when a 160 MHz PPDU that occupies S160 with received
3612 // power below the Per 20 MHz CCA threshold for all occupied 20 MHz subchannels
3614 delay,
3615 "Reception of a 160 MHz PPDU that occupies S160 below CCA sensitivity threshold",
3616 {},
3617 {{dBm_u{-64}, tx1Start, S160_CENTER_FREQUENCY, MHz_u{160}}},
3618 {
3619 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3620 {ppduDurations.at(MHz_u{160}) - smallDelta,
3621 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3622 {ppduDurations.at(MHz_u{160}) + smallDelta,
3623 WifiPhyState::IDLE} // IDLE just after the transmission ends
3624 },
3625 {});
3626 delay += testStep;
3627
3628 //----------------------------------------------------------------------------------------------------------------------------------
3629 // Verify PHY state stays IDLE but CCA-BUSY indication is reported when a 160 MHz PPDU
3630 // that occupies S160 with received power above the Per 20 MHz CCA threshold for any
3631 // occupied 20 MHz subchannels
3632 std::fill_n(m_expectedPer20MhzCcaBusyDurations.at(0).begin() + 8,
3633 8,
3634 ppduDurations.at(MHz_u{160}));
3636 delay,
3637 "Reception of a 160 MHz PPDU that occupies S160 above CCA sensitivity threshold",
3638 {},
3639 {{dBm_u{-62}, tx1Start, S160_CENTER_FREQUENCY, MHz_u{160}}},
3640 {
3641 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3642 {ppduDurations.at(MHz_u{160}) - smallDelta,
3643 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3644 {ppduDurations.at(MHz_u{160}) + smallDelta,
3645 WifiPhyState::IDLE} // IDLE just after the transmission ends
3646 },
3648 1,
3649 tx1Start,
3650 ppduDurations.at(MHz_u{160}),
3653 delay += testStep;
3655 }
3656
3657 if (m_channelWidth > MHz_u{20})
3658 {
3659 m_expectedPer20MhzCcaBusyDurations.at(0).at(0) = txDuration1;
3661 }
3662
3664 delay,
3665 "Reception of signal above ED threshold that triggers CCA BUSY indication followed by CCA "
3666 "IDLE indication when the threshold is increased",
3667 {{dBm_u{-60}, tx1Start, txDuration1, P20_CENTER_FREQUENCY, MHz_u{20}}},
3668 {},
3669 {
3670 {aCcaTimeWithDelta, WifiPhyState::CCA_BUSY}, // CCA-BUSY after aCcaTimeWithDelta
3671 {thresholdUpdateTime - smallDelta,
3672 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the threshold changes
3673 {thresholdUpdateTime + smallDelta,
3674 WifiPhyState::IDLE}, // IDLE just after the threshold changes
3675 {txEndSignal1 - smallDelta,
3676 WifiPhyState::IDLE}, // IDLE just before the transmission ends
3677 {txEndSignal1 + smallDelta, WifiPhyState::IDLE} // IDLE just after the transmission ends
3678 },
3679 {{thresholdUpdateTime - smallDelta,
3680 1, // first notification CCA busy until end of transmission
3681 tx1Start,
3682 txEndSignal1,
3685 {txEndSignal1 - smallDelta,
3686 2, // second notification CCA busy ends when threshold changed
3687 tx1Start,
3688 thresholdUpdateTime,
3691 {
3692 {.timePoint = thresholdUpdateTime,
3693 .ccaThreshold =
3694 dBm_u{-50}}, // change CCA threshold during the reception to a higher value
3695 });
3696 delay += testStep;
3698
3699 if (m_channelWidth > MHz_u{20})
3700 {
3701 m_expectedPer20MhzCcaBusyDurations.at(0).at(0) = txDuration1 - thresholdUpdateTime;
3702 }
3703
3705 delay,
3706 "Reception of signal below ED threshold that triggers CCA IDLE indication followed by CCA "
3707 "BUSY indication when the threshold is decreased",
3708 {{dBm_u{-65}, tx1Start, txDuration1, P20_CENTER_FREQUENCY, MHz_u{20}}},
3709 {},
3710 {
3711 {aCcaTimeWithDelta, WifiPhyState::IDLE}, // IDLE after aCcaTimeWithDelta
3712 {thresholdUpdateTime - smallDelta,
3713 WifiPhyState::IDLE}, // IDLE just before the threshold changes
3714 {thresholdUpdateTime + smallDelta,
3715 WifiPhyState::CCA_BUSY}, // CCA-BUSY just after the threshold changes
3716 {txEndSignal1 - smallDelta,
3717 WifiPhyState::CCA_BUSY}, // CCA-BUSY just before the transmission ends
3718 {txEndSignal1 + smallDelta, WifiPhyState::IDLE} // IDLE just after the transmission ends
3719 },
3720 {
3721 {txEndSignal1 - smallDelta,
3722 1, // first notification CCA busy until end of transmission since threshold changed
3723 thresholdUpdateTime,
3724 txEndSignal1,
3727 },
3728 {
3729 {.timePoint = thresholdUpdateTime,
3730 .ccaThreshold =
3731 dBm_u{-70}}, // change CCA threshold during the reception to a higher value
3732 });
3733 delay += testStep;
3735
3737}
3738
3739void
3767
3768void
3770{
3771 m_rxPhy->Dispose();
3772 m_rxPhy = nullptr;
3773 m_uxPhy->Dispose();
3774 m_uxPhy = nullptr;
3775 for (auto& signalGenerator : m_signalGenerators)
3776 {
3777 signalGenerator->Dispose();
3778 signalGenerator = nullptr;
3779 }
3780}
3781
3782/**
3783 * @ingroup wifi-test
3784 * @ingroup tests
3785 *
3786 * @brief Wi-Fi PHY CCA Test Suite
3787 */
3789{
3790 public:
3792};
3793
3801
3802static WifiPhyCcaTestSuite WifiPhyCcaTestSuite; ///< the test suite
uint32_t v
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.
Time m_startCcaBusy
Start of the CCA-BUSY duration.
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
Test CCA_BUSY indication provided by the PHY.
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 CheckCcaBusyNotifications(const std::string &scenario, std::size_t expectedCcaNotifications, Time expectedStartTime, Time expectedEndTime, WifiChannelListType expectedChannelType, const std::vector< Time > &expectedPer20MhzDurations)
Check the CCA-BUSY notifications.
void LogScenario(const std::string &scenario) const
Log scenario description.
void SendSuPpdu(dBm_u txPower, MHz_u frequency, MHz_u bandwidth)
Send a HE or EHT SU PPDU.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
MHz_u m_frequency
Operating frequency.
void CheckPhyState(const std::string &scenario, WifiPhyState expectedState)
Check the PHY state.
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(const std::string &scenario, 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 DoCheckCcaBusyNotifications(const std::string &scenario, std::size_t expectedCcaNotifications, Time expectedStartTime, Time expectedEndTime, WifiChannelListType expectedChannelType, const std::vector< Time > &expectedPer20MhzDurations)
Check the CCA-BUSY notifications.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
Ptr< SpectrumWifiPhy > m_uxPhy
PHY object of the transmitter.
WifiPhyCcaIndicationTest(WifiStandard standard)
Constructor.
void ScheduleTest(Time delay, const std::string &scenario, const std::vector< TxSignalInfo > &generatedSignals, const std::vector< TxPpduInfo > &generatedPpdus, const std::vector< StateCheckPoint > &stateCheckpoints, const std::vector< CcaCheckPoint > &ccaCheckpoints, const std::vector< CcaThresholdUpdatePoint > &ccaThresholdUpdates={})
Schedule test to perform.
void DoRun() override
Implementation to actually run this TestCase.
void Reset()
Reset function.
Ptr< SpectrumWifiPhy > m_rxPhy
PHY object of the receiver.
void StopSignal(Ptr< WaveformGenerator > signalGenerator)
Stop to generate a signal.
void UpdateCcaThreshold(dBm_u ccaThreshold)
Update the CCA threshold of the PHY.
Wi-Fi PHY CCA Test Suite.
PHY CCA thresholds test.
Ptr< WifiNetDevice > m_device
The WifiNetDevice.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Ptr< SpectrumWifiPhy > m_phy
The spectrum PHY.
Ptr< ObssPdAlgorithm > m_obssPdAlgorithm
The OBSS-PD algorithm.
dBm_u m_obssPdLevel
The current OBSS-PD level.
void VerifyCcaThreshold(const std::shared_ptr< PhyEntity > phy, const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType, dBm_u expectedCcaThreshold)
Function to verify the CCA threshold that is being reported by a given PHY entity upon reception of a...
Ptr< EhtConfiguration > m_ehtConfiguration
The EHT configuration.
Ptr< WifiPsdu > CreateDummyPsdu()
Create a dummy PSDU whose payload is 1000 bytes.
VhtConfiguration::SecondaryCcaSensitivityThresholds m_secondaryCcaSensitivityThresholds
The current CCA sensitivity thresholds for signals that do not occupy the primary 20 MHz channel.
void RunOne()
Run tests for given CCA attributes.
Ptr< VhtConfiguration > m_vhtConfiguration
The VHT configuration.
void DoRun() override
Implementation to actually run this TestCase.
Ptr< EhtPpdu > CreateDummyEhtPpdu(MHz_u bandwidth, const WifiPhyOperatingChannel &channel)
Create a EHT PPDU.
dBm_u m_per20CcaSensitivity
The current CCA sensitivity threshold for Per 20MHz check.
Ptr< VhtPpdu > CreateDummyVhtPpdu(MHz_u bandwidth, const WifiPhyOperatingChannel &channel)
Create a VHT PPDU.
Ptr< HtPpdu > CreateDummyHtPpdu(MHz_u bandwidth, const WifiPhyOperatingChannel &channel)
Create a HT PPDU.
Ptr< OfdmPpdu > CreateDummyNonHtPpdu(const WifiPhyOperatingChannel &channel)
Create a non-HT PPDU.
dBm_u m_CcaEdThreshold
The current CCA-ED threshold for a 20 MHz subchannel.
dBm_u m_CcaSensitivity
The current CCA sensitivity threshold for signals that occupy the primary 20 MHz channel.
Ptr< HePpdu > CreateDummyHePpdu(MHz_u bandwidth, const WifiPhyOperatingChannel &channel)
Create a HE PPDU.
static WifiMode GetEhtMcs0()
Return MCS 0 from EHT MCS values.
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
@ PSD_NON_HE_PORTION
Non-HE portion of an HE PPDU.
Definition he-ppdu.h:105
static WifiMode GetHtMcs0()
Return MCS 0 from HT MCS values.
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6 Mbps.
AttributeValue implementation for Pointer.
Definition pointer.h:37
Ptr< T > Get() const
Definition pointer.h:224
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
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:580
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
static void Run()
Run the simulation.
Definition simulator.cc:161
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:614
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
@ QUICK
Fast test.
Definition test.h:1057
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
Type
Type of test.
Definition test.h:1271
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
bool IsPositive() const
Exactly equivalent to t >= 0.
Definition nstime.h:324
AttributeValue implementation for Time.
Definition nstime.h:1483
std::tuple< dBm_u, dBm_u, dBm_u > SecondaryCcaSensitivityThresholds
Tuple identifying CCA sensitivity thresholds for secondary channels.
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
Implements the IEEE 802.11 MAC header.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
WifiChannelConfig::SegmentWithoutUnits ChannelTuple
kept for backward compatibility, can be deprecated when using strong types
Definition wifi-phy.h:954
receive notifications about PHY events.
Class that keeps track of all information about the current PHY operating channel.
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=GetFrequencyChannels().begin())
Find the first frequency segment matching the specified parameters.
This objects implements the PHY state machine of the Wifi device.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#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:267
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:133
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition test.h:499
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1415
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1432
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211ax
@ WIFI_PREAMBLE_LONG
@ WIFI_PREAMBLE_EHT_MU
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PREAMBLE_VHT_SU
@ WIFI_PREAMBLE_HT_MF
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17).
@ WIFI_MOD_CLASS_HT
HT (Clause 19).
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36).
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22).
@ WIFI_MOD_CLASS_HE
HE (Clause 27).
@ WIFI_CHANLIST_PRIMARY
@ WIFI_CHANLIST_SECONDARY40
@ WIFI_CHANLIST_SECONDARY
@ WIFI_CHANLIST_SECONDARY160
@ WIFI_CHANLIST_SECONDARY80
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyState
The state of the PHY layer.
@ IDLE
The PHY layer is IDLE.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ RX
The PHY layer is receiving a packet.
static constexpr uint8_t WIFI_MIN_TX_PWR_LEVEL
minimum TX power level value
std::vector< BandInfo > Bands
Container of BandInfo.
double MHz_u
MHz weak type.
Definition wifi-units.h:31
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
double dBm_u
dBm weak type
Definition wifi-units.h:27
@ WIFI_MAC_QOSDATA
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:32
Hz_u MHzToHz(MHz_u val)
Convert from MHz to Hz.
Definition wifi-utils.h:120
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
double dB_u
dB weak type
Definition wifi-units.h:28
STL namespace.
structure that holds information to perform CCA check
std::size_t expectedCcaNotifications
expected number of CCA_BUSY notifications
Time expectedCcaEndTime
expected CCA_BUSY end time
Time timePoint
time at which the check will performed
Time expectedCcaStartTime
expected CCA_BUSY start time
std::vector< Time > expectedPer20MhzDurations
expected per-20 MHz CCA duration
WifiChannelListType expectedChannelListType
expected channel list type
structure that holds information to perform CCA threshold update
Time timePoint
time at which the update will be performed
dBm_u ccaThreshold
new CCA threshold value to be set
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 legacyPhyHeaderDuration
const Time ehtPhyHeaderDuration
const Time aCcaTime
const Time aCcaTimeWithDelta
constexpr MHz_u P320_CENTER_FREQUENCY
constexpr MHz_u S80_CENTER_FREQUENCY
constexpr MHz_u S20_CENTER_FREQUENCY
const Time hePhyHeaderDuration
constexpr MHz_u P20_CENTER_FREQUENCY
constexpr MHz_u S160_CENTER_FREQUENCY
constexpr MHz_u S40_CENTER_FREQUENCY
const Time testStep
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