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