A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-phy-reception-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7 */
8
9#include "ns3/ampdu-tag.h"
10#include "ns3/ap-wifi-mac.h"
11#include "ns3/boolean.h"
12#include "ns3/config.h"
13#include "ns3/double.h"
14#include "ns3/he-phy.h"
15#include "ns3/he-ppdu.h"
16#include "ns3/interference-helper.h"
17#include "ns3/log.h"
18#include "ns3/mobility-helper.h"
19#include "ns3/mpdu-aggregator.h"
20#include "ns3/multi-model-spectrum-channel.h"
21#include "ns3/nist-error-rate-model.h"
22#include "ns3/packet-socket-address.h"
23#include "ns3/packet-socket-client.h"
24#include "ns3/packet-socket-helper.h"
25#include "ns3/packet-socket-server.h"
26#include "ns3/pointer.h"
27#include "ns3/rng-seed-manager.h"
28#include "ns3/simple-frame-capture-model.h"
29#include "ns3/single-model-spectrum-channel.h"
30#include "ns3/spectrum-wifi-helper.h"
31#include "ns3/spectrum-wifi-phy.h"
32#include "ns3/test.h"
33#include "ns3/threshold-preamble-detection-model.h"
34#include "ns3/wifi-bandwidth-filter.h"
35#include "ns3/wifi-mac-header.h"
36#include "ns3/wifi-mpdu.h"
37#include "ns3/wifi-net-device.h"
38#include "ns3/wifi-psdu.h"
39#include "ns3/wifi-spectrum-phy-interface.h"
40#include "ns3/wifi-spectrum-signal-parameters.h"
41#include "ns3/wifi-spectrum-value-helper.h"
42#include "ns3/wifi-utils.h"
43
44#include <optional>
45
46using namespace ns3;
47
48NS_LOG_COMPONENT_DEFINE("WifiPhyReceptionTest");
49
50static const uint8_t CHANNEL_NUMBER = 36;
51static const MHz_u FREQUENCY = 5180;
52static const MHz_u CHANNEL_WIDTH = 20;
53static const MHz_u GUARD_WIDTH = CHANNEL_WIDTH; // expanded to channel width to model spectrum mask
54
55/**
56 * \ingroup wifi-test
57 * \ingroup tests
58 *
59 * \brief Wifi Phy Reception Test base class
60 */
62{
63 public:
64 /**
65 * Constructor
66 *
67 * \param test_name the test name
68 */
69 WifiPhyReceptionTest(std::string test_name);
70 /**
71 * Destructor
72 */
73 ~WifiPhyReceptionTest() override = default;
74
75 protected:
76 void DoSetup() override;
77 void DoTeardown() override;
78
79 /**
80 * Send packet function
81 * \param rxPower the transmit power
82 * \param packetSize the size of the packet in bytes
83 * \param mcs the MCS to transmit the packet
84 */
85 void SendPacket(dBm_u rxPower, uint32_t packetSize, uint8_t mcs);
86
87 /**
88 * Schedule now to check the PHY state
89 * \param expectedState the expected PHY state
90 */
91 void CheckPhyState(WifiPhyState expectedState);
92 /**
93 * Check the PHY state now
94 * \param expectedState the expected PHY state
95 */
96 void DoCheckPhyState(WifiPhyState expectedState);
97
99 uint64_t m_uid{0}; //!< the UID to use for the PPDU
100};
101
103 : TestCase{test_name}
104{
105}
106
107void
109{
111 0,
113 NanoSeconds(800),
114 1,
115 1,
116 0,
117 20,
118 false);
119
121 WifiMacHeader hdr;
122
124 hdr.SetQosTid(0);
125
126 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
127 Time txDuration = m_phy->CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
128
129 Ptr<WifiPpdu> ppdu =
130 Create<HePpdu>(psdu, txVector, m_phy->GetOperatingChannel(), txDuration, m_uid++);
131
132 Ptr<SpectrumValue> txPowerSpectrum =
135 DbmToW(rxPower),
137
139 txParams->psd = txPowerSpectrum;
140 txParams->txPhy = nullptr;
141 txParams->duration = txDuration;
142 txParams->ppdu = ppdu;
143
144 m_phy->StartRx(txParams, nullptr);
145}
146
147void
149{
150 // This is needed to make sure PHY state will be checked as the last event if a state change
151 // occurred at the exact same time as the check
153}
154
155void
157{
158 WifiPhyState currentState;
159 PointerValue ptr;
160 m_phy->GetAttribute("State", ptr);
162 currentState = state->GetState();
163 NS_LOG_FUNCTION(this << currentState);
164 NS_TEST_ASSERT_MSG_EQ(currentState,
165 expectedState,
166 "PHY State " << currentState << " does not match expected state "
167 << expectedState << " at " << Simulator::Now());
168}
169
170void
172{
178 m_phy->SetInterferenceHelper(interferenceHelper);
180 m_phy->SetErrorRateModel(error);
181 m_phy->SetDevice(dev);
182 m_phy->AddChannel(spectrumChannel);
183 m_phy->SetOperatingChannel(WifiPhy::ChannelTuple{CHANNEL_NUMBER, 0, WIFI_PHY_BAND_5GHZ, 0});
184 m_phy->ConfigureStandard(WIFI_STANDARD_80211ax);
185 dev->SetPhy(m_phy);
186 node->AddDevice(dev);
187}
188
189void
191{
192 m_phy->Dispose();
193 m_phy = nullptr;
194}
195
196/**
197 * \ingroup wifi-test
198 * \ingroup tests
199 *
200 * \brief Preamble detection test w/o frame capture
201 */
203{
204 public:
206
207 protected:
208 void DoSetup() override;
209
210 /**
211 * Spectrum wifi receive success function
212 * \param psdu the PSDU
213 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
214 * \param txVector the transmit vector
215 * \param statusPerMpdu reception status per MPDU
216 */
218 RxSignalInfo rxSignalInfo,
219 WifiTxVector txVector,
220 std::vector<bool> statusPerMpdu);
221 /**
222 * Spectrum wifi receive failure function
223 * \param psdu the PSDU
224 */
226 uint32_t m_countRxSuccess{0}; ///< count RX success
227 uint32_t m_countRxFailure{0}; ///< count RX failure
228
229 private:
230 void DoRun() override;
231
232 /**
233 * Check the number of received packets
234 * \param expectedSuccessCount the number of successfully received packets
235 * \param expectedFailureCount the number of unsuccessfully received packets
236 */
237 void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
238};
239
243 "Threshold preamble detection model test when no frame capture model is applied")
244{
245}
246
247void
249 uint32_t expectedFailureCount)
250{
252 expectedSuccessCount,
253 "Didn't receive right number of successful packets");
255 expectedFailureCount,
256 "Didn't receive right number of unsuccessful packets");
257}
258
259void
261 RxSignalInfo rxSignalInfo,
262 WifiTxVector txVector,
263 std::vector<bool> statusPerMpdu)
264{
265 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
267}
268
269void
275
276void
278{
280
281 m_phy->SetReceiveOkCallback(
283 m_phy->SetReceiveErrorCallback(
285
286 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
288 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(4));
289 preambleDetectionModel->SetAttribute("MinimumRssi", DoubleValue(-82));
290 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
291}
292
293void
295{
298 int64_t streamNumber = 0;
299 m_phy->AssignStreams(streamNumber);
300
301 // RX power > CCA-ED > CCA-PD
302 dBm_u rxPower = -50;
303
304 // CASE 1: send one packet and check PHY state:
305 // All reception stages should succeed and PHY state should be RX for the duration of the packet
306 // minus the time to detect the preamble, otherwise it should be IDLE.
307
310 this,
311 rxPower,
312 1000,
313 7);
314 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
315 // CCA_BUSY
318 this,
319 WifiPhyState::IDLE);
322 this,
323 WifiPhyState::CCA_BUSY);
324 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
325 // CCA_BUSY to RX
328 this,
329 WifiPhyState::CCA_BUSY);
332 this,
333 WifiPhyState::RX);
334 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
337 this,
338 WifiPhyState::RX);
341 this,
342 WifiPhyState::IDLE);
343 // Packet should have been successfully received
346 this,
347 1,
348 0);
349
350 // CASE 2: send two packets with same power within the 4us window and check PHY state:
351 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
352 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
353 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
354 // time to detect the preamble.
355
358 this,
359 rxPower,
360 1000,
361 7);
364 this,
365 rxPower,
366 1000,
367 7);
368 // At 4us, no preamble is successfully detected and STA PHY STATE should move from IDLE to
369 // CCA_BUSY
372 this,
373 WifiPhyState::IDLE);
376 this,
377 WifiPhyState::CCA_BUSY);
378 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
379 // = 154.8us
382 this,
383 WifiPhyState::CCA_BUSY);
386 this,
387 WifiPhyState::IDLE);
388 // No more packet should have been successfully received, and since preamble detection did not
389 // pass, the packet should not have been counted as a failure
392 this,
393 1,
394 0);
395
396 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY
397 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
398 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
399 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
400 // time to detect the preamble.
401
404 this,
405 rxPower,
406 1000,
407 7);
410 this,
411 rxPower - 3,
412 1000,
413 7);
414 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
415 // CCA_BUSY
418 this,
419 WifiPhyState::IDLE);
422 this,
423 WifiPhyState::CCA_BUSY);
424 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
425 // = 154.8us
428 this,
429 WifiPhyState::CCA_BUSY);
432 this,
433 WifiPhyState::IDLE);
434 // No more packet should have been successfully received, and since preamble detection did not
435 // pass the packet should not have been counted as a failure
438 this,
439 1,
440 0);
441
442 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY
443 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
444 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
445 // decode the modulation).
446
449 this,
450 rxPower,
451 1000,
452 7);
455 this,
456 rxPower - 6,
457 1000,
458 7);
459 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
460 // CCA_BUSY
463 this,
464 WifiPhyState::IDLE);
467 this,
468 WifiPhyState::CCA_BUSY);
469 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
470 // CCA_BUSY to RX
473 this,
474 WifiPhyState::CCA_BUSY);
477 this,
478 WifiPhyState::RX);
479 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
480 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
481 // should first be seen as CCA_BUSY for 2us.
484 this,
485 WifiPhyState::RX);
488 this,
489 WifiPhyState::CCA_BUSY);
492 this,
493 WifiPhyState::CCA_BUSY);
496 this,
497 WifiPhyState::IDLE);
498 // In this case, the first packet should be marked as a failure
501 this,
502 1,
503 1);
504
505 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY
506 // state: PHY preamble detection should fail because SNR is too low (around -3 dB, which is
507 // lower than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is
508 // above CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus
509 // the time to detect the preamble.
510
513 this,
514 rxPower,
515 1000,
516 7);
519 this,
520 rxPower + static_cast<dB_u>(3.0),
521 1000,
522 7);
523 // At 6us (hence 4us after the last signal is received), no preamble is successfully detected,
524 // hence STA PHY STATE should move from IDLE to CCA_BUSY
527 this,
528 WifiPhyState::IDLE);
531 this,
532 WifiPhyState::CCA_BUSY);
533 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
534 // = 154.8us
537 this,
538 WifiPhyState::CCA_BUSY);
541 this,
542 WifiPhyState::IDLE);
543 // No more packet should have been successfully received, and since preamble detection did not
544 // pass the packet should not have been counted as a failure
547 this,
548 1,
549 1);
550
551 // CCA-PD < RX power < CCA-ED
552 rxPower = -70;
553
554 // CASE 6: send one packet and check PHY state:
555 // All reception stages should succeed and PHY state should be RX for the duration of the packet
556 // minus the time to detect the preamble, otherwise it should be IDLE.
557
560 this,
561 rxPower,
562 1000,
563 7);
564 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
565 // CCA_BUSY
568 this,
569 WifiPhyState::IDLE);
572 this,
573 WifiPhyState::CCA_BUSY);
574 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
575 // CCA_BUSY to RX
578 this,
579 WifiPhyState::CCA_BUSY);
582 this,
583 WifiPhyState::RX);
584 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
587 this,
588 WifiPhyState::RX);
591 this,
592 WifiPhyState::IDLE);
593 // Packet should have been successfully received
596 this,
597 2,
598 1);
599
600 // CASE 7: send two packets with same power within the 4us window and check PHY state:
601 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
602 // the threshold of 4 dB), and PHY state should be CCA_BUSY since it should detect the start of
603 // a valid OFDM transmission at a receive level greater than or equal to the minimum modulation
604 // and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
605
608 this,
609 rxPower,
610 1000,
611 7);
614 this,
615 rxPower,
616 1000,
617 7);
618 // At 4us, STA PHY STATE should stay IDLE
621 this,
622 WifiPhyState::CCA_BUSY);
623 // No more packet should have been successfully received, and since preamble detection did not
624 // pass the packet should not have been counted as a failure
627 this,
628 2,
629 1);
630
631 // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY
632 // state: PHY preamble detection should fail PHY preamble detection should fail because SNR is
633 // too low (around 3 dB, which is lower than the threshold of 4 dB), and PHY state should be
634 // CCA_BUSY since it should detect the start of a valid OFDM transmission at a receive level
635 // greater than or equal to the minimum modulation and coding rate sensitivity (–82 dBm for 20
636 // MHz channel spacing).
637
640 this,
641 rxPower,
642 1000,
643 7);
646 this,
647 rxPower - 3,
648 1000,
649 7);
650 // At 4us, STA PHY STATE should stay IDLE
653 this,
654 WifiPhyState::CCA_BUSY);
655 // No more packet should have been successfully received, and since preamble detection did not
656 // pass the packet should not have been counted as a failure
659 this,
660 2,
661 1);
662
663 // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY
664 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
665 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
666 // decode the modulation).
667
670 this,
671 rxPower,
672 1000,
673 7);
676 this,
677 rxPower - 6,
678 1000,
679 7);
680 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
681 // CCA_BUSY
684 this,
685 WifiPhyState::IDLE);
688 this,
689 WifiPhyState::CCA_BUSY);
690 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
691 // CCA_BUSY to RX
694 this,
695 WifiPhyState::CCA_BUSY);
698 this,
699 WifiPhyState::RX);
700 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
701 // 152.8us.
704 this,
705 WifiPhyState::RX);
708 this,
709 WifiPhyState::CCA_BUSY);
710 // In this case, the first packet should be marked as a failure
713 this,
714 2,
715 2);
716
717 // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY
718 // state: PHY preamble detection should fail because SNR is too low (around -3 dB, which is
719 // lower than the threshold of 4 dB), and PHY state should stay IDLE since the total energy is
720 // below CCA-ED (-62 dBm).
721
724 this,
725 rxPower,
726 1000,
727 7);
730 this,
731 rxPower + static_cast<dB_u>(3.0),
732 1000,
733 7);
734 // At 4us, STA PHY STATE should stay IDLE
737 this,
738 WifiPhyState::IDLE);
739 // No more packet should have been successfully received, and since preamble detection did not
740 // pass the packet should not have been counted as a failure
743 this,
744 2,
745 2);
746
747 // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble
748 // detection (-82 dBm) and check PHY state: preamble detection should succeed and PHY state
749 // should move to RX.
750
751 rxPower = -81;
752
755 this,
756 rxPower,
757 1000,
758 7);
759 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
760 // CCA_BUSY
763 this,
764 WifiPhyState::IDLE);
767 this,
768 WifiPhyState::CCA_BUSY);
769 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
770 // CCA_BUSY to RX
773 this,
774 WifiPhyState::CCA_BUSY);
777 this,
778 WifiPhyState::RX);
779 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
782 this,
783 WifiPhyState::RX);
786 this,
787 WifiPhyState::IDLE);
788
789 // RX power < CCA-PD < CCA-ED
790 rxPower = -83;
791
792 // CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble
793 // detection (-82 dBm) and check PHY state: preamble detection should fail and PHY should be
794 // kept in IDLE state.
795
798 this,
799 rxPower,
800 1000,
801 7);
802 // At 4us, STA PHY state should be IDLE
805 this,
806 WifiPhyState::IDLE);
807
810}
811
812/**
813 * \ingroup wifi-test
814 * \ingroup tests
815 *
816 * \brief Preamble detection test w/o frame capture
817 */
819{
820 public:
822
823 protected:
824 void DoSetup() override;
825
826 /**
827 * Spectrum wifi receive success function
828 * \param psdu the PSDU
829 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
830 * \param txVector the transmit vector
831 * \param statusPerMpdu reception status per MPDU
832 */
834 RxSignalInfo rxSignalInfo,
835 WifiTxVector txVector,
836 std::vector<bool> statusPerMpdu);
837 /**
838 * Spectrum wifi receive failure function
839 * \param psdu the PSDU
840 */
842 uint32_t m_countRxSuccess{0}; ///< count RX success
843 uint32_t m_countRxFailure{0}; ///< count RX failure
844
845 private:
846 void DoRun() override;
847
848 /**
849 * Check the number of received packets
850 * \param expectedSuccessCount the number of successfully received packets
851 * \param expectedFailureCount the number of unsuccessfuly received packets
852 */
853 void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
854};
855
858 "Threshold preamble detection model test when simple frame capture model is applied")
859{
860}
861
862void
864 uint32_t expectedFailureCount)
865{
867 expectedSuccessCount,
868 "Didn't receive right number of successful packets");
870 expectedFailureCount,
871 "Didn't receive right number of unsuccessful packets");
872}
873
874void
876 RxSignalInfo rxSignalInfo,
877 WifiTxVector txVector,
878 std::vector<bool> statusPerMpdu)
879{
880 NS_LOG_FUNCTION(this << *psdu << txVector);
882}
883
884void
890
891void
893{
895
896 m_phy->SetReceiveOkCallback(
898 m_phy->SetReceiveErrorCallback(
900
901 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
903 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(4));
904 preambleDetectionModel->SetAttribute("MinimumRssi", DoubleValue(-82));
905 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
906
908 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
909 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
910 m_phy->SetFrameCaptureModel(frameCaptureModel);
911}
912
913void
915{
918 int64_t streamNumber = 1;
919 m_phy->AssignStreams(streamNumber);
920
921 // RX power > CCA-ED > CCA-PD
922 dBm_u rxPower = -50;
923
924 // CASE 1: send one packet and check PHY state:
925 // All reception stages should succeed and PHY state should be RX for the duration of the packet
926 // minus the time to detect the preamble, otherwise it should be IDLE.
927
930 this,
931 rxPower,
932 1000,
933 7);
934 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
935 // CCA_BUSY
938 this,
939 WifiPhyState::IDLE);
942 this,
943 WifiPhyState::CCA_BUSY);
944 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
945 // CCA_BUSY to RX
948 this,
949 WifiPhyState::CCA_BUSY);
952 this,
953 WifiPhyState::RX);
954 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
957 this,
958 WifiPhyState::RX);
961 this,
962 WifiPhyState::IDLE);
963 // Packet should have been successfully received
966 this,
967 1,
968 0);
969
970 // CASE 2: send two packets with same power within the 4us window and check PHY state:
971 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
972 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
973 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
974 // time to detect the preamble.
975
978 this,
979 rxPower,
980 1000,
981 7);
984 this,
985 rxPower,
986 1000,
987 7);
988 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
989 // CCA_BUSY
992 this,
993 WifiPhyState::IDLE);
996 this,
997 WifiPhyState::CCA_BUSY);
998 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
999 // = 154.8us
1002 this,
1003 WifiPhyState::CCA_BUSY);
1006 this,
1007 WifiPhyState::IDLE);
1008 // No more packet should have been successfully received, and since preamble detection did not
1009 // pass the packet should not have been counted as a failure
1012 this,
1013 1,
1014 0);
1015
1016 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY
1017 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
1018 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1019 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1020 // time to detect the preamble.
1021
1024 this,
1025 rxPower,
1026 1000,
1027 7);
1030 this,
1031 rxPower - 3,
1032 1000,
1033 7);
1034 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1035 // CCA_BUSY
1038 this,
1039 WifiPhyState::IDLE);
1042 this,
1043 WifiPhyState::CCA_BUSY);
1044 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1045 // = 154.8us
1048 this,
1049 WifiPhyState::CCA_BUSY);
1052 this,
1053 WifiPhyState::IDLE);
1054 // No more packet should have been successfully received, and since preamble detection did not
1055 // pass the packet should not have been counted as a failure
1058 this,
1059 1,
1060 0);
1061
1062 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY
1063 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1064 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1065 // decode the modulation).
1066
1069 this,
1070 rxPower,
1071 1000,
1072 7);
1075 this,
1076 rxPower - 6,
1077 1000,
1078 7);
1079 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1080 // CCA_BUSY
1083 this,
1084 WifiPhyState::IDLE);
1087 this,
1088 WifiPhyState::CCA_BUSY);
1089 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1090 // CCA_BUSY to RX
1093 this,
1094 WifiPhyState::CCA_BUSY);
1097 this,
1098 WifiPhyState::RX);
1099 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1100 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
1101 // should first be seen as CCA_BUSY for 2us.
1104 this,
1105 WifiPhyState::RX);
1108 this,
1109 WifiPhyState::CCA_BUSY);
1112 this,
1113 WifiPhyState::CCA_BUSY);
1116 this,
1117 WifiPhyState::IDLE);
1118 // In this case, the first packet should be marked as a failure
1121 this,
1122 1,
1123 1);
1124
1125 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY
1126 // state: PHY preamble detection should switch because a higher packet is received within the
1127 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1128 // lower than the threshold of 4 dB), PHY state should be CCA_BUSY since the total energy is
1129 // above CCA-ED (-62 dBm).
1130
1133 this,
1134 rxPower,
1135 1000,
1136 7);
1139 this,
1140 rxPower + static_cast<dB_u>(3.0),
1141 1000,
1142 7);
1143 // At 4us, STA PHY STATE should stay IDLE
1146 this,
1147 WifiPhyState::IDLE);
1148 // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
1151 this,
1152 WifiPhyState::IDLE);
1155 this,
1156 WifiPhyState::CCA_BUSY);
1157 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1158 // = 154.8us
1161 this,
1162 WifiPhyState::CCA_BUSY);
1165 this,
1166 WifiPhyState::IDLE);
1167 // No more packet should have been successfully received, and since preamble detection did not
1168 // pass the packet should not have been counted as a failure
1171 this,
1172 1,
1173 1);
1174
1175 // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY
1176 // state: PHY preamble detection should switch because a higher packet is received within the
1177 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1178 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1179 // decode the modulation).
1180
1183 this,
1184 rxPower,
1185 1000,
1186 7);
1189 this,
1190 rxPower + static_cast<dB_u>(6.0),
1191 1000,
1192 7);
1193 // At 4us, STA PHY STATE should stay IDLE
1196 this,
1197 WifiPhyState::IDLE);
1198 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1199 // CCA_BUSY
1202 this,
1203 WifiPhyState::IDLE);
1206 this,
1207 WifiPhyState::CCA_BUSY);
1208 // At 46us, PHY header should be successfully received and STA PHY STATE should move from
1209 // CCA_BUSY to RX
1212 this,
1213 WifiPhyState::CCA_BUSY);
1216 this,
1217 WifiPhyState::RX);
1218 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1219 // = 154.8us
1222 this,
1223 WifiPhyState::RX);
1226 this,
1227 WifiPhyState::IDLE);
1228 // In this case, the second packet should be marked as a failure
1231 this,
1232 1,
1233 2);
1234
1235 // CASE 7: send two packets with same power at the exact same time and check PHY state:
1236 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
1237 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1238 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1239 // time to detect the preamble.
1240
1243 this,
1244 rxPower,
1245 1000,
1246 7);
1249 this,
1250 rxPower,
1251 1000,
1252 7);
1253 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1254 // CCA_BUSY
1257 this,
1258 WifiPhyState::IDLE);
1261 this,
1262 WifiPhyState::CCA_BUSY);
1263 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1264 // = 154.8us
1267 this,
1268 WifiPhyState::CCA_BUSY);
1271 this,
1272 WifiPhyState::IDLE);
1273 // No more packet should have been successfully received, and since preamble detection did not
1274 // pass the packet should not have been counted as a failure
1277 this,
1278 1,
1279 2);
1280
1281 // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY
1282 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
1283 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1284 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1285 // time to detect the preamble.
1286
1289 this,
1290 rxPower,
1291 1000,
1292 7);
1295 this,
1296 rxPower - 3,
1297 1000,
1298 7);
1299 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1300 // CCA_BUSY
1303 this,
1304 WifiPhyState::IDLE);
1307 this,
1308 WifiPhyState::CCA_BUSY);
1309 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1312 this,
1313 WifiPhyState::CCA_BUSY);
1316 this,
1317 WifiPhyState::IDLE);
1318 // No more packet should have been successfully received, and since preamble detection did not
1319 // pass the packet should not have been counted as a failure
1322 this,
1323 1,
1324 2);
1325
1326 // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY
1327 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1328 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1329 // decode the modulation).
1330
1333 this,
1334 rxPower,
1335 1000,
1336 7);
1339 this,
1340 rxPower - 6,
1341 1000,
1342 7);
1343 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1344 // CCA_BUSY
1347 this,
1348 WifiPhyState::IDLE);
1351 this,
1352 WifiPhyState::CCA_BUSY);
1353 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1354 // CCA_BUSY to RX
1357 this,
1358 WifiPhyState::CCA_BUSY);
1361 this,
1362 WifiPhyState::RX);
1363 // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
1366 this,
1367 WifiPhyState::RX);
1370 this,
1371 WifiPhyState::IDLE);
1372 // In this case, the first packet should be marked as a failure
1375 this,
1376 1,
1377 3);
1378
1379 // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY
1380 // state: PHY preamble detection should switch because a higher packet is received within the
1381 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1382 // lower than the threshold of 4 dB), PHY state should be CCA_BUSY since the total energy is
1383 // above CCA-ED (-62 dBm).
1384
1387 this,
1388 rxPower,
1389 1000,
1390 7);
1393 this,
1394 rxPower + static_cast<dB_u>(3.0),
1395 1000,
1396 7);
1397 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1398 // CCA_BUSY
1401 this,
1402 WifiPhyState::IDLE);
1405 this,
1406 WifiPhyState::CCA_BUSY);
1407 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1408 Simulator::Schedule(Seconds(10.0) + NanoSeconds(152799),
1410 this,
1411 WifiPhyState::CCA_BUSY);
1412 Simulator::Schedule(Seconds(10.0) + NanoSeconds(152800),
1414 this,
1415 WifiPhyState::IDLE);
1416 // No more packet should have been successfully received, and since preamble detection did not
1417 // pass the packet should not have been counted as a failure
1420 this,
1421 1,
1422 3);
1423
1424 // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY
1425 // state: PHY preamble detection should switch because a higher packet is received within the
1426 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1427 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1428 // decode the modulation).
1429
1432 this,
1433 rxPower,
1434 1000,
1435 7);
1438 this,
1439 rxPower + static_cast<dB_u>(6.0),
1440 1000,
1441 7);
1442 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1443 // CCA_BUSY
1446 this,
1447 WifiPhyState::IDLE);
1450 this,
1451 WifiPhyState::CCA_BUSY);
1452 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1453 // CCA_BUSY to RX
1456 this,
1457 WifiPhyState::CCA_BUSY);
1460 this,
1461 WifiPhyState::RX);
1462 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1463 Simulator::Schedule(Seconds(11.0) + NanoSeconds(152799),
1465 this,
1466 WifiPhyState::RX);
1467 Simulator::Schedule(Seconds(11.0) + NanoSeconds(152800),
1469 this,
1470 WifiPhyState::IDLE);
1471 // In this case, the second packet should be marked as a failure
1474 this,
1475 1,
1476 4);
1477
1478 // CCA-PD < RX power < CCA-ED
1479 rxPower = -70;
1480
1481 // CASE 12: send one packet and check PHY state:
1482 // All reception stages should succeed and PHY state should be RX for the duration of the packet
1483 // minus the time to detect the preamble, otherwise it should be IDLE.
1484
1487 this,
1488 rxPower,
1489 1000,
1490 7);
1491 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1492 // CCA_BUSY
1495 this,
1496 WifiPhyState::IDLE);
1499 this,
1500 WifiPhyState::CCA_BUSY);
1501 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1502 // CCA_BUSY to RX
1505 this,
1506 WifiPhyState::CCA_BUSY);
1509 this,
1510 WifiPhyState::RX);
1511 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
1512 Simulator::Schedule(Seconds(12.0) + NanoSeconds(152799),
1514 this,
1515 WifiPhyState::RX);
1516 Simulator::Schedule(Seconds(12.0) + NanoSeconds(152800),
1518 this,
1519 WifiPhyState::IDLE);
1520 // Packet should have been successfully received
1523 this,
1524 2,
1525 4);
1526
1527 // CASE 13: send two packets with same power within the 4us window and check PHY state:
1528 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
1529 // the threshold of 4 dB), and PHY state should be CCA_BUSY since it should detect the start of
1530 // a valid OFDM transmission at a receive level greater than or equal to the minimum modulation
1531 // and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
1532
1535 this,
1536 rxPower,
1537 1000,
1538 7);
1541 this,
1542 rxPower,
1543 1000,
1544 7);
1545 // At 4us, STA PHY STATE should stay IDLE
1548 this,
1549 WifiPhyState::CCA_BUSY);
1550 // No more packet should have been successfully received, and since preamble detection did not
1551 // pass the packet should not have been counted as a failure
1554 this,
1555 2,
1556 4);
1557
1558 // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY
1559 // state: PHY preamble detection should fail PHY preamble detection should fail because SNR is
1560 // too low (around 3 dB, which is lower than the threshold of 4 dB), and PHY state should be
1561 // CCA_BUSY since it should detect the start of a valid OFDM transmission at a receive level
1562 // greater than or equal to the minimum modulation and coding rate sensitivity (–82 dBm for 20
1563 // MHz channel spacing).
1564
1567 this,
1568 rxPower,
1569 1000,
1570 7);
1573 this,
1574 rxPower - 3,
1575 1000,
1576 7);
1577 // At 4us, STA PHY STATE should stay IDLE
1580 this,
1581 WifiPhyState::CCA_BUSY);
1582 // No more packet should have been successfully received, and since preamble detection did not
1583 // pass the packet should not have been counted as a failure
1586 this,
1587 2,
1588 4);
1589
1590 // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY
1591 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1592 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1593 // decode the modulation).
1594
1597 this,
1598 rxPower,
1599 1000,
1600 7);
1603 this,
1604 rxPower - 6,
1605 1000,
1606 7);
1607 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1608 // CCA_BUSY
1611 this,
1612 WifiPhyState::IDLE);
1615 this,
1616 WifiPhyState::CCA_BUSY);
1617 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1618 // CCA_BUSY to RX
1621 this,
1622 WifiPhyState::CCA_BUSY);
1625 this,
1626 WifiPhyState::RX);
1627 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
1628 // 152.8us.
1629 Simulator::Schedule(Seconds(15.0) + NanoSeconds(152799),
1631 this,
1632 WifiPhyState::RX);
1633 Simulator::Schedule(Seconds(15.0) + NanoSeconds(152800),
1635 this,
1636 WifiPhyState::CCA_BUSY);
1637 // In this case, the first packet should be marked as a failure
1640 this,
1641 2,
1642 5);
1643
1644 // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY
1645 // state: PHY preamble detection should switch because a higher packet is received within the
1646 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1647 // lower than the threshold of 4 dB). and PHY state should be CCA_BUSY since it should detect
1648 // the start of a valid OFDM transmission at a receive level greater than or equal to the
1649 // minimum modulation and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
1650
1653 this,
1654 rxPower,
1655 1000,
1656 7);
1659 this,
1660 rxPower + static_cast<dB_u>(3.0),
1661 1000,
1662 7);
1663 // At 4us, STA PHY STATE should stay IDLE
1666 this,
1667 WifiPhyState::IDLE);
1668 // At 6us, STA PHY STATE should be CCA_BUSY
1671 this,
1672 WifiPhyState::CCA_BUSY);
1673 // No more packet should have been successfully received, and since preamble detection did not
1674 // pass the packet should not have been counted as a failure
1677 this,
1678 2,
1679 5);
1680
1681 // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY
1682 // state: PHY preamble detection should switch because a higher packet is received within the
1683 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1684 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1685 // decode the modulation).
1686
1689 this,
1690 rxPower,
1691 1000,
1692 7);
1695 this,
1696 rxPower + static_cast<dB_u>(6.0),
1697 1000,
1698 7);
1699 // At 4us, STA PHY STATE should stay IDLE
1702 this,
1703 WifiPhyState::IDLE);
1704 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1705 // CCA_BUSY
1708 this,
1709 WifiPhyState::IDLE);
1712 this,
1713 WifiPhyState::CCA_BUSY);
1714 // At 46us, PHY header should be successfully received and STA PHY STATE should move from
1715 // CCA_BUSY to RX
1718 this,
1719 WifiPhyState::CCA_BUSY);
1722 this,
1723 WifiPhyState::RX);
1724 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1725 // = 154.8us
1726 Simulator::Schedule(Seconds(17.0) + NanoSeconds(154799),
1728 this,
1729 WifiPhyState::RX);
1730 Simulator::Schedule(Seconds(17.0) + NanoSeconds(154800),
1732 this,
1733 WifiPhyState::IDLE);
1734 // In this case, the second packet should be marked as a failure
1737 this,
1738 2,
1739 6);
1740
1741 rxPower = -50;
1742 // CASE 18: send two packets with second one 50 dB higher within the 4us window
1743
1746 this,
1747 rxPower,
1748 1000,
1749 7);
1752 this,
1753 rxPower + static_cast<dB_u>(50.0),
1754 1000,
1755 7);
1756 // The second packet should be received successfully
1759 this,
1760 3,
1761 6);
1762
1763 // CASE 19: send two packets with second one 10 dB higher within the 4us window
1764
1767 this,
1768 rxPower,
1769 1000,
1770 7);
1773 this,
1774 rxPower + static_cast<dB_u>(10.0),
1775 1000,
1776 7);
1777 // The second packet should be captured, but not decoded since SNR to low for used MCS
1780 this,
1781 3,
1782 7);
1783
1784 // CASE 20: send two packets with second one 50 dB higher in the same time
1785
1788 this,
1789 rxPower,
1790 1000,
1791 7);
1794 this,
1795 rxPower + static_cast<dB_u>(50.0),
1796 1000,
1797 7);
1798 // The second packet should be received successfully, same as in CASE 13
1801 this,
1802 4,
1803 7);
1804
1805 // CASE 21: send two packets with second one 10 dB higher in the same time
1806
1809 this,
1810 rxPower,
1811 1000,
1812 7);
1815 this,
1816 rxPower + static_cast<dB_u>(10.0),
1817 1000,
1818 7);
1819 // The second packet should be captured, but not decoded since SNR to low for used MCS, same as
1820 // in CASE 19
1823 this,
1824 4,
1825 8);
1826
1829}
1830
1831/**
1832 * \ingroup wifi-test
1833 * \ingroup tests
1834 *
1835 * \brief Simple frame capture model test
1836 */
1838{
1839 public:
1841
1842 private:
1843 void DoSetup() override;
1844 void DoRun() override;
1845
1846 /**
1847 * Reset function
1848 */
1849 void Reset();
1850 /**
1851 * Spectrum wifi receive success function
1852 * \param psdu the PSDU
1853 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
1854 * \param txVector the transmit vector
1855 * \param statusPerMpdu reception status per MPDU
1856 */
1858 RxSignalInfo rxSignalInfo,
1859 WifiTxVector txVector,
1860 std::vector<bool> statusPerMpdu);
1861 /**
1862 * RX dropped function
1863 * \param p the packet
1864 * \param reason the reason
1865 */
1867
1868 /**
1869 * Verify whether 1000 bytes packet has been received
1870 */
1872 /**
1873 * Verify whether 1500 bytes packet has been received
1874 */
1876 /**
1877 * Verify whether 1000 bytes packet has been dropped
1878 */
1880 /**
1881 * Verify whether 1500 bytes packet has been dropped
1882 */
1884
1885 bool m_rxSuccess1000B{false}; ///< count received packets with 1000B payload
1886 bool m_rxSuccess1500B{false}; ///< count received packets with 1500B payload
1887 bool m_rxDropped1000B{false}; ///< count dropped packets with 1000B payload
1888 bool m_rxDropped1500B{false}; ///< count dropped packets with 1500B payload
1889};
1890
1892 : WifiPhyReceptionTest("Simple frame capture model test")
1893{
1894}
1895
1896void
1898 RxSignalInfo rxSignalInfo,
1899 WifiTxVector txVector,
1900 std::vector<bool> statusPerMpdu)
1901{
1902 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
1903 NS_ASSERT(!psdu->IsAggregate() || psdu->IsSingle());
1904 if (psdu->GetSize() == 1030)
1905 {
1906 m_rxSuccess1000B = true;
1907 }
1908 else if (psdu->GetSize() == 1530)
1909 {
1910 m_rxSuccess1500B = true;
1911 }
1912}
1913
1914void
1916{
1917 NS_LOG_FUNCTION(this << p << reason);
1918 if (p->GetSize() == 1030)
1919 {
1920 m_rxDropped1000B = true;
1921 }
1922 else if (p->GetSize() == 1530)
1923 {
1924 m_rxDropped1500B = true;
1925 }
1926}
1927
1928void
1930{
1931 m_rxSuccess1000B = false;
1932 m_rxSuccess1500B = false;
1933 m_rxDropped1000B = false;
1934 m_rxDropped1500B = false;
1935}
1936
1937void
1942
1943void
1948
1949void
1954
1955void
1960
1961void
1963{
1965
1966 m_phy->SetReceiveOkCallback(MakeCallback(&TestSimpleFrameCaptureModel::RxSuccess, this));
1967 m_phy->TraceConnectWithoutContext("PhyRxDrop",
1969
1970 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
1972 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(2));
1973 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
1974
1976 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
1977 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
1978 m_phy->SetFrameCaptureModel(frameCaptureModel);
1979}
1980
1981void
1983{
1986 int64_t streamNumber = 2;
1987 dBm_u rxPower = -30;
1988 m_phy->AssignStreams(streamNumber);
1989
1990 // CASE 1: send two packets with same power within the capture window:
1991 // PHY should not switch reception because they have same power.
1992
1995 this,
1996 rxPower,
1997 1000,
1998 0);
2001 this,
2002 rxPower,
2003 1500,
2004 0);
2007
2008 // CASE 2: send two packets with second one 6 dB weaker within the capture window:
2009 // PHY should not switch reception because first one has higher power.
2010
2013 this,
2014 rxPower,
2015 1000,
2016 0);
2019 this,
2020 rxPower - 6,
2021 1500,
2022 0);
2025 this);
2028
2029 // CASE 3: send two packets with second one 6 dB higher within the capture window:
2030 // PHY should switch reception because the second one has a higher power.
2031
2034 this,
2035 rxPower,
2036 1000,
2037 0);
2040 this,
2041 rxPower + static_cast<dB_u>(6.0),
2042 1500,
2043 0);
2047 this);
2049
2050 // CASE 4: send two packets with second one 6 dB higher after the capture window:
2051 // PHY should not switch reception because capture window duration has elapsed when the second
2052 // packet arrives.
2053
2056 this,
2057 rxPower,
2058 1000,
2059 0);
2062 this,
2063 rxPower + static_cast<dB_u>(6.0),
2064 1500,
2065 0);
2068
2071}
2072
2073/**
2074 * \ingroup wifi-test
2075 * \ingroup tests
2076 *
2077 * \brief Test PHY state upon success or failure of L-SIG and SIG-A
2078 */
2080{
2081 public:
2083
2084 private:
2085 void DoRun() override;
2086};
2087
2089 : WifiPhyReceptionTest("PHY headers reception test")
2090{
2091}
2092
2093void
2095{
2098 int64_t streamNumber = 0;
2099 m_phy->AssignStreams(streamNumber);
2100
2101 // RX power > CCA-ED
2102 dBm_u rxPower = -50;
2103
2104 // CASE 1: send one packet followed by a second one with same power between the end of the 4us
2105 // preamble detection window and the start of L-SIG of the first packet: reception should be
2106 // aborted since L-SIG cannot be decoded (SNR too low).
2107
2108 Simulator::Schedule(Seconds(1.0), &TestPhyHeadersReception::SendPacket, this, rxPower, 1000, 7);
2111 this,
2112 rxPower,
2113 1000,
2114 7);
2115 // At 10 us, STA PHY STATE should be CCA_BUSY.
2118 this,
2119 WifiPhyState::CCA_BUSY);
2120 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX and be kept to
2121 // CCA_BUSY.
2124 this,
2125 WifiPhyState::CCA_BUSY);
2126 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10
2127 // = 162.8us.
2130 this,
2131 WifiPhyState::CCA_BUSY);
2134 this,
2135 WifiPhyState::IDLE);
2136
2137 // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us
2138 // preamble detection window and the start of L-SIG of the first packet: reception should not be
2139 // aborted since L-SIG can be decoded (SNR high enough).
2140
2141 Simulator::Schedule(Seconds(2.0), &TestPhyHeadersReception::SendPacket, this, rxPower, 1000, 7);
2144 this,
2145 rxPower - 3,
2146 1000,
2147 7);
2148 // At 10 us, STA PHY STATE should be CCA_BUSY.
2151 this,
2152 WifiPhyState::CCA_BUSY);
2153 // At 44us (end of PHY header), STA PHY STATE should have moved to RX since PHY header reception
2154 // should have succeeded.
2157 this,
2158 WifiPhyState::CCA_BUSY);
2161 this,
2162 WifiPhyState::RX);
2163 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
2164 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
2165 // should first be seen as CCA_BUSY for 10us.
2168 this,
2169 WifiPhyState::RX);
2172 this,
2173 WifiPhyState::CCA_BUSY);
2176 this,
2177 WifiPhyState::CCA_BUSY);
2180 this,
2181 WifiPhyState::IDLE);
2182
2183 // CASE 3: send one packet followed by a second one with same power between the end of L-SIG and
2184 // the start of HE-SIG of the first packet: PHY header reception should not succeed but PHY
2185 // should stay in RX state for the duration estimated from L-SIG.
2186
2187 Simulator::Schedule(Seconds(3.0), &TestPhyHeadersReception::SendPacket, this, rxPower, 1000, 7);
2190 this,
2191 rxPower,
2192 1000,
2193 7);
2194 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX (HE-SIG failed) and be
2195 // kept to CCA_BUSY.
2198 this,
2199 WifiPhyState::CCA_BUSY);
2200 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed,
2201 // i.e. at 152.8us. However, since there is a second packet transmitted with a power above
2202 // CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
2205 this,
2206 WifiPhyState::CCA_BUSY);
2209 this,
2210 WifiPhyState::CCA_BUSY);
2213 this,
2214 WifiPhyState::CCA_BUSY);
2217 this,
2218 WifiPhyState::IDLE);
2219
2220 // CASE 4: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the
2221 // start of HE-SIG of the first packet: PHY header reception should succeed.
2222
2223 Simulator::Schedule(Seconds(4.0), &TestPhyHeadersReception::SendPacket, this, rxPower, 1000, 7);
2226 this,
2227 rxPower - 3,
2228 1000,
2229 7);
2230 // At 10 us, STA PHY STATE should be CCA_BUSY.
2233 this,
2234 WifiPhyState::CCA_BUSY);
2235 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2236 // should have succeeded.
2239 this,
2240 WifiPhyState::CCA_BUSY);
2243 this,
2244 WifiPhyState::RX);
2245 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed,
2246 // i.e. at 152.8us. However, since there is a second packet transmitted with a power above
2247 // CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
2250 this,
2251 WifiPhyState::RX);
2254 this,
2255 WifiPhyState::CCA_BUSY);
2258 this,
2259 WifiPhyState::CCA_BUSY);
2262 this,
2263 WifiPhyState::IDLE);
2264
2265 // RX power < CCA-ED
2266 rxPower = -70;
2267
2268 // CASE 5: send one packet followed by a second one with same power between the end of the 4us
2269 // preamble detection window and the start of L-SIG of the first packet: reception should be
2270 // aborted since L-SIG cannot be decoded (SNR too low).
2271
2272 Simulator::Schedule(Seconds(5.0), &TestPhyHeadersReception::SendPacket, this, rxPower, 1000, 7);
2275 this,
2276 rxPower,
2277 1000,
2278 7);
2279 // At 10 us, STA PHY STATE should be CCA_BUSY.
2282 this,
2283 WifiPhyState::CCA_BUSY);
2284 // At 24us (end of L-SIG), STA PHY STATE stay CCA_BUSY because L-SIG reception failed and the
2285 // start of a valid OFDM transmission has been detected
2288 this,
2289 WifiPhyState::CCA_BUSY);
2290
2291 // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us
2292 // preamble detection window and the start of L-SIG of the first packet: reception should not be
2293 // aborted since L-SIG can be decoded (SNR high enough).
2294
2295 Simulator::Schedule(Seconds(6.0), &TestPhyHeadersReception::SendPacket, this, rxPower, 1000, 7);
2298 this,
2299 rxPower - 3,
2300 1000,
2301 7);
2302 // At 10 us, STA PHY STATE should be CCA_BUSY.
2305 this,
2306 WifiPhyState::CCA_BUSY);
2307 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2308 // succeeded.
2311 this,
2312 WifiPhyState::CCA_BUSY);
2313 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2314 // should have succeeded.
2317 this,
2318 WifiPhyState::CCA_BUSY);
2321 this,
2322 WifiPhyState::RX);
2323 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
2324 // 152.8us.
2327 this,
2328 WifiPhyState::RX);
2331 this,
2332 WifiPhyState::CCA_BUSY);
2333
2334 // CASE 7: send one packet followed by a second one with same power between the end of L-SIG and
2335 // the start of HE-SIG of the first packet: PHY header reception should not succeed but PHY
2336 // should stay in RX state for the duration estimated from L-SIG.
2337
2338 Simulator::Schedule(Seconds(7.0), &TestPhyHeadersReception::SendPacket, this, rxPower, 1000, 7);
2341 this,
2342 rxPower,
2343 1000,
2344 7);
2345 // At 10 us, STA PHY STATE should be CCA_BUSY.
2348 this,
2349 WifiPhyState::CCA_BUSY);
2350 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2351 // succeeded.
2354 this,
2355 WifiPhyState::CCA_BUSY);
2356 // At 44 us (end of HE-SIG), STA PHY STATE should be not have moved to RX since reception of
2357 // HE-SIG should have failed.
2360 this,
2361 WifiPhyState::CCA_BUSY);
2362 // STA PHY STATE should keep CCA_BUSY once the duration estimated from L-SIG has elapsed, i.e.
2363 // at 152.8us.
2366 this,
2367 WifiPhyState::CCA_BUSY);
2368
2369 // CASE 8: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the
2370 // start of HE-SIG of the first packet: PHY header reception should succeed.
2371
2372 Simulator::Schedule(Seconds(8.0), &TestPhyHeadersReception::SendPacket, this, rxPower, 1000, 7);
2375 this,
2376 rxPower - 3,
2377 1000,
2378 7);
2379 // At 10 us, STA PHY STATE should be CCA_BUSY.
2382 this,
2383 WifiPhyState::CCA_BUSY);
2384 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2385 // succeeded.
2388 this,
2389 WifiPhyState::CCA_BUSY);
2390 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2391 // should have succeeded.
2394 this,
2395 WifiPhyState::CCA_BUSY);
2398 this,
2399 WifiPhyState::RX);
2400 // STA PHY STATE should move back to CCA_BUSY once the duration estimated from L-SIG has
2401 // elapsed, i.e. at 152.8us.
2404 this,
2405 WifiPhyState::RX);
2408 this,
2409 WifiPhyState::CCA_BUSY);
2410
2413}
2414
2415/**
2416 * \ingroup wifi-test
2417 * \ingroup tests
2418 *
2419 * \brief A-MPDU reception test
2420 */
2422{
2423 public:
2425
2426 private:
2427 void DoSetup() override;
2428 void DoRun() override;
2429
2430 /**
2431 * RX success function
2432 * \param psdu the PSDU
2433 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
2434 * \param txVector the transmit vector
2435 * \param statusPerMpdu reception status per MPDU
2436 */
2438 RxSignalInfo rxSignalInfo,
2439 WifiTxVector txVector,
2440 std::vector<bool> statusPerMpdu);
2441 /**
2442 * RX failure function
2443 * \param psdu the PSDU
2444 */
2445 void RxFailure(Ptr<const WifiPsdu> psdu);
2446 /**
2447 * RX dropped function
2448 * \param p the packet
2449 * \param reason the reason
2450 */
2452 /**
2453 * Increment reception success bitmap.
2454 * \param size the size of the received packet
2455 */
2457 /**
2458 * Increment reception failure bitmap.
2459 * \param size the size of the received packet
2460 */
2462
2463 /**
2464 * Reset bitmaps function
2465 */
2466 void ResetBitmaps();
2467
2468 /**
2469 * Send A-MPDU with 3 MPDUs of different size (i-th MSDU will have 100 bytes more than
2470 * (i-1)-th).
2471 * \param rxPower the transmit power
2472 * \param referencePacketSize the reference size of the packets in bytes (i-th MSDU will have
2473 * 100 bytes more than (i-1)-th)
2474 */
2475 void SendAmpduWithThreeMpdus(dBm_u rxPower, uint32_t referencePacketSize);
2476
2477 /**
2478 * Check the RX success bitmap for A-MPDU 1
2479 * \param expected the expected bitmap
2480 */
2481 void CheckRxSuccessBitmapAmpdu1(uint8_t expected);
2482 /**
2483 * Check the RX success bitmap for A-MPDU 2
2484 * \param expected the expected bitmap
2485 */
2486 void CheckRxSuccessBitmapAmpdu2(uint8_t expected);
2487 /**
2488 * Check the RX failure bitmap for A-MPDU 1
2489 * \param expected the expected bitmap
2490 */
2491 void CheckRxFailureBitmapAmpdu1(uint8_t expected);
2492 /**
2493 * Check the RX failure bitmap for A-MPDU 2
2494 * \param expected the expected bitmap
2495 */
2496 void CheckRxFailureBitmapAmpdu2(uint8_t expected);
2497 /**
2498 * Check the RX dropped bitmap for A-MPDU 1
2499 * \param expected the expected bitmap
2500 */
2501 void CheckRxDroppedBitmapAmpdu1(uint8_t expected);
2502 /**
2503 * Check the RX dropped bitmap for A-MPDU 2
2504 * \param expected the expected bitmap
2505 */
2506 void CheckRxDroppedBitmapAmpdu2(uint8_t expected);
2507
2508 /**
2509 * Check the PHY state
2510 * \param expectedState the expected PHY state
2511 */
2512 void CheckPhyState(WifiPhyState expectedState);
2513
2514 uint8_t m_rxSuccessBitmapAmpdu1{0}; ///< bitmap of successfully received MPDUs in A-MPDU #1
2515 uint8_t m_rxSuccessBitmapAmpdu2{0}; ///< bitmap of successfully received MPDUs in A-MPDU #2
2516
2517 uint8_t m_rxFailureBitmapAmpdu1{0}; ///< bitmap of unsuccessfully received MPDUs in A-MPDU #1
2518 uint8_t m_rxFailureBitmapAmpdu2{0}; ///< bitmap of unsuccessfully received MPDUs in A-MPDU #2
2519
2520 uint8_t m_rxDroppedBitmapAmpdu1{0}; ///< bitmap of dropped MPDUs in A-MPDU #1
2521 uint8_t m_rxDroppedBitmapAmpdu2{0}; ///< bitmap of dropped MPDUs in A-MPDU #2
2522};
2523
2525 : WifiPhyReceptionTest("A-MPDU reception test")
2526{
2527}
2528
2529void
2539
2540void
2542 RxSignalInfo rxSignalInfo,
2543 WifiTxVector txVector,
2544 std::vector<bool> statusPerMpdu)
2545{
2546 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
2547 if (statusPerMpdu.empty()) // wait for the whole A-MPDU
2548 {
2549 return;
2550 }
2551 NS_ABORT_MSG_IF(psdu->GetNMpdus() != statusPerMpdu.size(),
2552 "Should have one receive status per MPDU");
2553 auto rxOkForMpdu = statusPerMpdu.begin();
2554 for (auto mpdu = psdu->begin(); mpdu != psdu->end(); ++mpdu)
2555 {
2556 if (*rxOkForMpdu)
2557 {
2558 IncrementSuccessBitmap((*mpdu)->GetSize());
2559 }
2560 else
2561 {
2562 IncrementFailureBitmap((*mpdu)->GetSize());
2563 }
2564 ++rxOkForMpdu;
2565 }
2566}
2567
2568void
2570{
2571 if (size == 1030) // A-MPDU 1 - MPDU #1
2572 {
2574 }
2575 else if (size == 1130) // A-MPDU 1 - MPDU #2
2576 {
2577 m_rxSuccessBitmapAmpdu1 |= (1 << 1);
2578 }
2579 else if (size == 1230) // A-MPDU 1 - MPDU #3
2580 {
2581 m_rxSuccessBitmapAmpdu1 |= (1 << 2);
2582 }
2583 else if (size == 1330) // A-MPDU 2 - MPDU #1
2584 {
2586 }
2587 else if (size == 1430) // A-MPDU 2 - MPDU #2
2588 {
2589 m_rxSuccessBitmapAmpdu2 |= (1 << 1);
2590 }
2591 else if (size == 1530) // A-MPDU 2 - MPDU #3
2592 {
2593 m_rxSuccessBitmapAmpdu2 |= (1 << 2);
2594 }
2595}
2596
2597void
2599{
2600 NS_LOG_FUNCTION(this << *psdu);
2601 for (auto mpdu = psdu->begin(); mpdu != psdu->end(); ++mpdu)
2602 {
2603 IncrementFailureBitmap((*mpdu)->GetSize());
2604 }
2605}
2606
2607void
2609{
2610 if (size == 1030) // A-MPDU 1 - MPDU #1
2611 {
2613 }
2614 else if (size == 1130) // A-MPDU 1 - MPDU #2
2615 {
2616 m_rxFailureBitmapAmpdu1 |= (1 << 1);
2617 }
2618 else if (size == 1230) // A-MPDU 1 - MPDU #3
2619 {
2620 m_rxFailureBitmapAmpdu1 |= (1 << 2);
2621 }
2622 else if (size == 1330) // A-MPDU 2 - MPDU #1
2623 {
2625 }
2626 else if (size == 1430) // A-MPDU 2 - MPDU #2
2627 {
2628 m_rxFailureBitmapAmpdu2 |= (1 << 1);
2629 }
2630 else if (size == 1530) // A-MPDU 2 - MPDU #3
2631 {
2632 m_rxFailureBitmapAmpdu2 |= (1 << 2);
2633 }
2634}
2635
2636void
2638{
2639 NS_LOG_FUNCTION(this << p << reason);
2640 if (p->GetSize() == 1030) // A-MPDU 1 - MPDU #1
2641 {
2643 }
2644 else if (p->GetSize() == 1130) // A-MPDU 1 - MPDU #2
2645 {
2646 m_rxDroppedBitmapAmpdu1 |= (1 << 1);
2647 }
2648 else if (p->GetSize() == 1230) // A-MPDU 1 - MPDU #3
2649 {
2650 m_rxDroppedBitmapAmpdu1 |= (1 << 2);
2651 }
2652 else if (p->GetSize() == 1330) // A-MPDU 2 - MPDU #1
2653 {
2655 }
2656 else if (p->GetSize() == 1430) // A-MPDU 2 - MPDU #2
2657 {
2658 m_rxDroppedBitmapAmpdu2 |= (1 << 1);
2659 }
2660 else if (p->GetSize() == 1530) // A-MPDU 2 - MPDU #3
2661 {
2662 m_rxDroppedBitmapAmpdu2 |= (1 << 2);
2663 }
2664}
2665
2666void
2668{
2670 expected,
2671 "RX success bitmap for A-MPDU 1 is not as expected");
2672}
2673
2674void
2676{
2678 expected,
2679 "RX success bitmap for A-MPDU 2 is not as expected");
2680}
2681
2682void
2684{
2686 expected,
2687 "RX failure bitmap for A-MPDU 1 is not as expected");
2688}
2689
2690void
2692{
2694 expected,
2695 "RX failure bitmap for A-MPDU 2 is not as expected");
2696}
2697
2698void
2700{
2702 expected,
2703 "RX dropped bitmap for A-MPDU 1 is not as expected");
2704}
2705
2706void
2708{
2710 expected,
2711 "RX dropped bitmap for A-MPDU 2 is not as expected");
2712}
2713
2714void
2716{
2717 WifiPhyState currentState;
2718 PointerValue ptr;
2719 m_phy->GetAttribute("State", ptr);
2721 currentState = state->GetState();
2722 NS_TEST_ASSERT_MSG_EQ(currentState,
2723 expectedState,
2724 "PHY State " << currentState << " does not match expected state "
2725 << expectedState << " at " << Simulator::Now());
2726}
2727
2728void
2730{
2732 0,
2734 NanoSeconds(800),
2735 1,
2736 1,
2737 0,
2738 20,
2739 true);
2740
2741 WifiMacHeader hdr;
2743 hdr.SetQosTid(0);
2744
2745 std::vector<Ptr<WifiMpdu>> mpduList;
2746 for (size_t i = 0; i < 3; ++i)
2747 {
2748 Ptr<Packet> p = Create<Packet>(referencePacketSize + i * 100);
2749 mpduList.push_back(Create<WifiMpdu>(p, hdr));
2750 }
2751 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(mpduList);
2752
2753 Time txDuration = m_phy->CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
2754
2755 Ptr<WifiPpdu> ppdu =
2756 Create<HePpdu>(psdu, txVector, m_phy->GetOperatingChannel(), txDuration, m_uid++);
2757
2758 Ptr<SpectrumValue> txPowerSpectrum =
2761 DbmToW(rxPower),
2762 GUARD_WIDTH);
2763
2765 txParams->psd = txPowerSpectrum;
2766 txParams->txPhy = nullptr;
2767 txParams->duration = txDuration;
2768 txParams->ppdu = ppdu;
2769
2770 m_phy->StartRx(txParams, nullptr);
2771}
2772
2773void
2775{
2777
2778 m_phy->SetReceiveOkCallback(MakeCallback(&TestAmpduReception::RxSuccess, this));
2779 m_phy->SetReceiveErrorCallback(MakeCallback(&TestAmpduReception::RxFailure, this));
2780 m_phy->TraceConnectWithoutContext("PhyRxDrop",
2782
2783 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
2785 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(2));
2786 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
2787
2789 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
2790 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
2791 m_phy->SetFrameCaptureModel(frameCaptureModel);
2792}
2793
2794void
2796{
2799 int64_t streamNumber = 1;
2800 dBm_u rxPower = -30;
2801 m_phy->AssignStreams(streamNumber);
2802
2803 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2804 // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
2805 // power under RX sensitivity. The second A-MPDU is received 2 microseconds after the first
2806 // A-MPDU (i.e. during preamble detection).
2807 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2808
2809 // A-MPDU 1
2812 this,
2813 rxPower - 100,
2814 1000);
2815
2816 // A-MPDU 2
2819 this,
2820 rxPower,
2821 1300);
2822
2823 // All MPDUs of A-MPDU 1 should have been ignored.
2826 this,
2827 0b00000000);
2830 this,
2831 0b00000000);
2834 this,
2835 0b00000000);
2836
2837 // All MPDUs of A-MPDU 2 should have been successfully received.
2840 this,
2841 0b00000111);
2844 this,
2845 0b00000000);
2848 this,
2849 0b00000000);
2850
2852
2853 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2854 // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
2855 // with power under RX sensitivity. The second A-MPDU is received 2 microseconds after the first
2856 // A-MPDU (i.e. during preamble detection).
2857 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2858
2859 // A-MPDU 1
2862 this,
2863 rxPower,
2864 1000);
2865
2866 // A-MPDU 2
2869 this,
2870 rxPower - 100,
2871 1300);
2872
2873 // All MPDUs of A-MPDU 1 should have been received.
2876 this,
2877 0b00000111);
2880 this,
2881 0b00000000);
2884 this,
2885 0b00000000);
2886
2887 // All MPDUs of A-MPDU 2 should have been ignored.
2890 this,
2891 0b00000000);
2894 this,
2895 0b00000000);
2898 this,
2899 0b00000000);
2900
2902
2903 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2904 // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
2905 // power under RX sensitivity. The second A-MPDU is received 10 microseconds after the first
2906 // A-MPDU (i.e. during the frame capture window).
2907 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2908
2909 // A-MPDU 1
2912 this,
2913 rxPower - 100,
2914 1000);
2915
2916 // A-MPDU 2
2919 this,
2920 rxPower,
2921 1300);
2922
2923 // All MPDUs of A-MPDU 1 should have been ignored.
2926 this,
2927 0b00000000);
2930 this,
2931 0b00000000);
2934 this,
2935 0b00000000);
2936
2937 // All MPDUs of A-MPDU 2 should have been successfully received.
2940 this,
2941 0b00000111);
2944 this,
2945 0b00000000);
2948 this,
2949 0b00000000);
2950
2952
2953 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2954 // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
2955 // with power under RX sensitivity. The second A-MPDU is received 10 microseconds after the
2956 // first A-MPDU (i.e. during the frame capture window).
2957 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2958
2959 // A-MPDU 1
2962 this,
2963 rxPower,
2964 1000);
2965
2966 // A-MPDU 2
2969 this,
2970 rxPower - 100,
2971 1300);
2972
2973 // All MPDUs of A-MPDU 1 should have been received.
2976 this,
2977 0b00000111);
2980 this,
2981 0b00000000);
2984 this,
2985 0b00000000);
2986
2987 // All MPDUs of A-MPDU 2 should have been ignored.
2990 this,
2991 0b00000000);
2994 this,
2995 0b00000000);
2998 this,
2999 0b00000000);
3000
3002
3003 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3004 // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
3005 // power under RX sensitivity. The second A-MPDU is received 100 microseconds after the first
3006 // A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
3007 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3008
3009 // A-MPDU 1
3012 this,
3013 rxPower - 100,
3014 1000);
3015
3016 // A-MPDU 2
3019 this,
3020 rxPower,
3021 1300);
3022
3023 // All MPDUs of A-MPDU 1 should have been ignored.
3026 this,
3027 0b00000000);
3030 this,
3031 0b00000000);
3034 this,
3035 0b00000000);
3036
3037 // All MPDUs of A-MPDU 2 should have been successfully received.
3040 this,
3041 0b00000111);
3044 this,
3045 0b00000000);
3048 this,
3049 0b00000000);
3050
3052
3053 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3054 // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
3055 // with power under RX sensitivity. The second A-MPDU is received 100 microseconds after the
3056 // first A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
3057 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3058
3059 // A-MPDU 1
3062 this,
3063 rxPower,
3064 1000);
3065
3066 // A-MPDU 2
3069 this,
3070 rxPower - 100,
3071 1300);
3072
3073 // All MPDUs of A-MPDU 1 should have been received.
3076 this,
3077 0b00000111);
3080 this,
3081 0b00000000);
3084 this,
3085 0b00000000);
3086
3087 // All MPDUs of A-MPDU 2 should have been ignored.
3090 this,
3091 0b00000000);
3094 this,
3095 0b00000000);
3098 this,
3099 0b00000000);
3100
3102
3103 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3104 // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
3105 // power under RX sensitivity. The second A-MPDU is received during the payload of MPDU #2.
3106 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3107
3108 // A-MPDU 1
3111 this,
3112 rxPower - 100,
3113 1000);
3114
3115 // A-MPDU 2
3116 Simulator::Schedule(Seconds(7.0) + NanoSeconds(1100000),
3118 this,
3119 rxPower,
3120 1300);
3121
3122 // All MPDUs of A-MPDU 1 should have been ignored.
3125 this,
3126 0b00000000);
3129 this,
3130 0b00000000);
3133 this,
3134 0b00000000);
3135
3136 // All MPDUs of A-MPDU 2 should have been successfully received.
3139 this,
3140 0b00000111);
3143 this,
3144 0b00000000);
3147 this,
3148 0b00000000);
3149
3151
3152 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3153 // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
3154 // with power under RX sensitivity. The second A-MPDU is received during the payload of MPDU #2.
3155 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3156
3157 // A-MPDU 1
3160 this,
3161 rxPower,
3162 1000);
3163
3164 // A-MPDU 2
3165 Simulator::Schedule(Seconds(8.0) + NanoSeconds(1100000),
3167 this,
3168 rxPower - 100,
3169 1300);
3170
3171 // All MPDUs of A-MPDU 1 should have been received.
3174 this,
3175 0b00000111);
3178 this,
3179 0b00000000);
3182 this,
3183 0b00000000);
3184
3185 // All MPDUs of A-MPDU 2 should have been ignored.
3188 this,
3189 0b00000000);
3192 this,
3193 0b00000000);
3196 this,
3197 0b00000000);
3198
3200
3201 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3202 // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3
3203 // dB higher. The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during
3204 // preamble detection).
3205 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3206
3207 // A-MPDU 1
3210 this,
3211 rxPower,
3212 1000);
3213
3214 // A-MPDU 2
3217 this,
3218 rxPower + static_cast<dB_u>(3.0),
3219 1300);
3220
3221 // All MPDUs of A-MPDU 1 should have been dropped.
3224 this,
3225 0b00000000);
3228 this,
3229 0b00000000);
3232 this,
3233 0b00000111);
3234
3235 // All MPDUs of A-MPDU 2 should have been received with errors.
3238 this,
3239 0b00000000);
3242 this,
3243 0b00000111);
3246 this,
3247 0b00000000);
3248
3250
3251 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3252 // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3253 // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble
3254 // detection).
3255 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3256
3257 // A-MPDU 1
3260 this,
3261 rxPower,
3262 1000);
3263
3264 // A-MPDU 2
3267 this,
3268 rxPower,
3269 1300);
3270
3271 // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
3274 this,
3275 0b00000000);
3278 this,
3279 0b00000000);
3282 this,
3283 0b00000111);
3284
3285 // All MPDUs of A-MPDU 2 should have been dropped as well.
3288 this,
3289 0b00000000);
3292 this,
3293 0b00000000);
3296 this,
3297 0b00000111);
3298
3300
3301 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3302 // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3
3303 // dB higher. The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during
3304 // preamble detection).
3305 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3306
3307 // A-MPDU 1
3310 this,
3311 rxPower + static_cast<dB_u>(3.0),
3312 1000);
3313
3314 // A-MPDU 2
3317 this,
3318 rxPower,
3319 1300);
3320
3321 // All MPDUs of A-MPDU 1 should have been received with errors.
3324 this,
3325 0b00000000);
3328 this,
3329 0b00000111);
3332 this,
3333 0b00000000);
3334
3335 // All MPDUs of A-MPDU 2 should have been dropped.
3338 this,
3339 0b00000000);
3342 this,
3343 0b00000000);
3346 this,
3347 0b00000111);
3348
3350
3351 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3352 // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3353 // 3 dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e.
3354 // during the frame capture window).
3355 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3356
3357 // A-MPDU 1
3360 this,
3361 rxPower,
3362 1000);
3363
3364 // A-MPDU 2
3367 this,
3368 rxPower + static_cast<dB_u>(3.0),
3369 1300);
3370
3371 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and
3372 // thus incorrect decoding of payload).
3375 this,
3376 0b00000000);
3379 this,
3380 0b00000000);
3383 this,
3384 0b00000111);
3385
3386 // All MPDUs of A-MPDU 2 should have been dropped (even though TX power is higher, it is not
3387 // high enough to get the PHY reception switched)
3390 this,
3391 0b00000000);
3394 this,
3395 0b00000000);
3398 this,
3399 0b00000111);
3400
3402
3403 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3404 // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3405 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame
3406 // capture window).
3407 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3408
3409 // A-MPDU 1
3412 this,
3413 rxPower,
3414 1000);
3415
3416 // A-MPDU 2
3419 this,
3420 rxPower,
3421 1300);
3422
3423 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and
3424 // thus incorrect decoding of payload).
3427 this,
3428 0b00000000);
3431 this,
3432 0b00000000);
3435 this,
3436 0b00000111);
3437
3438 // All MPDUs of A-MPDU 2 should have been dropped as well.
3441 this,
3442 0b00000000);
3445 this,
3446 0b00000000);
3449 this,
3450 0b00000111);
3451
3453
3454 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3455 // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3
3456 // dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during
3457 // the frame capture window).
3458 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3459
3460 // A-MPDU 1
3463 this,
3464 rxPower + static_cast<dB_u>(3.0),
3465 1000);
3466
3467 // A-MPDU 2
3470 this,
3471 rxPower,
3472 1300);
3473
3474 // All MPDUs of A-MPDU 1 should have been received with errors.
3477 this,
3478 0b00000000);
3481 this,
3482 0b00000111);
3485 this,
3486 0b00000000);
3487
3488 // All MPDUs of A-MPDU 2 should have been dropped.
3491 this,
3492 0b00000000);
3495 this,
3496 0b00000000);
3499 this,
3500 0b00000111);
3501
3503
3504 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3505 // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3506 // 6 dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e.
3507 // during the frame capture window).
3508 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3509
3510 // A-MPDU 1
3513 this,
3514 rxPower,
3515 1000);
3516
3517 // A-MPDU 2
3520 this,
3521 rxPower + static_cast<dB_u>(6.0),
3522 1300);
3523
3524 // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
3527 this,
3528 0b00000000);
3531 this,
3532 0b00000000);
3535 this,
3536 0b00000111);
3537
3538 // All MPDUs of A-MPDU 2 should have been successfully received
3541 this,
3542 0b00000111);
3545 this,
3546 0b00000000);
3549 this,
3550 0b00000000);
3551
3553
3554 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3555 // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3556 // dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during
3557 // the frame capture window).
3558 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3559
3560 // A-MPDU 1
3563 this,
3564 rxPower + static_cast<dB_u>(6.0),
3565 1000);
3566
3567 // A-MPDU 2
3570 this,
3571 rxPower,
3572 1300);
3573
3574 // All MPDUs of A-MPDU 1 should have been successfully received.
3577 this,
3578 0b00000111);
3581 this,
3582 0b00000000);
3585 this,
3586 0b00000000);
3587
3588 // All MPDUs of A-MPDU 2 should have been dropped.
3591 this,
3592 0b00000000);
3595 this,
3596 0b00000000);
3599 this,
3600 0b00000111);
3601
3603
3604 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3605 // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3606 // 6 dB higher. The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after
3607 // the frame capture window, but still during PHY header).
3608 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3609
3610 // A-MPDU 1
3613 this,
3614 rxPower,
3615 1000);
3616
3617 // A-MPDU 2
3620 this,
3621 rxPower + static_cast<dB_u>(6.0),
3622 1300);
3623
3624 // All MPDUs of A-MPDU 1 should have been received with errors.
3627 this,
3628 0b00000000);
3631 this,
3632 0b00000000);
3635 this,
3636 0b00000111);
3637
3638 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because
3639 // PHY is already in RX state).
3642 this,
3643 0b00000000);
3646 this,
3647 0b00000000);
3650 this,
3651 0b00000111);
3652
3654
3655 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3656 // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3657 // dB higher. The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after
3658 // the frame capture window, but still during PHY header).
3659 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3660
3661 // A-MPDU 1
3664 this,
3665 rxPower + static_cast<dB_u>(6.0),
3666 1000);
3667
3668 // A-MPDU 2
3671 this,
3672 rxPower,
3673 1300);
3674
3675 // All MPDUs of A-MPDU 1 should have been successfully received.
3678 this,
3679 0b00000111);
3682 this,
3683 0b00000000);
3686 this,
3687 0b00000000);
3688
3689 // All MPDUs of A-MPDU 2 should have been dropped.
3692 this,
3693 0b00000000);
3696 this,
3697 0b00000000);
3700 this,
3701 0b00000111);
3702
3704
3705 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3706 // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3707 // The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after the frame
3708 // capture window, but still during PHY header).
3709 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3710
3711 // A-MPDU 1
3714 this,
3715 rxPower,
3716 1000);
3717
3718 // A-MPDU 2
3721 this,
3722 rxPower,
3723 1300);
3724
3725 // All MPDUs of A-MPDU 1 should have been received with errors.
3728 this,
3729 0b00000000);
3732 this,
3733 0b00000000);
3736 this,
3737 0b00000111);
3738
3739 // All MPDUs of A-MPDU 2 should have been dropped.
3742 this,
3743 0b00000000);
3746 this,
3747 0b00000000);
3750 this,
3751 0b00000111);
3752
3754
3755 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3756 // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3757 // 6 dB higher. The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e.
3758 // during the payload of MPDU #1).
3759 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3760
3761 // A-MPDU 1
3764 this,
3765 rxPower,
3766 1000);
3767
3768 // A-MPDU 2
3771 this,
3772 rxPower + static_cast<dB_u>(6.0),
3773 1300);
3774
3775 // All MPDUs of A-MPDU 1 should have been received with errors.
3778 this,
3779 0b00000000);
3782 this,
3783 0b00000111);
3786 this,
3787 0b00000000);
3788
3789 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because
3790 // PHY is already in RX state).
3793 this,
3794 0b00000000);
3797 this,
3798 0b00000000);
3801 this,
3802 0b00000111);
3803
3805
3806 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3807 // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3808 // dB higher. The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during
3809 // the payload of MPDU #1).
3810 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3811
3812 // A-MPDU 1
3815 this,
3816 rxPower + static_cast<dB_u>(6.0),
3817 1000);
3818
3819 // A-MPDU 2
3822 this,
3823 rxPower,
3824 1300);
3825
3826 // All MPDUs of A-MPDU 1 should have been successfully received.
3829 this,
3830 0b00000111);
3833 this,
3834 0b00000000);
3837 this,
3838 0b00000000);
3839
3840 // All MPDUs of A-MPDU 2 should have been dropped.
3843 this,
3844 0b00000000);
3847 this,
3848 0b00000000);
3851 this,
3852 0b00000111);
3853
3855
3856 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3857 // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3858 // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the
3859 // payload of MPDU #1).
3860 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3861
3862 // A-MPDU 1
3865 this,
3866 rxPower,
3867 1000);
3868
3869 // A-MPDU 2
3872 this,
3873 rxPower,
3874 1300);
3875
3876 // All MPDUs of A-MPDU 1 should have been received with errors.
3879 this,
3880 0b00000000);
3883 this,
3884 0b00000111);
3887 this,
3888 0b00000000);
3889
3890 // All MPDUs of A-MPDU 2 should have been dropped.
3893 this,
3894 0b00000000);
3897 this,
3898 0b00000000);
3901 this,
3902 0b00000111);
3903
3905
3906 ///////////////////////////////////////////////////////////////////////////////
3907 // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3908 // The second A-MPDU is received during the payload of MPDU #2.
3909 ///////////////////////////////////////////////////////////////////////////////
3910
3911 // A-MPDU 1
3914 this,
3915 rxPower,
3916 1000);
3917
3918 // A-MPDU 2
3919 Simulator::Schedule(Seconds(23.0) + NanoSeconds(1100000),
3921 this,
3922 rxPower,
3923 1300);
3924
3925 // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
3926 // The two other MPDUs failed due to interference and are marked as failure (and dropped).
3929 this,
3930 0b00000001);
3933 this,
3934 0b00000110);
3937 this,
3938 0b00000000);
3939
3940 // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving
3941 // A-MPDU 1). The last MPDU of A-MPDU 2 is interference free (A-MPDU 1 transmission is finished)
3942 // but is dropped because its PHY preamble and header were not received.
3945 this,
3946 0b00000000);
3949 this,
3950 0b00000000);
3953 this,
3954 0b00000111);
3955
3957
3960}
3961
3962/**
3963 * \ingroup wifi-test
3964 * \ingroup tests
3965 *
3966 * \brief Unsupported Modulation Reception Test
3967 * This test creates a mixed network, in which an HE STA and a VHT
3968 * STA are associated to an HE AP and send uplink traffic. In the
3969 * simulated deployment the VHT STA's backoff will expire while the
3970 * HE STA is sending a packet, and the VHT STA will access the
3971 * channel anyway. This happens because the HE STA is using an HeMcs
3972 * that the VHT STA is not able to demodulate: the VHT STA will
3973 * correctly stop listening to the HE packet, but it will not update
3974 * its InterferenceHelper with the HE packet. Later on, this leads to
3975 * the STA wrongly assuming the medium is available when its back-off
3976 * expires in the middle of the HE packet. We detect that this is
3977 * happening by looking at the reason why the AP is failing to decode
3978 * the preamble from the VHT STA's transmission: if the reason is
3979 * that it's in RX already, the test fails. The test is based on
3980 * wifi-txop-test.cc.
3981 */
3983{
3984 public:
3987
3988 private:
3989 void DoRun() override;
3990
3991 /**
3992 * Callback invoked when PHY drops an incoming packet
3993 * \param context the context
3994 * \param packet the packet that was dropped
3995 * \param reason the reason the packet was dropped
3996 */
3997 void Dropped(std::string context, Ptr<const Packet> packet, WifiPhyRxfailureReason reason);
3998 /**
3999 * Check correctness of transmitted frames
4000 */
4001 void CheckResults();
4002
4003 uint16_t m_dropped{0}; ///< number of packets dropped by the AP because it was already receiving
4004};
4005
4007 : TestCase("Check correct behavior when a STA is receiving a transmission using an unsupported "
4008 "modulation")
4009{
4010}
4011
4012void
4014 Ptr<const Packet> packet,
4016{
4017 // Print if the test is executed through test-runner
4018 if (reason == RXING)
4019 {
4020 std::cout << "Dropped a packet because already receiving" << std::endl;
4021 m_dropped++;
4022 }
4023}
4024
4025void
4027{
4028 uint16_t m_nStations = 2; ///< number of stations
4029 NetDeviceContainer m_staDevices; ///< container for stations' NetDevices
4030 NetDeviceContainer m_apDevices; ///< container for AP's NetDevice
4031
4032 int64_t streamNumber = 100;
4033
4034 NodeContainer wifiApNode;
4035 wifiApNode.Create(1);
4036
4037 NodeContainer wifiStaNodes;
4038 wifiStaNodes.Create(m_nStations);
4039
4042 spectrumChannel->AddPropagationLossModel(lossModel);
4045 spectrumChannel->SetPropagationDelayModel(delayModel);
4046
4048 phy.SetChannel(spectrumChannel);
4049
4050 Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue(65535));
4051
4052 WifiHelper wifi;
4053 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
4054
4055 WifiMacHelper mac;
4056 mac.SetType("ns3::StaWifiMac",
4057 "QosSupported",
4058 BooleanValue(true),
4059 "Ssid",
4060 SsidValue(Ssid("non-existent-ssid")));
4061
4062 wifi.SetStandard(WIFI_STANDARD_80211ax);
4063 m_staDevices.Add(wifi.Install(phy, mac, wifiStaNodes.Get(0)));
4064 wifi.SetStandard(WIFI_STANDARD_80211ac);
4065 m_staDevices.Add(wifi.Install(phy, mac, wifiStaNodes.Get(1)));
4066
4067 wifi.SetStandard(WIFI_STANDARD_80211ax);
4068 mac.SetType("ns3::ApWifiMac",
4069 "QosSupported",
4070 BooleanValue(true),
4071 "Ssid",
4072 SsidValue(Ssid("wifi-backoff-ssid")),
4073 "BeaconInterval",
4074 TimeValue(MicroSeconds(102400)),
4075 "EnableBeaconJitter",
4076 BooleanValue(false));
4077
4078 m_apDevices = wifi.Install(phy, mac, wifiApNode);
4079
4080 // schedule association requests at different times
4081 Time init = MilliSeconds(100);
4083
4084 for (uint16_t i = 0; i < m_nStations; i++)
4085 {
4086 dev = DynamicCast<WifiNetDevice>(m_staDevices.Get(i));
4087 Simulator::Schedule(init + i * MicroSeconds(102400),
4089 dev->GetMac(),
4090 Ssid("wifi-backoff-ssid"));
4091 }
4092
4093 // Assign fixed streams to random variables in use
4094 WifiHelper::AssignStreams(m_apDevices, streamNumber);
4095
4096 MobilityHelper mobility;
4098
4099 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
4100 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
4101 positionAlloc->Add(Vector(0.0, 1.0, 0.0));
4102 positionAlloc->Add(Vector(-1.0, 0.0, 0.0));
4103 mobility.SetPositionAllocator(positionAlloc);
4104
4105 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
4106 mobility.Install(wifiApNode);
4107 mobility.Install(wifiStaNodes);
4108
4109 // set the TXOP limit on BE AC
4110 dev = DynamicCast<WifiNetDevice>(m_apDevices.Get(0));
4111 PointerValue ptr;
4112 dev->GetMac()->GetAttribute("BE_Txop", ptr);
4113
4114 PacketSocketHelper packetSocket;
4115 packetSocket.Install(wifiApNode);
4116 packetSocket.Install(wifiStaNodes);
4117
4118 // UL Traffic
4119 for (uint16_t i = 0; i < m_nStations; i++)
4120 {
4121 PacketSocketAddress socket;
4122 socket.SetSingleDevice(m_staDevices.Get(0)->GetIfIndex());
4123 socket.SetPhysicalAddress(m_apDevices.Get(0)->GetAddress());
4124 socket.SetProtocol(1);
4126 client->SetAttribute("PacketSize", UintegerValue(1500));
4127 client->SetAttribute("MaxPackets", UintegerValue(200));
4128 client->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
4129 client->SetRemote(socket);
4130 wifiStaNodes.Get(i)->AddApplication(client);
4131 client->SetStartTime(MicroSeconds(400000));
4132 client->SetStopTime(Seconds(1.0));
4134 legacyStaClient->SetAttribute("PacketSize", UintegerValue(1500));
4135 legacyStaClient->SetAttribute("MaxPackets", UintegerValue(200));
4136 legacyStaClient->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
4137 legacyStaClient->SetRemote(socket);
4138 wifiStaNodes.Get(i)->AddApplication(legacyStaClient);
4139 legacyStaClient->SetStartTime(MicroSeconds(400000));
4140 legacyStaClient->SetStopTime(Seconds(1.0));
4142 server->SetLocal(socket);
4143 wifiApNode.Get(0)->AddApplication(server);
4144 server->SetStartTime(Seconds(0.0));
4145 server->SetStopTime(Seconds(1.0));
4146 }
4147
4148 // Trace dropped packets
4149 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
4151
4154
4155 CheckResults();
4156
4158}
4159
4160void
4162{
4163 NS_TEST_EXPECT_MSG_EQ(m_dropped, 0, "Dropped some packets unexpectedly");
4164}
4165
4166/**
4167 * \ingroup wifi-test
4168 * \ingroup tests
4169 *
4170 * \brief Unsupported Bandwidth Reception Test
4171 * This test checks whether a PHY receiving a PPDU sent over a channel width
4172 * larger than the one supported by the PHY is getting dropped at the expected
4173 * time. The expected time corresponds to the moment the PHY header indicating
4174 * the channel width used to transmit the PPDU is received. Since we are considering
4175 * 802.11ax for this test, this corresponds to the time HE-SIG-A is received.
4176 */
4178{
4179 public:
4181
4182 private:
4183 void DoSetup() override;
4184 void DoTeardown() override;
4185 void DoRun() override;
4186
4187 /**
4188 * Function to create a PPDU
4189 *
4190 * \param centerFreq the center frequency used for the transmission of the PPDU
4191 * \param bandwidth the bandwidth used for the transmission of the PPDU
4192 */
4193 void SendPpdu(MHz_u centerFreq, MHz_u bandwidth);
4194
4195 /**
4196 * Function called upon a PSDU received successfully
4197 * \param psdu the PSDU
4198 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
4199 * \param txVector the transmit vector
4200 * \param statusPerMpdu reception status per MPDU
4201 */
4203 RxSignalInfo rxSignalInfo,
4204 WifiTxVector txVector,
4205 std::vector<bool> statusPerMpdu);
4206
4207 /**
4208 * Function called upon a PSDU received unsuccessfuly
4209 * \param psdu the PSDU
4210 */
4211 void RxFailure(Ptr<const WifiPsdu> psdu);
4212
4213 /**
4214 * Function called upon a PSDU dropped by the PHY
4215 * \param packet the packet that was dropped
4216 * \param reason the reason the packet was dropped
4217 */
4219
4220 /**
4221 * Check the reception results
4222 * \param expectedCountRxSuccess the expected number of RX success
4223 * \param expectedCountRxFailure the expected number of RX failure
4224 * \param expectedCountRxDropped the expected number of RX drop
4225 * \param expectedLastRxSucceeded the expected time the last RX success occurred or std::nullopt
4226 * if the expected number of RX success is not strictly positive \param expectedLastRxFailed the
4227 * expected time the last RX failure occurred or std::nullopt if the expected number of RX
4228 * failure is not strictly positive \param expectedLastRxDropped the expected time the last RX
4229 * drop occurred or std::nullopt if the expected number of RX drop is not strictly positive
4230 */
4231 void CheckRx(uint32_t expectedCountRxSuccess,
4232 uint32_t expectedCountRxFailure,
4233 uint32_t expectedCountRxDropped,
4234 std::optional<Time> expectedLastRxSucceeded,
4235 std::optional<Time> expectedLastRxFailed,
4236 std::optional<Time> expectedLastRxDropped);
4237
4238 uint32_t m_countRxSuccess; ///< count RX success
4239 uint32_t m_countRxFailure; ///< count RX failure
4240 uint32_t m_countRxDropped; ///< count RX drop
4241
4242 std::optional<Time> m_lastRxSucceeded; ///< time of last RX success, if any
4243 std::optional<Time> m_lastRxFailed; ///< time of last RX failure, if any
4244 std::optional<Time> m_lastRxDropped; ///< time of last RX drop, if any
4245
4248};
4249
4251 : TestCase("Check correct behavior when a STA is receiving a transmission using an unsupported "
4252 "bandwidth"),
4253 m_countRxSuccess(0),
4254 m_countRxFailure(0),
4255 m_countRxDropped(0),
4256 m_lastRxSucceeded(std::nullopt),
4257 m_lastRxFailed(std::nullopt),
4258 m_lastRxDropped(std::nullopt)
4259{
4260}
4261
4262void
4264{
4265 auto txVector = WifiTxVector(HePhy::GetHeMcs0(),
4266 0,
4268 NanoSeconds(800),
4269 1,
4270 1,
4271 0,
4272 bandwidth,
4273 false);
4274
4275 auto pkt = Create<Packet>(1000);
4276 WifiMacHeader hdr;
4277
4279 hdr.SetQosTid(0);
4280
4281 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
4282 Time txDuration =
4283 m_rxPhy->CalculateTxDuration(psdu->GetSize(), txVector, m_rxPhy->GetPhyBand());
4284
4285 auto ppdu = Create<HePpdu>(psdu, txVector, m_txPhy->GetOperatingChannel(), txDuration, 0);
4286
4287 auto txPowerSpectrum = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity(centerFreq,
4288 bandwidth,
4289 DbmToW(-50),
4290 bandwidth);
4291
4292 auto txParams = Create<WifiSpectrumSignalParameters>();
4293 txParams->psd = txPowerSpectrum;
4294 txParams->txPhy = nullptr;
4295 txParams->duration = txDuration;
4296 txParams->ppdu = ppdu;
4297
4298 m_rxPhy->StartRx(txParams, nullptr);
4299}
4300
4301void
4303 RxSignalInfo rxSignalInfo,
4304 WifiTxVector txVector,
4305 std::vector<bool> statusPerMpdu)
4306{
4307 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
4310}
4311
4312void
4319
4320void
4328
4329void
4331 uint32_t expectedCountRxFailure,
4332 uint32_t expectedCountRxDropped,
4333 std::optional<Time> expectedLastRxSucceeded,
4334 std::optional<Time> expectedLastRxFailed,
4335 std::optional<Time> expectedLastRxDropped)
4336{
4338 expectedCountRxSuccess,
4339 "Didn't receive right number of successful packets");
4340
4342 expectedCountRxFailure,
4343 "Didn't receive right number of unsuccessful packets");
4344
4346 expectedCountRxDropped,
4347 "Didn't receive right number of dropped packets");
4348
4349 if (expectedCountRxSuccess > 0)
4350 {
4351 NS_ASSERT(m_lastRxSucceeded.has_value());
4352 NS_ASSERT(expectedLastRxSucceeded.has_value());
4354 expectedLastRxSucceeded.value(),
4355 "Didn't receive the last successful packet at the expected time");
4356 }
4357
4358 if (expectedCountRxFailure > 0)
4359 {
4360 NS_ASSERT(m_lastRxFailed.has_value());
4361 NS_ASSERT(expectedLastRxFailed.has_value());
4363 expectedLastRxFailed.value(),
4364 "Didn't receive the last unsuccessful packet at the expected time");
4365 }
4366
4367 if (expectedCountRxDropped > 0)
4368 {
4369 NS_ASSERT(m_lastRxDropped.has_value());
4370 NS_ASSERT(expectedLastRxDropped.has_value());
4372 expectedLastRxDropped.value(),
4373 "Didn't drop the last filtered packet at the expected time");
4374 }
4375}
4376
4377void
4379{
4384 auto rxInterferenceHelper = CreateObject<InterferenceHelper>();
4385 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
4386 auto rxErrorRateModel = CreateObject<NistErrorRateModel>();
4387 m_rxPhy->SetErrorRateModel(rxErrorRateModel);
4388 m_rxPhy->SetDevice(dev);
4389 m_rxPhy->AddChannel(spectrumChannel);
4390 m_rxPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4391 dev->SetPhy(m_rxPhy);
4392 node->AddDevice(dev);
4393
4394 m_rxPhy->SetReceiveOkCallback(
4396 m_rxPhy->SetReceiveErrorCallback(
4398 m_rxPhy->TraceConnectWithoutContext(
4399 "PhyRxDrop",
4401
4403 auto txInterferenceHelper = CreateObject<InterferenceHelper>();
4404 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
4405 auto txErrorRateModel = CreateObject<NistErrorRateModel>();
4406 m_txPhy->SetErrorRateModel(txErrorRateModel);
4407 m_txPhy->AddChannel(spectrumChannel);
4408 m_txPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4409}
4410
4411void
4413{
4414 m_rxPhy->Dispose();
4415 m_rxPhy = nullptr;
4416
4417 m_txPhy->Dispose();
4418 m_txPhy = nullptr;
4419}
4420
4421void
4423{
4426
4427 int64_t streamNumber = 0;
4428 m_rxPhy->AssignStreams(streamNumber);
4429
4430 // Case 1: the PHY is operating on channel 36 (20 MHz) and receives a 40 MHz PPDU (channel 38).
4431 // The PPDU should be dropped once HE-SIG-A is successfully received, since it contains
4432 // indication about the BW used for the transmission and the PHY shall detect it is larger than
4433 // its operating BW.
4434 m_txPhy->SetOperatingChannel(WifiPhy::ChannelTuple{38, 40, WIFI_PHY_BAND_5GHZ, 0});
4435 m_rxPhy->SetOperatingChannel(WifiPhy::ChannelTuple{36, 20, WIFI_PHY_BAND_5GHZ, 0});
4436
4438
4439 auto heSigAExpectedRxTime = Seconds(1.0) + MicroSeconds(32);
4442 this,
4443 0,
4444 0,
4445 1,
4446 std::nullopt,
4447 std::nullopt,
4448 heSigAExpectedRxTime);
4449
4450 // TODO: this test can be extended with other scenarios
4451
4454}
4455
4456/**
4457 * \ingroup wifi-test
4458 * \ingroup tests
4459 *
4460 * \brief Primary 20 MHz Covered By Ppdu Test
4461 * This test checks whether the functions WifiPpdu::DoesOverlapChannel and
4462 * WifiPpdu::DoesCoverChannel are returning the expected results.
4463 */
4465{
4466 public:
4468
4469 private:
4470 void DoSetup() override;
4471 void DoRun() override;
4472 void DoTeardown() override;
4473
4474 /**
4475 * Function to create a PPDU
4476 *
4477 * \param ppduCenterFreq the center frequency used for the transmission of the PPDU
4478 * \return the created PPDU
4479 */
4480 Ptr<HePpdu> CreatePpdu(MHz_u ppduCenterFreq);
4481
4482 /**
4483 * Run one function
4484 *
4485 * \param band the PHY band to use
4486 * \param phyCenterFreq the operating center frequency of the PHY
4487 * \param p20Index the primary20 index
4488 * \param ppduCenterFreq the center frequency used for the transmission of the PPDU
4489 * \param expectedP20Overlap flag whether the primary 20 MHz channel is expected to be fully
4490 * covered by the bandwidth of the incoming PPDU
4491 * \param expectedP20Covered flag whether the
4492 * primary 20 MHz channel is expected to overlap with the bandwidth of the incoming PPDU
4493 */
4494 void RunOne(WifiPhyBand band,
4495 MHz_u phyCenterFreq,
4496 uint8_t p20Index,
4497 MHz_u ppduCenterFreq,
4498 bool expectedP20Overlap,
4499 bool expectedP20Covered);
4500
4503};
4504
4506 : TestCase("Check correct detection of whether P20 is fully covered (hence it can be received) "
4507 "or overlaps with the bandwidth of an incoming PPDU")
4508{
4509}
4510
4513{
4514 const auto& channelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
4515 ppduCenterFreq,
4516 0,
4518 m_rxPhy->GetPhyBand()));
4519 m_txPhy->SetOperatingChannel(
4520 WifiPhy::ChannelTuple{channelInfo.number, channelInfo.width, channelInfo.band, 0});
4521 auto txVector = WifiTxVector(HePhy::GetHeMcs7(),
4522 0,
4524 NanoSeconds(800),
4525 1,
4526 1,
4527 0,
4528 channelInfo.width,
4529 false);
4530
4531 auto pkt = Create<Packet>(1000);
4533
4534 auto psdu = Create<WifiPsdu>(pkt, hdr);
4535 auto txDuration = m_txPhy->CalculateTxDuration(psdu->GetSize(), txVector, channelInfo.band);
4536
4537 return Create<HePpdu>(psdu, txVector, m_txPhy->GetOperatingChannel(), txDuration, 0);
4538}
4539
4540void
4542{
4544 auto rxInterferenceHelper = CreateObject<InterferenceHelper>();
4545 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
4546 auto rxErrorRateModel = CreateObject<NistErrorRateModel>();
4547 m_rxPhy->SetErrorRateModel(rxErrorRateModel);
4549 m_rxPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4550
4552 auto txInterferenceHelper = CreateObject<InterferenceHelper>();
4553 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
4554 auto txErrorRateModel = CreateObject<NistErrorRateModel>();
4555 m_txPhy->SetErrorRateModel(txErrorRateModel);
4557 m_txPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4558}
4559
4560void
4562{
4563 m_rxPhy->Dispose();
4564 m_rxPhy = nullptr;
4565 m_txPhy->Dispose();
4566 m_txPhy = nullptr;
4567}
4568
4569void
4571 MHz_u phyCenterFreq,
4572 uint8_t p20Index,
4573 MHz_u ppduCenterFreq,
4574 bool expectedP20Overlap,
4575 bool expectedP20Covered)
4576{
4577 const auto& channelInfo =
4578 (*WifiPhyOperatingChannel::FindFirst(0, phyCenterFreq, 0, WIFI_STANDARD_80211ax, band));
4579
4580 m_rxPhy->SetOperatingChannel(
4581 WifiPhy::ChannelTuple{channelInfo.number, channelInfo.width, channelInfo.band, p20Index});
4582 auto p20CenterFreq = m_rxPhy->GetOperatingChannel().GetPrimaryChannelCenterFrequency(20);
4583 auto p20MinFreq = p20CenterFreq - 10;
4584 auto p20MaxFreq = p20CenterFreq + 10;
4585
4586 auto ppdu = CreatePpdu(ppduCenterFreq);
4587
4588 auto p20Overlap = ppdu->DoesOverlapChannel(p20MinFreq, p20MaxFreq);
4589 NS_TEST_ASSERT_MSG_EQ(p20Overlap,
4590 expectedP20Overlap,
4591 "PPDU is " << (expectedP20Overlap ? "expected" : "not expected")
4592 << " to overlap with the P20");
4593
4594 auto p20Covered = m_rxPhy->GetPhyEntity(WIFI_STANDARD_80211ax)
4595 ->CanStartRx(ppdu); // CanStartRx returns true is the P20 is fully covered
4596 NS_TEST_ASSERT_MSG_EQ(p20Covered,
4597 expectedP20Covered,
4598 "PPDU is " << (expectedP20Covered ? "expected" : "not expected")
4599 << " to cover the whole P20");
4600}
4601
4602void
4604{
4605 /*
4606 * Receiver PHY Operating Channel: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4607 * Transmitted 20 MHz PPDU: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4608 * Overlap with primary 20 MHz: yes
4609 * Primary 20 MHz fully covered: yes
4610 */
4611 RunOne(WIFI_PHY_BAND_2_4GHZ, 2427, 0, 2427, true, true);
4612
4613 /*
4614 * Receiver PHY Operating Channel: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4615 * Transmitted 20 MHz PPDU: 2.4 GHz Channel 6 (2427 MHz – 2447 MHz)
4616 * Overlap with primary 20 MHz: yes
4617 * Primary 20 MHz fully covered: no
4618 */
4619 RunOne(WIFI_PHY_BAND_2_4GHZ, 2427, 0, 2437, true, false);
4620
4621 /*
4622 * Receiver PHY Operating Channel: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4623 * Transmitted 40 MHz PPDU: 5 GHz Channel 38 (5170 MHz – 5210 MHz)
4624 * Overlap with primary 20 MHz: yes
4625 * Primary 20 MHz fully covered: yes
4626 */
4627 RunOne(WIFI_PHY_BAND_5GHZ, 5180, 0, 5190, true, true);
4628
4629 /*
4630 * Receiver PHY Operating Channel: 5 GHz Channel 36 (5170 MHz–5190 MHz)
4631 * Transmitted 20 MHz PPDU: 5 GHz Channel 40 (5190 MHz – 5210 MHz)
4632 * Overlap with primary 20 MHz: no
4633 * Primary 20 MHz fully covered: no
4634 */
4635 RunOne(WIFI_PHY_BAND_5GHZ, 5180, 0, 5200, false, false);
4636
4637 /*
4638 * Receiver PHY Operating Channel: 5 GHz Channel 38 (5170 MHz – 5210 MHz) with P20 index 0
4639 * Transmitted 20 MHz PPDU: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4640 * Overlap with primary 20 MHz: yes
4641 * Primary 20 MHz fully covered: yes
4642 */
4643 RunOne(WIFI_PHY_BAND_5GHZ, 5190, 0, 5180, true, true);
4644
4645 /*
4646 * Receiver PHY Operating Channel: 5 GHz Channel 38 (5170 MHz – 5210 MHz) with P20 index 1
4647 * Transmitted 20 MHz PPDU: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4648 * Overlap with primary 20 MHz: no
4649 * Primary 20 MHz fully covered: no
4650 */
4651 RunOne(WIFI_PHY_BAND_5GHZ, 5190, 1, 5180, false, false);
4652
4654}
4655
4656/**
4657 * \ingroup wifi-test
4658 * \ingroup tests
4659 *
4660 * \brief This test verifies the correct function of the WifiBandwidthFilter. 2 SpectrumWifiPhy are
4661 * setup and connected on the same spectrum channel. The test will
4662 * send a packet over the channel and if the signal plus guardband overlaps the channel the
4663 * filter will not discard the signal but if there is no overlap the filter will filter it out.
4664 */
4666{
4667 public:
4668 /**
4669 * Constructor
4670 *
4671 * \param channel channel to be used by transmitter
4672 * \param expectedValue expected number of received packets
4673 */
4674 TestSpectrumChannelWithBandwidthFilter(uint8_t channel, uint16_t expectedValue);
4675
4676 protected:
4677 void DoSetup() override;
4678 void DoTeardown() override;
4679
4680 private:
4681 /**
4682 * Callback invoked when the PHY model starts to process a signal
4683 *
4684 * \param signal the arriving signal
4685 * \param senderNodeId node Id of the sender of the signal
4686 * \param rxPower received signal power
4687 * \param duration signal duration
4688 */
4690 uint32_t senderNodeId,
4691 double rxPower,
4692 Time duration);
4693
4694 /**
4695 * Send function (sends a single packet)
4696 */
4697 void Send() const;
4698
4699 /**
4700 * Event scheduled at end of simulation for validation
4701 *
4702 * \param expectedValue expected number of receive events
4703 */
4704 void CheckRxPacketCount(uint16_t expectedValue);
4705
4706 void DoRun() override;
4707
4708 Ptr<SpectrumWifiPhy> m_tx{nullptr}; ///< transmit function
4709 Ptr<SpectrumWifiPhy> m_rx{nullptr}; ///< receive function
4710 uint32_t m_countRxBegin{0}; ///< count of receive events
4711 uint8_t m_channel{36}; ///< channel for packet transmission
4712 uint16_t m_expectedValue{0}; ///< expected count of receive events
4713};
4714
4716 uint8_t channel,
4717 uint16_t expectedValue)
4718 : TestCase("Test for early discard of signal in single-model-spectrum-channel::StartTx()"),
4719 m_channel(channel),
4720 m_expectedValue(expectedValue)
4721{
4722}
4723
4724void
4726{
4728 0,
4730 NanoSeconds(800),
4731 1,
4732 1,
4733 0,
4734 20,
4735 false);
4736
4737 Ptr<Packet> pkt = Create<Packet>(1000);
4738 WifiMacHeader hdr;
4739
4741 hdr.SetQosTid(0);
4742
4743 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
4744 m_tx->Send(psdu, txVector);
4745}
4746
4747void
4749{
4751 expectedValue,
4752 "Received a different amount of packets than expected.");
4753}
4754
4755void
4757 [[maybe_unused]],
4758 uint32_t senderNodeId [[maybe_unused]],
4759 double rxPower [[maybe_unused]],
4760 Time duration [[maybe_unused]])
4761{
4762 NS_LOG_FUNCTION(this << signal << senderNodeId << rxPower << duration);
4764}
4765
4766void
4768{
4769 NS_LOG_FUNCTION(this);
4771
4773 channel->AddSpectrumTransmitFilter(wifiFilter);
4774
4778 m_tx->SetDevice(dev);
4779 m_tx->SetTxPowerStart(20);
4780 m_tx->SetTxPowerEnd(20);
4781
4782 Ptr<Node> nodeRx = CreateObject<Node>();
4785 m_rx->SetDevice(devRx);
4786
4788 m_tx->SetInterferenceHelper(interferenceTx);
4790 m_tx->SetErrorRateModel(errorTx);
4791
4793 m_rx->SetInterferenceHelper(interferenceRx);
4795 m_rx->SetErrorRateModel(errorRx);
4796
4797 m_tx->AddChannel(channel);
4798 m_rx->AddChannel(channel);
4799
4800 m_tx->ConfigureStandard(WIFI_STANDARD_80211ax);
4801 m_rx->ConfigureStandard(WIFI_STANDARD_80211ax);
4802
4803 dev->SetPhy(m_tx);
4804 node->AddDevice(dev);
4805 devRx->SetPhy(m_rx);
4806 nodeRx->AddDevice(devRx);
4807
4808 m_rx->TraceConnectWithoutContext(
4809 "SignalArrival",
4811}
4812
4813void
4815{
4816 m_tx->Dispose();
4817 m_rx->Dispose();
4818}
4819
4820void
4836
4837/**
4838 * \ingroup wifi-test
4839 * \ingroup tests
4840 *
4841 * \brief This test verifies that the WifiPhyRxfailureReason distinguishes between two cases: 1) a
4842 * drop due to transmitting during the signal detection interval, and 2) a drop due to transmitting
4843 * after the receiver has detected a preamble but is waiting for the end of the preamble. 2
4844 * SpectrumWifiPhy are setup and connected on the same spectrum channel. The test will send a packet
4845 * over the channel and after a controlled amount of transmit delay (to check both cases) the
4846 * receiver of the packet will send its own packet. If delay is less than preamble detection period,
4847 * the signal detection should be aborted by transmission. If delay is greater than preamble
4848 * detection period, the signal reception should be aborted by transmission.
4849 */
4851{
4852 public:
4853 /**
4854 * Constructor
4855 *
4856 * \param delay delay in microseconds to send second packet
4857 * \param expectedReason expected failure reason
4858 */
4859 TestPhyDropDueToTx(Time delay, WifiPhyRxfailureReason expectedReason);
4860
4861 protected:
4862 void DoSetup() override;
4863 void DoTeardown() override;
4864
4865 private:
4866 /**
4867 * RX dropped function
4868 * \param p the packet
4869 * \param reason the reason
4870 */
4872
4873 /**
4874 * Send function (sends a single packet)
4875 * \param phy the WifiPhy object to send the packet
4876 */
4877 void Send(Ptr<WifiPhy> phy) const;
4878
4879 /**
4880 * Event scheduled at end of simulation for validation
4881 */
4882 void CheckDropReason();
4883
4884 void DoRun() override;
4885
4886 Ptr<SpectrumWifiPhy> m_phyA{nullptr}; ///< transmit function
4887 Ptr<SpectrumWifiPhy> m_phyB{nullptr}; ///< transmit/receive function
4888
4889 Time m_delay; ///< delay between transmissions in MicroSeconds
4890
4891 WifiPhyRxfailureReason m_expectedReason; ///< expected WifiPhyRxfailureReason
4892 WifiPhyRxfailureReason m_observedReason; ///< observed WifiPhyRxfailureReason
4893};
4894
4896 : TestCase("Test for correct WifiPhyRxfailureReason from PhyRxDrop trace"),
4897 m_delay(delay),
4898 m_expectedReason(expectedReason)
4899{
4900}
4901
4902void
4904{
4905 const auto txVector = WifiTxVector(HePhy::GetHeMcs0(),
4906 0,
4908 NanoSeconds(800),
4909 1,
4910 1,
4911 0,
4912 20,
4913 false);
4914
4915 auto pkt = Create<Packet>(1000);
4916 WifiMacHeader hdr;
4917
4919 hdr.SetQosTid(0);
4920
4921 auto psdu = Create<WifiPsdu>(pkt, hdr);
4922 phy->Send(psdu, txVector);
4923}
4924
4925void
4927{
4930 "Packet was dropped due to the wrong drop reason reported ");
4931}
4932
4933void
4939
4940void
4942{
4943 NS_LOG_FUNCTION(this);
4945
4946 auto node = CreateObject<Node>();
4947 auto devA = CreateObject<WifiNetDevice>();
4949 m_phyA->SetDevice(devA);
4950 m_phyA->SetTxPowerStart(20);
4951 m_phyA->SetTxPowerEnd(20);
4952
4953 auto nodeRx = CreateObject<Node>();
4954 auto devB = CreateObject<WifiNetDevice>();
4956 m_phyB->SetDevice(devB);
4957 m_phyB->SetTxPowerStart(20);
4958 m_phyB->SetTxPowerEnd(20);
4959
4960 auto interferenceTx = CreateObject<InterferenceHelper>();
4961 m_phyA->SetInterferenceHelper(interferenceTx);
4962 auto errorTx = CreateObject<NistErrorRateModel>();
4963 m_phyA->SetErrorRateModel(errorTx);
4964
4965 auto interferenceRx = CreateObject<InterferenceHelper>();
4966 m_phyB->SetInterferenceHelper(interferenceRx);
4967 auto errorRx = CreateObject<NistErrorRateModel>();
4968 m_phyB->SetErrorRateModel(errorRx);
4969
4970 m_phyA->AddChannel(channel);
4971 m_phyB->AddChannel(channel);
4972
4973 m_phyA->ConfigureStandard(WIFI_STANDARD_80211ax);
4974 m_phyA->SetOperatingChannel(WifiPhy::ChannelTuple{36, 0, WIFI_PHY_BAND_5GHZ, 0});
4975
4976 m_phyB->ConfigureStandard(WIFI_STANDARD_80211ax);
4977 m_phyB->SetOperatingChannel(WifiPhy::ChannelTuple{36, 0, WIFI_PHY_BAND_5GHZ, 0});
4978
4979 devA->SetPhy(m_phyA);
4980 node->AddDevice(devA);
4981 devB->SetPhy(m_phyB);
4982 nodeRx->AddDevice(devB);
4983
4984 m_phyB->TraceConnectWithoutContext("PhyRxDrop",
4986}
4987
4988void
4990{
4991 m_phyA->Dispose();
4992 m_phyB->Dispose();
4993}
4994
4995void
4997{
4998 NS_LOG_FUNCTION(this);
4999
5002
5003 // Upon transmitting the second packet from m_phyB, the reception from
5004 // m_phyA will be immediately dropped. Check the drop reason a short
5005 // while later (1 ns is sufficient)
5007
5010}
5011
5012/**
5013 * \ingroup wifi-test
5014 * \ingroup tests
5015 *
5016 * \brief wifi PHY reception Test Suite
5017 */
5019{
5020 public:
5022};
5023
5025 : TestSuite("wifi-phy-reception", Type::UNIT)
5026{
5027 AddTestCase(new TestThresholdPreambleDetectionWithoutFrameCapture, TestCase::Duration::QUICK);
5028 AddTestCase(new TestThresholdPreambleDetectionWithFrameCapture, TestCase::Duration::QUICK);
5029 AddTestCase(new TestSimpleFrameCaptureModel, TestCase::Duration::QUICK);
5030 AddTestCase(new TestPhyHeadersReception, TestCase::Duration::QUICK);
5031 AddTestCase(new TestAmpduReception, TestCase::Duration::QUICK);
5032 AddTestCase(new TestUnsupportedModulationReception(), TestCase::Duration::QUICK);
5033 AddTestCase(new TestUnsupportedBandwidthReception(), TestCase::Duration::QUICK);
5034 AddTestCase(new TestPrimary20CoveredByPpdu(), TestCase::Duration::QUICK);
5035 // The below three test cases are related. The test involves a receiver tuned to
5036 // channel 36 and a transmitter sending on channels 36, 40, and 44, respectively.
5037 // The second argument corresponds to the number of signals expected to be received.
5038 // Signals on channel 36 and 40 will fall within the receiver bandwidth, while
5039 // a signal on channel 44 will fall completely outside and will be filtered.
5040 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(36, 1), TestCase::Duration::QUICK);
5041 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(40, 1), TestCase::Duration::QUICK);
5042 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(44, 0), TestCase::Duration::QUICK);
5043 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(36, 1), TestCase::Duration::QUICK);
5044 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(40, 1), TestCase::Duration::QUICK);
5045 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(44, 0), TestCase::Duration::QUICK);
5046 // 4 Microseconds is just less than the preamble detection period since there is no
5047 // propagation delay model
5049 TestCase::Duration::QUICK);
5051 TestCase::Duration::QUICK);
5052}
5053
A-MPDU reception test.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
RX success function.
void IncrementSuccessBitmap(uint32_t size)
Increment reception success bitmap.
uint8_t m_rxDroppedBitmapAmpdu2
bitmap of dropped MPDUs in A-MPDU #2
void CheckRxSuccessBitmapAmpdu2(uint8_t expected)
Check the RX success bitmap for A-MPDU 2.
void DoRun() override
Implementation to actually run this TestCase.
void CheckRxDroppedBitmapAmpdu1(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 1.
uint8_t m_rxSuccessBitmapAmpdu1
bitmap of successfully received MPDUs in A-MPDU #1
uint8_t m_rxFailureBitmapAmpdu1
bitmap of unsuccessfully received MPDUs in A-MPDU #1
uint8_t m_rxFailureBitmapAmpdu2
bitmap of unsuccessfully received MPDUs in A-MPDU #2
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void SendAmpduWithThreeMpdus(dBm_u rxPower, uint32_t referencePacketSize)
Send A-MPDU with 3 MPDUs of different size (i-th MSDU will have 100 bytes more than (i-1)-th).
void RxFailure(Ptr< const WifiPsdu > psdu)
RX failure function.
void CheckRxFailureBitmapAmpdu2(uint8_t expected)
Check the RX failure bitmap for A-MPDU 2.
uint8_t m_rxDroppedBitmapAmpdu1
bitmap of dropped MPDUs in A-MPDU #1
void IncrementFailureBitmap(uint32_t size)
Increment reception failure bitmap.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void ResetBitmaps()
Reset bitmaps function.
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
void CheckRxSuccessBitmapAmpdu1(uint8_t expected)
Check the RX success bitmap for A-MPDU 1.
void CheckRxFailureBitmapAmpdu1(uint8_t expected)
Check the RX failure bitmap for A-MPDU 1.
uint8_t m_rxSuccessBitmapAmpdu2
bitmap of successfully received MPDUs in A-MPDU #2
void CheckRxDroppedBitmapAmpdu2(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 2.
This test verifies that the WifiPhyRxfailureReason distinguishes between two cases: 1) a drop due to ...
WifiPhyRxfailureReason m_expectedReason
expected WifiPhyRxfailureReason
void PhyDropTraceSink(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void DoRun() override
Implementation to actually run this TestCase.
WifiPhyRxfailureReason m_observedReason
observed WifiPhyRxfailureReason
void CheckDropReason()
Event scheduled at end of simulation for validation.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Time m_delay
delay between transmissions in MicroSeconds
Ptr< SpectrumWifiPhy > m_phyA
transmit function
void DoSetup() override
Implementation to do any local setup required for this TestCase.
Ptr< SpectrumWifiPhy > m_phyB
transmit/receive function
TestPhyDropDueToTx(Time delay, WifiPhyRxfailureReason expectedReason)
Constructor.
void Send(Ptr< WifiPhy > phy) const
Send function (sends a single packet)
Test PHY state upon success or failure of L-SIG and SIG-A.
void DoRun() override
Implementation to actually run this TestCase.
Primary 20 MHz Covered By Ppdu Test This test checks whether the functions WifiPpdu::DoesOverlapChann...
Ptr< SpectrumWifiPhy > m_rxPhy
RX PHY.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void RunOne(WifiPhyBand band, MHz_u phyCenterFreq, uint8_t p20Index, MHz_u ppduCenterFreq, bool expectedP20Overlap, bool expectedP20Covered)
Run one function.
Ptr< HePpdu > CreatePpdu(MHz_u ppduCenterFreq)
Function to create a PPDU.
void DoRun() override
Implementation to actually run this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Ptr< SpectrumWifiPhy > m_txPhy
TX PHY.
Simple frame capture model test.
void Expect1000BPacketReceived()
Verify whether 1000 bytes packet has been received.
bool m_rxDropped1500B
count dropped packets with 1500B payload
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void Expect1500BPacketDropped()
Verify whether 1500 bytes packet has been dropped.
void Expect1000BPacketDropped()
Verify whether 1000 bytes packet has been dropped.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void DoRun() override
Implementation to actually run this TestCase.
bool m_rxSuccess1000B
count received packets with 1000B payload
bool m_rxSuccess1500B
count received packets with 1500B payload
void Expect1500BPacketReceived()
Verify whether 1500 bytes packet has been received.
bool m_rxDropped1000B
count dropped packets with 1000B payload
This test verifies the correct function of the WifiBandwidthFilter.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
uint8_t m_channel
channel for packet transmission
uint16_t m_expectedValue
expected count of receive events
void Send() const
Send function (sends a single packet)
Ptr< SpectrumWifiPhy > m_tx
transmit function
Ptr< SpectrumWifiPhy > m_rx
receive function
void DoRun() override
Implementation to actually run this TestCase.
void CheckRxPacketCount(uint16_t expectedValue)
Event scheduled at end of simulation for validation.
void RxBegin(Ptr< const SpectrumSignalParameters > signal, uint32_t senderNodeId, double rxPower, Time duration)
Callback invoked when the PHY model starts to process a signal.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
TestSpectrumChannelWithBandwidthFilter(uint8_t channel, uint16_t expectedValue)
Constructor.
uint32_t m_countRxBegin
count of receive events
Preamble detection test w/o frame capture.
void RxFailure(Ptr< const WifiPsdu > psdu)
Spectrum wifi receive failure function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void DoRun() override
Implementation to actually run this TestCase.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
Preamble detection test w/o frame capture.
void DoRun() override
Implementation to actually run this TestCase.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void RxFailure(Ptr< const WifiPsdu > psdu)
Spectrum wifi receive failure function.
Unsupported Bandwidth Reception Test This test checks whether a PHY receiving a PPDU sent over a chan...
void DoSetup() override
Implementation to do any local setup required for this TestCase.
std::optional< Time > m_lastRxDropped
time of last RX drop, if any
std::optional< Time > m_lastRxSucceeded
time of last RX success, if any
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void CheckRx(uint32_t expectedCountRxSuccess, uint32_t expectedCountRxFailure, uint32_t expectedCountRxDropped, std::optional< Time > expectedLastRxSucceeded, std::optional< Time > expectedLastRxFailed, std::optional< Time > expectedLastRxDropped)
Check the reception results.
void RxFailure(Ptr< const WifiPsdu > psdu)
Function called upon a PSDU received unsuccessfuly.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Function called upon a PSDU received successfully.
void DoRun() override
Implementation to actually run this TestCase.
std::optional< Time > m_lastRxFailed
time of last RX failure, if any
void SendPpdu(MHz_u centerFreq, MHz_u bandwidth)
Function to create a PPDU.
void RxDropped(Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Function called upon a PSDU dropped by the PHY.
Unsupported Modulation Reception Test This test creates a mixed network, in which an HE STA and a VHT...
void DoRun() override
Implementation to actually run this TestCase.
void CheckResults()
Check correctness of transmitted frames.
void Dropped(std::string context, Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Callback invoked when PHY drops an incoming packet.
~TestUnsupportedModulationReception() override=default
uint16_t m_dropped
number of packets dropped by the AP because it was already receiving
Wifi Phy Reception Test base class.
WifiPhyReceptionTest(std::string test_name)
Constructor.
void SendPacket(dBm_u rxPower, uint32_t packetSize, uint8_t mcs)
Send packet function.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
~WifiPhyReceptionTest() override=default
Destructor.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
uint64_t m_uid
the UID to use for the PPDU
Ptr< SpectrumWifiPhy > m_phy
the PHY
void DoSetup() override
Implementation to do any local setup required for this TestCase.
wifi PHY reception Test Suite
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition he-phy.cc:1573
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
static WifiMode GetHeMcs7()
Return MCS 7 from HE MCS values.
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
AttributeValue implementation for Pointer.
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
static int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the PHY and MAC aspects ...
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.
create MAC layers for a ns3::WifiNetDevice.
void SetSsid(Ssid ssid)
Definition wifi-mac.cc:512
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:919
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first frequency segment matching the specified parameters.
This objects implements the PHY state machine of the Wifi device.
static Ptr< SpectrumValue > CreateHeOfdmTxPowerSpectralDensity(MHz_u centerFrequency, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=-20, dBr_u minOuterband=-28, dBr_u lowestPoint=-40, const std::vector< bool > &puncturedSubchannels={})
Create a transmit power spectral density corresponding to OFDM High Efficiency (HE) (802....
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:967
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:241
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPhyBand
Identifies the PHY band.
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ UNSUPPORTED_SETTINGS
@ SIGNAL_DETECTION_ABORTED_BY_TX
@ RECEPTION_ABORTED_BY_TX
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyState
The state of the PHY layer.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
@ WIFI_MAC_QOSDATA
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:31
STL namespace.
RxSignalInfo structure containing info on the received signal.
Definition wifi-types.h:72
static const uint8_t CHANNEL_NUMBER
static const MHz_u FREQUENCY
static WifiPhyReceptionTestSuite wifiPhyReceptionTestSuite
the test suite
static const MHz_u GUARD_WIDTH
static const MHz_u CHANNEL_WIDTH
static const uint32_t packetSize
Packet size generated at the AP.