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-ns3-constants.h"
39#include "ns3/wifi-psdu.h"
40#include "ns3/wifi-spectrum-phy-interface.h"
41#include "ns3/wifi-spectrum-signal-parameters.h"
42#include "ns3/wifi-spectrum-value-helper.h"
43#include "ns3/wifi-utils.h"
44
45#include <optional>
46
47using namespace ns3;
48
49NS_LOG_COMPONENT_DEFINE("WifiPhyReceptionTest");
50
51static const uint8_t CHANNEL_NUMBER = 36;
52static const MHz_u FREQUENCY{5180};
53static const MHz_u CHANNEL_WIDTH{20};
54static const MHz_u GUARD_WIDTH = CHANNEL_WIDTH; // expanded to channel width to model spectrum mask
55
56/**
57 * @ingroup wifi-test
58 * @ingroup tests
59 *
60 * @brief Wifi Phy Reception Test base class
61 */
63{
64 public:
65 /**
66 * Constructor
67 *
68 * @param test_name the test name
69 */
70 WifiPhyReceptionTest(std::string test_name);
71 /**
72 * Destructor
73 */
74 ~WifiPhyReceptionTest() override = default;
75
76 protected:
77 void DoSetup() override;
78 void DoTeardown() override;
79
80 /**
81 * Send packet function
82 * @param rxPower the transmit power
83 * @param packetSize the size of the packet in bytes
84 * @param mcs the MCS to transmit the packet
85 */
86 void SendPacket(dBm_u rxPower, uint32_t packetSize, uint8_t mcs);
87
88 /**
89 * Schedule now to check the PHY state
90 * @param expectedState the expected PHY state
91 */
92 void CheckPhyState(WifiPhyState expectedState);
93 /**
94 * Check the PHY state now
95 * @param expectedState the expected PHY state
96 */
97 void DoCheckPhyState(WifiPhyState expectedState);
98
100 uint64_t m_uid{0}; //!< the UID to use for the PPDU
101};
102
104 : TestCase{test_name}
105{
106}
107
108void
110{
114 NanoSeconds(800),
115 1,
116 1,
117 0,
118 MHz_u{20},
119 false);
120
122 WifiMacHeader hdr;
123
125 hdr.SetQosTid(0);
126
127 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
128 Time txDuration =
129 SpectrumWifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
130
131 Ptr<WifiPpdu> ppdu =
132 Create<HePpdu>(psdu, txVector, m_phy->GetOperatingChannel(), txDuration, m_uid++);
133
134 Ptr<SpectrumValue> txPowerSpectrum =
137 DbmToW(rxPower),
139
141 txParams->psd = txPowerSpectrum;
142 txParams->txPhy = nullptr;
143 txParams->duration = txDuration;
144 txParams->ppdu = ppdu;
145
146 m_phy->StartRx(txParams, nullptr);
147}
148
149void
151{
152 // This is needed to make sure PHY state will be checked as the last event if a state change
153 // occurred at the exact same time as the check
155}
156
157void
159{
160 WifiPhyState currentState;
161 PointerValue ptr;
162 m_phy->GetAttribute("State", ptr);
164 currentState = state->GetState();
165 NS_LOG_FUNCTION(this << currentState);
166 NS_TEST_ASSERT_MSG_EQ(currentState,
167 expectedState,
168 "PHY State " << currentState << " does not match expected state "
169 << expectedState << " at " << Simulator::Now());
170}
171
172void
174{
180 m_phy->SetInterferenceHelper(interferenceHelper);
182 m_phy->SetErrorRateModel(error);
183 m_phy->SetDevice(dev);
184 m_phy->AddChannel(spectrumChannel);
185 m_phy->SetOperatingChannel(WifiPhy::ChannelTuple{CHANNEL_NUMBER, 0, WIFI_PHY_BAND_5GHZ, 0});
186 m_phy->ConfigureStandard(WIFI_STANDARD_80211ax);
187 dev->SetPhy(m_phy);
188 node->AddDevice(dev);
189}
190
191void
193{
194 m_phy->Dispose();
195 m_phy = nullptr;
196}
197
198/**
199 * @ingroup wifi-test
200 * @ingroup tests
201 *
202 * @brief Preamble detection test w/o frame capture
203 */
205{
206 public:
208
209 protected:
210 void DoSetup() override;
211
212 /**
213 * Spectrum wifi receive success function
214 * @param psdu the PSDU
215 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
216 * @param txVector the transmit vector
217 * @param statusPerMpdu reception status per MPDU
218 */
220 RxSignalInfo rxSignalInfo,
221 const WifiTxVector& txVector,
222 const std::vector<bool>& statusPerMpdu);
223 /**
224 * Spectrum wifi receive failure function
225 * @param psdu the PSDU
226 */
228 uint32_t m_countRxSuccess{0}; ///< count RX success
229 uint32_t m_countRxFailure{0}; ///< count RX failure
230
231 private:
232 void DoRun() override;
233
234 /**
235 * Check the number of received packets
236 * @param expectedSuccessCount the number of successfully received packets
237 * @param expectedFailureCount the number of unsuccessfully received packets
238 */
239 void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
240};
241
245 "Threshold preamble detection model test when no frame capture model is applied")
246{
247}
248
249void
251 uint32_t expectedFailureCount)
252{
254 expectedSuccessCount,
255 "Didn't receive right number of successful packets");
257 expectedFailureCount,
258 "Didn't receive right number of unsuccessful packets");
259}
260
261void
263 RxSignalInfo rxSignalInfo,
264 const WifiTxVector& txVector,
265 const std::vector<bool>& statusPerMpdu)
266{
267 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
269}
270
271void
277
278void
280{
282
283 m_phy->SetReceiveOkCallback(
285 m_phy->SetReceiveErrorCallback(
287
288 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
290 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(4));
291 preambleDetectionModel->SetAttribute("MinimumRssi", DoubleValue(-82));
292 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
293}
294
295void
297{
300 int64_t streamNumber = 0;
301 m_phy->AssignStreams(streamNumber);
302
303 // RX power > CCA-ED > CCA-PD
304 dBm_u rxPower{-50};
305
306 // CASE 1: send one packet and check PHY state:
307 // All reception stages should succeed and PHY state should be RX for the duration of the packet
308 // minus the time to detect the preamble, otherwise it should be IDLE.
309
312 this,
313 rxPower,
314 1000,
315 7);
316 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
317 // CCA_BUSY
320 this,
324 this,
326 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
327 // CCA_BUSY to RX
330 this,
334 this,
336 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
339 this,
343 this,
345 // Packet should have been successfully received
348 this,
349 1,
350 0);
351
352 // CASE 2: send two packets with same power within the 4us window and check PHY state:
353 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
354 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
355 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
356 // time to detect the preamble.
357
360 this,
361 rxPower,
362 1000,
363 7);
366 this,
367 rxPower,
368 1000,
369 7);
370 // At 4us, no preamble is successfully detected and STA PHY STATE should move from IDLE to
371 // CCA_BUSY
374 this,
378 this,
380 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
381 // = 154.8us
384 this,
388 this,
390 // No more packet should have been successfully received, and since preamble detection did not
391 // pass, the packet should not have been counted as a failure
394 this,
395 1,
396 0);
397
398 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY
399 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
400 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
401 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
402 // time to detect the preamble.
403
406 this,
407 rxPower,
408 1000,
409 7);
412 this,
413 rxPower - dB_u{3},
414 1000,
415 7);
416 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
417 // CCA_BUSY
420 this,
424 this,
426 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
427 // = 154.8us
430 this,
434 this,
436 // No more packet should have been successfully received, and since preamble detection did not
437 // pass the packet should not have been counted as a failure
440 this,
441 1,
442 0);
443
444 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY
445 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
446 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
447 // decode the modulation).
448
451 this,
452 rxPower,
453 1000,
454 7);
457 this,
458 rxPower - dB_u{6},
459 1000,
460 7);
461 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
462 // CCA_BUSY
465 this,
469 this,
471 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
472 // CCA_BUSY to RX
475 this,
479 this,
481 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
482 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
483 // should first be seen as CCA_BUSY for 2us.
486 this,
490 this,
494 this,
498 this,
500 // In this case, the first packet should be marked as a failure
503 this,
504 1,
505 1);
506
507 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY
508 // state: PHY preamble detection should fail because SNR is too low (around -3 dB, which is
509 // lower than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is
510 // above CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus
511 // the time to detect the preamble.
512
515 this,
516 rxPower,
517 1000,
518 7);
521 this,
522 rxPower + dB_u{3.0},
523 1000,
524 7);
525 // At 6us (hence 4us after the last signal is received), no preamble is successfully detected,
526 // hence STA PHY STATE should move from IDLE to CCA_BUSY
529 this,
533 this,
535 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
536 // = 154.8us
539 this,
543 this,
545 // No more packet should have been successfully received, and since preamble detection did not
546 // pass the packet should not have been counted as a failure
549 this,
550 1,
551 1);
552
553 // CCA-PD < RX power < CCA-ED
554 rxPower = dBm_u{-70};
555
556 // CASE 6: send one packet and check PHY state:
557 // All reception stages should succeed and PHY state should be RX for the duration of the packet
558 // minus the time to detect the preamble, otherwise it should be IDLE.
559
562 this,
563 rxPower,
564 1000,
565 7);
566 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
567 // CCA_BUSY
570 this,
574 this,
576 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
577 // CCA_BUSY to RX
580 this,
584 this,
586 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
589 this,
593 this,
595 // Packet should have been successfully received
598 this,
599 2,
600 1);
601
602 // CASE 7: send two packets with same power within the 4us window and check PHY state:
603 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
604 // the threshold of 4 dB), and PHY state should be CCA_BUSY since it should detect the start of
605 // a valid OFDM transmission at a receive level greater than or equal to the minimum modulation
606 // and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
607
610 this,
611 rxPower,
612 1000,
613 7);
616 this,
617 rxPower,
618 1000,
619 7);
620 // At 4us, STA PHY STATE should stay IDLE
623 this,
625 // No more packet should have been successfully received, and since preamble detection did not
626 // pass the packet should not have been counted as a failure
629 this,
630 2,
631 1);
632
633 // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY
634 // state: PHY preamble detection should fail PHY preamble detection should fail because SNR is
635 // too low (around 3 dB, which is lower than the threshold of 4 dB), and PHY state should be
636 // CCA_BUSY since it should detect the start of a valid OFDM transmission at a receive level
637 // greater than or equal to the minimum modulation and coding rate sensitivity (–82 dBm for 20
638 // MHz channel spacing).
639
642 this,
643 rxPower,
644 1000,
645 7);
648 this,
649 rxPower - dB_u{3},
650 1000,
651 7);
652 // At 4us, STA PHY STATE should stay IDLE
655 this,
657 // No more packet should have been successfully received, and since preamble detection did not
658 // pass the packet should not have been counted as a failure
661 this,
662 2,
663 1);
664
665 // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY
666 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
667 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
668 // decode the modulation).
669
672 this,
673 rxPower,
674 1000,
675 7);
678 this,
679 rxPower - dB_u{6},
680 1000,
681 7);
682 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
683 // CCA_BUSY
686 this,
690 this,
692 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
693 // CCA_BUSY to RX
696 this,
700 this,
702 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
703 // 152.8us.
706 this,
710 this,
712 // In this case, the first packet should be marked as a failure
715 this,
716 2,
717 2);
718
719 // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY
720 // state: PHY preamble detection should fail because SNR is too low (around -3 dB, which is
721 // lower than the threshold of 4 dB), and PHY state should stay IDLE since the total energy is
722 // below CCA-ED (-62 dBm).
723
726 this,
727 rxPower,
728 1000,
729 7);
732 this,
733 rxPower + dB_u{3.0},
734 1000,
735 7);
736 // At 4us, STA PHY STATE should stay IDLE
739 this,
741 // No more packet should have been successfully received, and since preamble detection did not
742 // pass the packet should not have been counted as a failure
745 this,
746 2,
747 2);
748
749 // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble
750 // detection (-82 dBm) and check PHY state: preamble detection should succeed and PHY state
751 // should move to RX.
752
753 rxPower = dBm_u{-81};
754
757 this,
758 rxPower,
759 1000,
760 7);
761 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
762 // CCA_BUSY
765 this,
769 this,
771 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
772 // CCA_BUSY to RX
775 this,
779 this,
781 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
784 this,
788 this,
790
791 // RX power < CCA-PD < CCA-ED
792 rxPower = dBm_u{-83};
793
794 // CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble
795 // detection (-82 dBm) and check PHY state: preamble detection should fail and PHY should be
796 // kept in IDLE state.
797
800 this,
801 rxPower,
802 1000,
803 7);
804 // At 4us, STA PHY state should be IDLE
807 this,
809
812}
813
814/**
815 * @ingroup wifi-test
816 * @ingroup tests
817 *
818 * @brief Preamble detection test w/o frame capture
819 */
821{
822 public:
824
825 protected:
826 void DoSetup() override;
827
828 /**
829 * Spectrum wifi receive success function
830 * @param psdu the PSDU
831 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
832 * @param txVector the transmit vector
833 * @param statusPerMpdu reception status per MPDU
834 */
836 RxSignalInfo rxSignalInfo,
837 const WifiTxVector& txVector,
838 const std::vector<bool>& statusPerMpdu);
839 /**
840 * Spectrum wifi receive failure function
841 * @param psdu the PSDU
842 */
844 uint32_t m_countRxSuccess{0}; ///< count RX success
845 uint32_t m_countRxFailure{0}; ///< count RX failure
846
847 private:
848 void DoRun() override;
849
850 /**
851 * Check the number of received packets
852 * @param expectedSuccessCount the number of successfully received packets
853 * @param expectedFailureCount the number of unsuccessfully received packets
854 */
855 void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
856};
857
860 "Threshold preamble detection model test when simple frame capture model is applied")
861{
862}
863
864void
866 uint32_t expectedFailureCount)
867{
869 expectedSuccessCount,
870 "Didn't receive right number of successful packets");
872 expectedFailureCount,
873 "Didn't receive right number of unsuccessful packets");
874}
875
876void
878 RxSignalInfo rxSignalInfo,
879 const WifiTxVector& txVector,
880 const std::vector<bool>& statusPerMpdu)
881{
882 NS_LOG_FUNCTION(this << *psdu << txVector);
884}
885
886void
892
893void
895{
897
898 m_phy->SetReceiveOkCallback(
900 m_phy->SetReceiveErrorCallback(
902
903 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
905 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(4));
906 preambleDetectionModel->SetAttribute("MinimumRssi", DoubleValue(-82));
907 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
908
910 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
911 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
912 m_phy->SetFrameCaptureModel(frameCaptureModel);
913}
914
915void
917{
920 int64_t streamNumber = 1;
921 m_phy->AssignStreams(streamNumber);
922
923 // RX power > CCA-ED > CCA-PD
924 dBm_u rxPower{-50};
925
926 // CASE 1: send one packet and check PHY state:
927 // All reception stages should succeed and PHY state should be RX for the duration of the packet
928 // minus the time to detect the preamble, otherwise it should be IDLE.
929
932 this,
933 rxPower,
934 1000,
935 7);
936 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
937 // CCA_BUSY
940 this,
944 this,
946 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
947 // CCA_BUSY to RX
950 this,
954 this,
956 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
959 this,
963 this,
965 // Packet should have been successfully received
968 this,
969 1,
970 0);
971
972 // CASE 2: send two packets with same power within the 4us window and check PHY state:
973 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
974 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
975 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
976 // time to detect the preamble.
977
980 this,
981 rxPower,
982 1000,
983 7);
986 this,
987 rxPower,
988 1000,
989 7);
990 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
991 // CCA_BUSY
994 this,
998 this,
1000 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1001 // = 154.8us
1004 this,
1008 this,
1010 // No more packet should have been successfully received, and since preamble detection did not
1011 // pass the packet should not have been counted as a failure
1014 this,
1015 1,
1016 0);
1017
1018 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY
1019 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
1020 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1021 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1022 // time to detect the preamble.
1023
1026 this,
1027 rxPower,
1028 1000,
1029 7);
1032 this,
1033 rxPower - dB_u{3},
1034 1000,
1035 7);
1036 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1037 // CCA_BUSY
1040 this,
1044 this,
1046 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1047 // = 154.8us
1050 this,
1054 this,
1056 // No more packet should have been successfully received, and since preamble detection did not
1057 // pass the packet should not have been counted as a failure
1060 this,
1061 1,
1062 0);
1063
1064 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY
1065 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1066 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1067 // decode the modulation).
1068
1071 this,
1072 rxPower,
1073 1000,
1074 7);
1077 this,
1078 rxPower - dB_u{6},
1079 1000,
1080 7);
1081 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1082 // CCA_BUSY
1085 this,
1089 this,
1091 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1092 // CCA_BUSY to RX
1095 this,
1099 this,
1101 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1102 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
1103 // should first be seen as CCA_BUSY for 2us.
1106 this,
1110 this,
1114 this,
1118 this,
1120 // In this case, the first packet should be marked as a failure
1123 this,
1124 1,
1125 1);
1126
1127 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY
1128 // state: PHY preamble detection should switch because a higher packet is received within the
1129 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1130 // lower than the threshold of 4 dB), PHY state should be CCA_BUSY since the total energy is
1131 // above CCA-ED (-62 dBm).
1132
1135 this,
1136 rxPower,
1137 1000,
1138 7);
1141 this,
1142 rxPower + dB_u{3.0},
1143 1000,
1144 7);
1145 // At 4us, STA PHY STATE should stay IDLE
1148 this,
1150 // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
1153 this,
1157 this,
1159 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1160 // = 154.8us
1163 this,
1167 this,
1169 // No more packet should have been successfully received, and since preamble detection did not
1170 // pass the packet should not have been counted as a failure
1173 this,
1174 1,
1175 1);
1176
1177 // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY
1178 // state: PHY preamble detection should switch because a higher packet is received within the
1179 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1180 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1181 // decode the modulation).
1182
1185 this,
1186 rxPower,
1187 1000,
1188 7);
1191 this,
1192 rxPower + dB_u{6.0},
1193 1000,
1194 7);
1195 // At 4us, STA PHY STATE should stay IDLE
1198 this,
1200 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1201 // CCA_BUSY
1204 this,
1208 this,
1210 // At 46us, PHY header should be successfully received and STA PHY STATE should move from
1211 // CCA_BUSY to RX
1214 this,
1218 this,
1220 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1221 // = 154.8us
1224 this,
1228 this,
1230 // In this case, the second packet should be marked as a failure
1233 this,
1234 1,
1235 2);
1236
1237 // CASE 7: send two packets with same power at the exact same time and check PHY state:
1238 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
1239 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1240 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1241 // time to detect the preamble.
1242
1245 this,
1246 rxPower,
1247 1000,
1248 7);
1251 this,
1252 rxPower,
1253 1000,
1254 7);
1255 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1256 // CCA_BUSY
1259 this,
1263 this,
1265 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1266 // = 154.8us
1269 this,
1273 this,
1275 // No more packet should have been successfully received, and since preamble detection did not
1276 // pass the packet should not have been counted as a failure
1279 this,
1280 1,
1281 2);
1282
1283 // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY
1284 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
1285 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1286 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1287 // time to detect the preamble.
1288
1291 this,
1292 rxPower,
1293 1000,
1294 7);
1297 this,
1298 rxPower - dB_u{3},
1299 1000,
1300 7);
1301 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1302 // CCA_BUSY
1305 this,
1309 this,
1311 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1314 this,
1318 this,
1320 // No more packet should have been successfully received, and since preamble detection did not
1321 // pass the packet should not have been counted as a failure
1324 this,
1325 1,
1326 2);
1327
1328 // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY
1329 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1330 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1331 // decode the modulation).
1332
1335 this,
1336 rxPower,
1337 1000,
1338 7);
1341 this,
1342 rxPower - dB_u{6},
1343 1000,
1344 7);
1345 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1346 // CCA_BUSY
1349 this,
1353 this,
1355 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1356 // CCA_BUSY to RX
1359 this,
1363 this,
1365 // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
1368 this,
1372 this,
1374 // In this case, the first packet should be marked as a failure
1377 this,
1378 1,
1379 3);
1380
1381 // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY
1382 // state: PHY preamble detection should switch because a higher packet is received within the
1383 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1384 // lower than the threshold of 4 dB), PHY state should be CCA_BUSY since the total energy is
1385 // above CCA-ED (-62 dBm).
1386
1389 this,
1390 rxPower,
1391 1000,
1392 7);
1395 this,
1396 rxPower + dB_u{3.0},
1397 1000,
1398 7);
1399 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1400 // CCA_BUSY
1403 this,
1407 this,
1409 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1412 this,
1416 this,
1418 // No more packet should have been successfully received, and since preamble detection did not
1419 // pass the packet should not have been counted as a failure
1422 this,
1423 1,
1424 3);
1425
1426 // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY
1427 // state: PHY preamble detection should switch because a higher packet is received within the
1428 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1429 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1430 // decode the modulation).
1431
1434 this,
1435 rxPower,
1436 1000,
1437 7);
1440 this,
1441 rxPower + dB_u{6.0},
1442 1000,
1443 7);
1444 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1445 // CCA_BUSY
1448 this,
1452 this,
1454 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1455 // CCA_BUSY to RX
1458 this,
1462 this,
1464 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1467 this,
1471 this,
1473 // In this case, the second packet should be marked as a failure
1476 this,
1477 1,
1478 4);
1479
1480 // CCA-PD < RX power < CCA-ED
1481 rxPower = dBm_u{-70};
1482
1483 // CASE 12: send one packet and check PHY state:
1484 // All reception stages should succeed and PHY state should be RX for the duration of the packet
1485 // minus the time to detect the preamble, otherwise it should be IDLE.
1486
1489 this,
1490 rxPower,
1491 1000,
1492 7);
1493 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1494 // CCA_BUSY
1497 this,
1501 this,
1503 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1504 // CCA_BUSY to RX
1507 this,
1511 this,
1513 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
1516 this,
1520 this,
1522 // Packet should have been successfully received
1525 this,
1526 2,
1527 4);
1528
1529 // CASE 13: send two packets with same power within the 4us window and check PHY state:
1530 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
1531 // the threshold of 4 dB), and PHY state should be CCA_BUSY since it should detect the start of
1532 // a valid OFDM transmission at a receive level greater than or equal to the minimum modulation
1533 // and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
1534
1537 this,
1538 rxPower,
1539 1000,
1540 7);
1543 this,
1544 rxPower,
1545 1000,
1546 7);
1547 // At 4us, STA PHY STATE should stay IDLE
1550 this,
1552 // No more packet should have been successfully received, and since preamble detection did not
1553 // pass the packet should not have been counted as a failure
1556 this,
1557 2,
1558 4);
1559
1560 // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY
1561 // state: PHY preamble detection should fail PHY preamble detection should fail because SNR is
1562 // too low (around 3 dB, which is lower than the threshold of 4 dB), and PHY state should be
1563 // CCA_BUSY since it should detect the start of a valid OFDM transmission at a receive level
1564 // greater than or equal to the minimum modulation and coding rate sensitivity (–82 dBm for 20
1565 // MHz channel spacing).
1566
1569 this,
1570 rxPower,
1571 1000,
1572 7);
1575 this,
1576 rxPower - dB_u{3},
1577 1000,
1578 7);
1579 // At 4us, STA PHY STATE should stay IDLE
1582 this,
1584 // No more packet should have been successfully received, and since preamble detection did not
1585 // pass the packet should not have been counted as a failure
1588 this,
1589 2,
1590 4);
1591
1592 // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY
1593 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1594 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1595 // decode the modulation).
1596
1599 this,
1600 rxPower,
1601 1000,
1602 7);
1605 this,
1606 rxPower - dB_u{6},
1607 1000,
1608 7);
1609 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1610 // CCA_BUSY
1613 this,
1617 this,
1619 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1620 // CCA_BUSY to RX
1623 this,
1627 this,
1629 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
1630 // 152.8us.
1633 this,
1637 this,
1639 // In this case, the first packet should be marked as a failure
1642 this,
1643 2,
1644 5);
1645
1646 // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY
1647 // state: PHY preamble detection should switch because a higher packet is received within the
1648 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1649 // lower than the threshold of 4 dB). and PHY state should be CCA_BUSY since it should detect
1650 // the start of a valid OFDM transmission at a receive level greater than or equal to the
1651 // minimum modulation and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
1652
1655 this,
1656 rxPower,
1657 1000,
1658 7);
1661 this,
1662 rxPower + dB_u{3.0},
1663 1000,
1664 7);
1665 // At 4us, STA PHY STATE should stay IDLE
1668 this,
1670 // At 6us, STA PHY STATE should be CCA_BUSY
1673 this,
1675 // No more packet should have been successfully received, and since preamble detection did not
1676 // pass the packet should not have been counted as a failure
1679 this,
1680 2,
1681 5);
1682
1683 // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY
1684 // state: PHY preamble detection should switch because a higher packet is received within the
1685 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1686 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1687 // decode the modulation).
1688
1691 this,
1692 rxPower,
1693 1000,
1694 7);
1697 this,
1698 rxPower + dB_u{6.0},
1699 1000,
1700 7);
1701 // At 4us, STA PHY STATE should stay IDLE
1704 this,
1706 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1707 // CCA_BUSY
1710 this,
1714 this,
1716 // At 46us, PHY header should be successfully received and STA PHY STATE should move from
1717 // CCA_BUSY to RX
1720 this,
1724 this,
1726 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1727 // = 154.8us
1730 this,
1734 this,
1736 // In this case, the second packet should be marked as a failure
1739 this,
1740 2,
1741 6);
1742
1743 rxPower = dBm_u{-50};
1744 // CASE 18: send two packets with second one 50 dB higher within the 4us window
1745
1748 this,
1749 rxPower,
1750 1000,
1751 7);
1754 this,
1755 rxPower + dB_u{50.0},
1756 1000,
1757 7);
1758 // The second packet should be received successfully
1761 this,
1762 3,
1763 6);
1764
1765 // CASE 19: send two packets with second one 10 dB higher within the 4us window
1766
1769 this,
1770 rxPower,
1771 1000,
1772 7);
1775 this,
1776 rxPower + dB_u{10.0},
1777 1000,
1778 7);
1779 // The second packet should be captured, but not decoded since SNR to low for used MCS
1782 this,
1783 3,
1784 7);
1785
1786 // CASE 20: send two packets with second one 50 dB higher in the same time
1787
1790 this,
1791 rxPower,
1792 1000,
1793 7);
1796 this,
1797 rxPower + dB_u{50.0},
1798 1000,
1799 7);
1800 // The second packet should be received successfully, same as in CASE 13
1803 this,
1804 4,
1805 7);
1806
1807 // CASE 21: send two packets with second one 10 dB higher in the same time
1808
1811 this,
1812 rxPower,
1813 1000,
1814 7);
1817 this,
1818 rxPower + dB_u{10.0},
1819 1000,
1820 7);
1821 // The second packet should be captured, but not decoded since SNR to low for used MCS, same as
1822 // in CASE 19
1825 this,
1826 4,
1827 8);
1828
1831}
1832
1833/**
1834 * @ingroup wifi-test
1835 * @ingroup tests
1836 *
1837 * @brief Simple frame capture model test
1838 */
1840{
1841 public:
1843
1844 private:
1845 void DoSetup() override;
1846 void DoRun() override;
1847
1848 /**
1849 * Reset function
1850 */
1851 void Reset();
1852 /**
1853 * Spectrum wifi receive success function
1854 * @param psdu the PSDU
1855 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
1856 * @param txVector the transmit vector
1857 * @param statusPerMpdu reception status per MPDU
1858 */
1860 RxSignalInfo rxSignalInfo,
1861 const WifiTxVector& txVector,
1862 const std::vector<bool>& statusPerMpdu);
1863 /**
1864 * RX dropped function
1865 * @param p the packet
1866 * @param reason the reason
1867 */
1869
1870 /**
1871 * Verify whether 1000 bytes packet has been received
1872 */
1874 /**
1875 * Verify whether 1500 bytes packet has been received
1876 */
1878 /**
1879 * Verify whether 1000 bytes packet has been dropped
1880 */
1882 /**
1883 * Verify whether 1500 bytes packet has been dropped
1884 */
1886
1887 bool m_rxSuccess1000B{false}; ///< count received packets with 1000B payload
1888 bool m_rxSuccess1500B{false}; ///< count received packets with 1500B payload
1889 bool m_rxDropped1000B{false}; ///< count dropped packets with 1000B payload
1890 bool m_rxDropped1500B{false}; ///< count dropped packets with 1500B payload
1891};
1892
1894 : WifiPhyReceptionTest("Simple frame capture model test")
1895{
1896}
1897
1898void
1900 RxSignalInfo rxSignalInfo,
1901 const WifiTxVector& txVector,
1902 const std::vector<bool>& statusPerMpdu)
1903{
1904 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
1905 NS_ASSERT(!psdu->IsAggregate() || psdu->IsSingle());
1906 if (psdu->GetSize() == 1030)
1907 {
1908 m_rxSuccess1000B = true;
1909 }
1910 else if (psdu->GetSize() == 1530)
1911 {
1912 m_rxSuccess1500B = true;
1913 }
1914}
1915
1916void
1918{
1919 NS_LOG_FUNCTION(this << p << reason);
1920 if (p->GetSize() == 1030)
1921 {
1922 m_rxDropped1000B = true;
1923 }
1924 else if (p->GetSize() == 1530)
1925 {
1926 m_rxDropped1500B = true;
1927 }
1928}
1929
1930void
1932{
1933 m_rxSuccess1000B = false;
1934 m_rxSuccess1500B = false;
1935 m_rxDropped1000B = false;
1936 m_rxDropped1500B = false;
1937}
1938
1939void
1944
1945void
1950
1951void
1956
1957void
1962
1963void
1965{
1967
1968 m_phy->SetReceiveOkCallback(MakeCallback(&TestSimpleFrameCaptureModel::RxSuccess, this));
1969 m_phy->TraceConnectWithoutContext("PhyRxDrop",
1971
1972 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
1974 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(2));
1975 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
1976
1978 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
1979 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
1980 m_phy->SetFrameCaptureModel(frameCaptureModel);
1981}
1982
1983void
1985{
1988 int64_t streamNumber = 2;
1989 dBm_u rxPower{-30};
1990 m_phy->AssignStreams(streamNumber);
1991
1992 // CASE 1: send two packets with same power within the capture window:
1993 // PHY should not switch reception because they have same power.
1994
1997 this,
1998 rxPower,
1999 1000,
2000 0);
2003 this,
2004 rxPower,
2005 1500,
2006 0);
2009
2010 // CASE 2: send two packets with second one 6 dB weaker within the capture window:
2011 // PHY should not switch reception because first one has higher power.
2012
2015 this,
2016 rxPower,
2017 1000,
2018 0);
2021 this,
2022 rxPower - dB_u{6},
2023 1500,
2024 0);
2027 this);
2030
2031 // CASE 3: send two packets with second one 6 dB higher within the capture window:
2032 // PHY should switch reception because the second one has a higher power.
2033
2036 this,
2037 rxPower,
2038 1000,
2039 0);
2042 this,
2043 rxPower + dB_u{6.0},
2044 1500,
2045 0);
2049 this);
2051
2052 // CASE 4: send two packets with second one 6 dB higher after the capture window:
2053 // PHY should not switch reception because capture window duration has elapsed when the second
2054 // packet arrives.
2055
2058 this,
2059 rxPower,
2060 1000,
2061 0);
2064 this,
2065 rxPower + dB_u{6.0},
2066 1500,
2067 0);
2070
2073}
2074
2075/**
2076 * @ingroup wifi-test
2077 * @ingroup tests
2078 *
2079 * @brief Test PHY state upon success or failure of L-SIG and SIG-A
2080 */
2082{
2083 public:
2085
2086 private:
2087 void DoRun() override;
2088};
2089
2091 : WifiPhyReceptionTest("PHY headers reception test")
2092{
2093}
2094
2095void
2097{
2100 int64_t streamNumber = 0;
2101 m_phy->AssignStreams(streamNumber);
2102
2103 // RX power > CCA-ED
2104 dBm_u rxPower{-50};
2105
2106 // CASE 1: send one packet followed by a second one with same power between the end of the 4us
2107 // preamble detection window and the start of L-SIG of the first packet: reception should be
2108 // aborted since L-SIG cannot be decoded (SNR too low).
2109
2113 this,
2114 rxPower,
2115 1000,
2116 7);
2117 // At 10 us, STA PHY STATE should be CCA_BUSY.
2120 this,
2122 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX and be kept to
2123 // CCA_BUSY.
2126 this,
2128 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10
2129 // = 162.8us.
2132 this,
2136 this,
2138
2139 // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us
2140 // preamble detection window and the start of L-SIG of the first packet: reception should not be
2141 // aborted since L-SIG can be decoded (SNR high enough).
2142
2146 this,
2147 rxPower - dB_u{3},
2148 1000,
2149 7);
2150 // At 10 us, STA PHY STATE should be CCA_BUSY.
2153 this,
2155 // At 44us (end of PHY header), STA PHY STATE should have moved to RX since PHY header reception
2156 // should have succeeded.
2159 this,
2163 this,
2165 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
2166 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
2167 // should first be seen as CCA_BUSY for 10us.
2170 this,
2174 this,
2178 this,
2182 this,
2184
2185 // CASE 3: send one packet followed by a second one with same power between the end of L-SIG and
2186 // the start of HE-SIG of the first packet: PHY header reception should not succeed but PHY
2187 // should stay in RX state for the duration estimated from L-SIG.
2188
2192 this,
2193 rxPower,
2194 1000,
2195 7);
2196 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX (HE-SIG failed) and be
2197 // kept to CCA_BUSY.
2200 this,
2202 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed,
2203 // i.e. at 152.8us. However, since there is a second packet transmitted with a power above
2204 // CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
2207 this,
2211 this,
2215 this,
2219 this,
2221
2222 // CASE 4: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the
2223 // start of HE-SIG of the first packet: PHY header reception should succeed.
2224
2228 this,
2229 rxPower - dB_u{3},
2230 1000,
2231 7);
2232 // At 10 us, STA PHY STATE should be CCA_BUSY.
2235 this,
2237 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2238 // should have succeeded.
2241 this,
2245 this,
2247 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed,
2248 // i.e. at 152.8us. However, since there is a second packet transmitted with a power above
2249 // CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
2252 this,
2256 this,
2260 this,
2264 this,
2266
2267 // RX power < CCA-ED
2268 rxPower = dBm_u{-70};
2269
2270 // CASE 5: send one packet followed by a second one with same power between the end of the 4us
2271 // preamble detection window and the start of L-SIG of the first packet: reception should be
2272 // aborted since L-SIG cannot be decoded (SNR too low).
2273
2277 this,
2278 rxPower,
2279 1000,
2280 7);
2281 // At 10 us, STA PHY STATE should be CCA_BUSY.
2284 this,
2286 // At 24us (end of L-SIG), STA PHY STATE stay CCA_BUSY because L-SIG reception failed and the
2287 // start of a valid OFDM transmission has been detected
2290 this,
2292
2293 // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us
2294 // preamble detection window and the start of L-SIG of the first packet: reception should not be
2295 // aborted since L-SIG can be decoded (SNR high enough).
2296
2300 this,
2301 rxPower - dB_u{3},
2302 1000,
2303 7);
2304 // At 10 us, STA PHY STATE should be CCA_BUSY.
2307 this,
2309 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2310 // succeeded.
2313 this,
2315 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2316 // should have succeeded.
2319 this,
2323 this,
2325 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
2326 // 152.8us.
2329 this,
2333 this,
2335
2336 // CASE 7: send one packet followed by a second one with same power between the end of L-SIG and
2337 // the start of HE-SIG of the first packet: PHY header reception should not succeed but PHY
2338 // should stay in RX state for the duration estimated from L-SIG.
2339
2343 this,
2344 rxPower,
2345 1000,
2346 7);
2347 // At 10 us, STA PHY STATE should be CCA_BUSY.
2350 this,
2352 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2353 // succeeded.
2356 this,
2358 // At 44 us (end of HE-SIG), STA PHY STATE should be not have moved to RX since reception of
2359 // HE-SIG should have failed.
2362 this,
2364 // STA PHY STATE should keep CCA_BUSY once the duration estimated from L-SIG has elapsed, i.e.
2365 // at 152.8us.
2368 this,
2370
2371 // CASE 8: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the
2372 // start of HE-SIG of the first packet: PHY header reception should succeed.
2373
2377 this,
2378 rxPower - dB_u{3},
2379 1000,
2380 7);
2381 // At 10 us, STA PHY STATE should be CCA_BUSY.
2384 this,
2386 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2387 // succeeded.
2390 this,
2392 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2393 // should have succeeded.
2396 this,
2400 this,
2402 // STA PHY STATE should move back to CCA_BUSY once the duration estimated from L-SIG has
2403 // elapsed, i.e. at 152.8us.
2406 this,
2410 this,
2412
2415}
2416
2417/**
2418 * @ingroup wifi-test
2419 * @ingroup tests
2420 *
2421 * @brief A-MPDU reception test
2422 */
2424{
2425 public:
2427
2428 private:
2429 void DoSetup() override;
2430 void DoRun() override;
2431
2432 /**
2433 * RX success function
2434 * @param psdu the PSDU
2435 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
2436 * @param txVector the transmit vector
2437 * @param statusPerMpdu reception status per MPDU
2438 */
2440 RxSignalInfo rxSignalInfo,
2441 const WifiTxVector& txVector,
2442 const std::vector<bool>& statusPerMpdu);
2443 /**
2444 * RX failure function
2445 * @param psdu the PSDU
2446 */
2447 void RxFailure(Ptr<const WifiPsdu> psdu);
2448 /**
2449 * RX dropped function
2450 * @param p the packet
2451 * @param reason the reason
2452 */
2454 /**
2455 * Increment reception success bitmap.
2456 * @param size the size of the received packet
2457 */
2459 /**
2460 * Increment reception failure bitmap.
2461 * @param size the size of the received packet
2462 */
2464
2465 /**
2466 * Reset bitmaps function
2467 */
2468 void ResetBitmaps();
2469
2470 /**
2471 * Send A-MPDU with 3 MPDUs of different size (i-th MSDU will have 100 bytes more than
2472 * (i-1)-th).
2473 * @param rxPower the transmit power
2474 * @param referencePacketSize the reference size of the packets in bytes (i-th MSDU will have
2475 * 100 bytes more than (i-1)-th)
2476 */
2477 void SendAmpduWithThreeMpdus(dBm_u rxPower, uint32_t referencePacketSize);
2478
2479 /**
2480 * Check the RX success bitmap for A-MPDU 1
2481 * @param expected the expected bitmap
2482 */
2483 void CheckRxSuccessBitmapAmpdu1(uint8_t expected);
2484 /**
2485 * Check the RX success bitmap for A-MPDU 2
2486 * @param expected the expected bitmap
2487 */
2488 void CheckRxSuccessBitmapAmpdu2(uint8_t expected);
2489 /**
2490 * Check the RX failure bitmap for A-MPDU 1
2491 * @param expected the expected bitmap
2492 */
2493 void CheckRxFailureBitmapAmpdu1(uint8_t expected);
2494 /**
2495 * Check the RX failure bitmap for A-MPDU 2
2496 * @param expected the expected bitmap
2497 */
2498 void CheckRxFailureBitmapAmpdu2(uint8_t expected);
2499 /**
2500 * Check the RX dropped bitmap for A-MPDU 1
2501 * @param expected the expected bitmap
2502 */
2503 void CheckRxDroppedBitmapAmpdu1(uint8_t expected);
2504 /**
2505 * Check the RX dropped bitmap for A-MPDU 2
2506 * @param expected the expected bitmap
2507 */
2508 void CheckRxDroppedBitmapAmpdu2(uint8_t expected);
2509
2510 /**
2511 * Check the PHY state
2512 * @param expectedState the expected PHY state
2513 */
2514 void CheckPhyState(WifiPhyState expectedState);
2515
2516 uint8_t m_rxSuccessBitmapAmpdu1{0}; ///< bitmap of successfully received MPDUs in A-MPDU #1
2517 uint8_t m_rxSuccessBitmapAmpdu2{0}; ///< bitmap of successfully received MPDUs in A-MPDU #2
2518
2519 uint8_t m_rxFailureBitmapAmpdu1{0}; ///< bitmap of unsuccessfully received MPDUs in A-MPDU #1
2520 uint8_t m_rxFailureBitmapAmpdu2{0}; ///< bitmap of unsuccessfully received MPDUs in A-MPDU #2
2521
2522 uint8_t m_rxDroppedBitmapAmpdu1{0}; ///< bitmap of dropped MPDUs in A-MPDU #1
2523 uint8_t m_rxDroppedBitmapAmpdu2{0}; ///< bitmap of dropped MPDUs in A-MPDU #2
2524};
2525
2527 : WifiPhyReceptionTest("A-MPDU reception test")
2528{
2529}
2530
2531void
2541
2542void
2544 RxSignalInfo rxSignalInfo,
2545 const WifiTxVector& txVector,
2546 const std::vector<bool>& statusPerMpdu)
2547{
2548 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
2549 if (statusPerMpdu.empty()) // wait for the whole A-MPDU
2550 {
2551 return;
2552 }
2553 NS_ABORT_MSG_IF(psdu->GetNMpdus() != statusPerMpdu.size(),
2554 "Should have one receive status per MPDU");
2555 auto rxOkForMpdu = statusPerMpdu.begin();
2556 for (auto mpdu = psdu->begin(); mpdu != psdu->end(); ++mpdu)
2557 {
2558 if (*rxOkForMpdu)
2559 {
2560 IncrementSuccessBitmap((*mpdu)->GetSize());
2561 }
2562 else
2563 {
2564 IncrementFailureBitmap((*mpdu)->GetSize());
2565 }
2566 ++rxOkForMpdu;
2567 }
2568}
2569
2570void
2572{
2573 if (size == 1030) // A-MPDU 1 - MPDU #1
2574 {
2576 }
2577 else if (size == 1130) // A-MPDU 1 - MPDU #2
2578 {
2579 m_rxSuccessBitmapAmpdu1 |= (1 << 1);
2580 }
2581 else if (size == 1230) // A-MPDU 1 - MPDU #3
2582 {
2583 m_rxSuccessBitmapAmpdu1 |= (1 << 2);
2584 }
2585 else if (size == 1330) // A-MPDU 2 - MPDU #1
2586 {
2588 }
2589 else if (size == 1430) // A-MPDU 2 - MPDU #2
2590 {
2591 m_rxSuccessBitmapAmpdu2 |= (1 << 1);
2592 }
2593 else if (size == 1530) // A-MPDU 2 - MPDU #3
2594 {
2595 m_rxSuccessBitmapAmpdu2 |= (1 << 2);
2596 }
2597}
2598
2599void
2601{
2602 NS_LOG_FUNCTION(this << *psdu);
2603 for (auto mpdu = psdu->begin(); mpdu != psdu->end(); ++mpdu)
2604 {
2605 IncrementFailureBitmap((*mpdu)->GetSize());
2606 }
2607}
2608
2609void
2611{
2612 if (size == 1030) // A-MPDU 1 - MPDU #1
2613 {
2615 }
2616 else if (size == 1130) // A-MPDU 1 - MPDU #2
2617 {
2618 m_rxFailureBitmapAmpdu1 |= (1 << 1);
2619 }
2620 else if (size == 1230) // A-MPDU 1 - MPDU #3
2621 {
2622 m_rxFailureBitmapAmpdu1 |= (1 << 2);
2623 }
2624 else if (size == 1330) // A-MPDU 2 - MPDU #1
2625 {
2627 }
2628 else if (size == 1430) // A-MPDU 2 - MPDU #2
2629 {
2630 m_rxFailureBitmapAmpdu2 |= (1 << 1);
2631 }
2632 else if (size == 1530) // A-MPDU 2 - MPDU #3
2633 {
2634 m_rxFailureBitmapAmpdu2 |= (1 << 2);
2635 }
2636}
2637
2638void
2640{
2641 NS_LOG_FUNCTION(this << p << reason);
2642 if (p->GetSize() == 1030) // A-MPDU 1 - MPDU #1
2643 {
2645 }
2646 else if (p->GetSize() == 1130) // A-MPDU 1 - MPDU #2
2647 {
2648 m_rxDroppedBitmapAmpdu1 |= (1 << 1);
2649 }
2650 else if (p->GetSize() == 1230) // A-MPDU 1 - MPDU #3
2651 {
2652 m_rxDroppedBitmapAmpdu1 |= (1 << 2);
2653 }
2654 else if (p->GetSize() == 1330) // A-MPDU 2 - MPDU #1
2655 {
2657 }
2658 else if (p->GetSize() == 1430) // A-MPDU 2 - MPDU #2
2659 {
2660 m_rxDroppedBitmapAmpdu2 |= (1 << 1);
2661 }
2662 else if (p->GetSize() == 1530) // A-MPDU 2 - MPDU #3
2663 {
2664 m_rxDroppedBitmapAmpdu2 |= (1 << 2);
2665 }
2666}
2667
2668void
2670{
2672 expected,
2673 "RX success bitmap for A-MPDU 1 is not as expected");
2674}
2675
2676void
2678{
2680 expected,
2681 "RX success bitmap for A-MPDU 2 is not as expected");
2682}
2683
2684void
2686{
2688 expected,
2689 "RX failure bitmap for A-MPDU 1 is not as expected");
2690}
2691
2692void
2694{
2696 expected,
2697 "RX failure bitmap for A-MPDU 2 is not as expected");
2698}
2699
2700void
2702{
2704 expected,
2705 "RX dropped bitmap for A-MPDU 1 is not as expected");
2706}
2707
2708void
2710{
2712 expected,
2713 "RX dropped bitmap for A-MPDU 2 is not as expected");
2714}
2715
2716void
2718{
2719 WifiPhyState currentState;
2720 PointerValue ptr;
2721 m_phy->GetAttribute("State", ptr);
2723 currentState = state->GetState();
2724 NS_TEST_ASSERT_MSG_EQ(currentState,
2725 expectedState,
2726 "PHY State " << currentState << " does not match expected state "
2727 << expectedState << " at " << Simulator::Now());
2728}
2729
2730void
2732{
2736 NanoSeconds(800),
2737 1,
2738 1,
2739 0,
2740 MHz_u{20},
2741 true);
2742
2743 WifiMacHeader hdr;
2745 hdr.SetQosTid(0);
2746
2747 std::vector<Ptr<WifiMpdu>> mpduList;
2748 for (size_t i = 0; i < 3; ++i)
2749 {
2750 Ptr<Packet> p = Create<Packet>(referencePacketSize + i * 100);
2751 mpduList.push_back(Create<WifiMpdu>(p, hdr));
2752 }
2753 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(mpduList);
2754
2755 Time txDuration =
2756 SpectrumWifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
2757
2758 Ptr<WifiPpdu> ppdu =
2759 Create<HePpdu>(psdu, txVector, m_phy->GetOperatingChannel(), txDuration, m_uid++);
2760
2761 Ptr<SpectrumValue> txPowerSpectrum =
2764 DbmToW(rxPower),
2765 GUARD_WIDTH);
2766
2768 txParams->psd = txPowerSpectrum;
2769 txParams->txPhy = nullptr;
2770 txParams->duration = txDuration;
2771 txParams->ppdu = ppdu;
2772
2773 m_phy->StartRx(txParams, nullptr);
2774}
2775
2776void
2778{
2780
2781 m_phy->SetReceiveOkCallback(MakeCallback(&TestAmpduReception::RxSuccess, this));
2782 m_phy->SetReceiveErrorCallback(MakeCallback(&TestAmpduReception::RxFailure, this));
2783 m_phy->TraceConnectWithoutContext("PhyRxDrop",
2785
2786 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
2788 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(2));
2789 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
2790
2792 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
2793 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
2794 m_phy->SetFrameCaptureModel(frameCaptureModel);
2795}
2796
2797void
2799{
2802 int64_t streamNumber = 1;
2803 dBm_u rxPower{-30};
2804 m_phy->AssignStreams(streamNumber);
2805
2806 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2807 // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
2808 // power under RX sensitivity. The second A-MPDU is received 2 microseconds after the first
2809 // A-MPDU (i.e. during preamble detection).
2810 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2811
2812 // A-MPDU 1
2815 this,
2816 rxPower - dB_u{100},
2817 1000);
2818
2819 // A-MPDU 2
2822 this,
2823 rxPower,
2824 1300);
2825
2826 // All MPDUs of A-MPDU 1 should have been ignored.
2829 this,
2830 0b00000000);
2833 this,
2834 0b00000000);
2837 this,
2838 0b00000000);
2839
2840 // All MPDUs of A-MPDU 2 should have been successfully received.
2843 this,
2844 0b00000111);
2847 this,
2848 0b00000000);
2851 this,
2852 0b00000000);
2853
2855
2856 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2857 // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
2858 // with power under RX sensitivity. The second A-MPDU is received 2 microseconds after the first
2859 // A-MPDU (i.e. during preamble detection).
2860 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2861
2862 // A-MPDU 1
2865 this,
2866 rxPower,
2867 1000);
2868
2869 // A-MPDU 2
2872 this,
2873 rxPower - dB_u{100},
2874 1300);
2875
2876 // All MPDUs of A-MPDU 1 should have been received.
2879 this,
2880 0b00000111);
2883 this,
2884 0b00000000);
2887 this,
2888 0b00000000);
2889
2890 // All MPDUs of A-MPDU 2 should have been ignored.
2893 this,
2894 0b00000000);
2897 this,
2898 0b00000000);
2901 this,
2902 0b00000000);
2903
2905
2906 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2907 // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
2908 // power under RX sensitivity. The second A-MPDU is received 10 microseconds after the first
2909 // A-MPDU (i.e. during the frame capture window).
2910 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2911
2912 // A-MPDU 1
2915 this,
2916 rxPower - dB_u{100},
2917 1000);
2918
2919 // A-MPDU 2
2922 this,
2923 rxPower,
2924 1300);
2925
2926 // All MPDUs of A-MPDU 1 should have been ignored.
2929 this,
2930 0b00000000);
2933 this,
2934 0b00000000);
2937 this,
2938 0b00000000);
2939
2940 // All MPDUs of A-MPDU 2 should have been successfully received.
2943 this,
2944 0b00000111);
2947 this,
2948 0b00000000);
2951 this,
2952 0b00000000);
2953
2955
2956 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2957 // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
2958 // with power under RX sensitivity. The second A-MPDU is received 10 microseconds after the
2959 // first A-MPDU (i.e. during the frame capture window).
2960 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2961
2962 // A-MPDU 1
2965 this,
2966 rxPower,
2967 1000);
2968
2969 // A-MPDU 2
2972 this,
2973 rxPower - dB_u{100},
2974 1300);
2975
2976 // All MPDUs of A-MPDU 1 should have been received.
2979 this,
2980 0b00000111);
2983 this,
2984 0b00000000);
2987 this,
2988 0b00000000);
2989
2990 // All MPDUs of A-MPDU 2 should have been ignored.
2993 this,
2994 0b00000000);
2997 this,
2998 0b00000000);
3001 this,
3002 0b00000000);
3003
3005
3006 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3007 // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
3008 // power under RX sensitivity. The second A-MPDU is received 100 microseconds after the first
3009 // A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
3010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3011
3012 // A-MPDU 1
3015 this,
3016 rxPower - dB_u{100},
3017 1000);
3018
3019 // A-MPDU 2
3022 this,
3023 rxPower,
3024 1300);
3025
3026 // All MPDUs of A-MPDU 1 should have been ignored.
3029 this,
3030 0b00000000);
3033 this,
3034 0b00000000);
3037 this,
3038 0b00000000);
3039
3040 // All MPDUs of A-MPDU 2 should have been successfully received.
3043 this,
3044 0b00000111);
3047 this,
3048 0b00000000);
3051 this,
3052 0b00000000);
3053
3055
3056 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3057 // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
3058 // with power under RX sensitivity. The second A-MPDU is received 100 microseconds after the
3059 // first A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
3060 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3061
3062 // A-MPDU 1
3065 this,
3066 rxPower,
3067 1000);
3068
3069 // A-MPDU 2
3072 this,
3073 rxPower - dB_u{100},
3074 1300);
3075
3076 // All MPDUs of A-MPDU 1 should have been received.
3079 this,
3080 0b00000111);
3083 this,
3084 0b00000000);
3087 this,
3088 0b00000000);
3089
3090 // All MPDUs of A-MPDU 2 should have been ignored.
3093 this,
3094 0b00000000);
3097 this,
3098 0b00000000);
3101 this,
3102 0b00000000);
3103
3105
3106 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3107 // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
3108 // power under RX sensitivity. The second A-MPDU is received during the payload of MPDU #2.
3109 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3110
3111 // A-MPDU 1
3114 this,
3115 rxPower - dB_u{100},
3116 1000);
3117
3118 // A-MPDU 2
3121 this,
3122 rxPower,
3123 1300);
3124
3125 // All MPDUs of A-MPDU 1 should have been ignored.
3128 this,
3129 0b00000000);
3132 this,
3133 0b00000000);
3136 this,
3137 0b00000000);
3138
3139 // All MPDUs of A-MPDU 2 should have been successfully received.
3142 this,
3143 0b00000111);
3146 this,
3147 0b00000000);
3150 this,
3151 0b00000000);
3152
3154
3155 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3156 // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
3157 // with power under RX sensitivity. The second A-MPDU is received during the payload of MPDU #2.
3158 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3159
3160 // A-MPDU 1
3163 this,
3164 rxPower,
3165 1000);
3166
3167 // A-MPDU 2
3170 this,
3171 rxPower - dB_u{100},
3172 1300);
3173
3174 // All MPDUs of A-MPDU 1 should have been received.
3177 this,
3178 0b00000111);
3181 this,
3182 0b00000000);
3185 this,
3186 0b00000000);
3187
3188 // All MPDUs of A-MPDU 2 should have been ignored.
3191 this,
3192 0b00000000);
3195 this,
3196 0b00000000);
3199 this,
3200 0b00000000);
3201
3203
3204 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3205 // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3
3206 // dB higher. The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during
3207 // preamble detection).
3208 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3209
3210 // A-MPDU 1
3213 this,
3214 rxPower,
3215 1000);
3216
3217 // A-MPDU 2
3220 this,
3221 rxPower + dB_u{3.0},
3222 1300);
3223
3224 // All MPDUs of A-MPDU 1 should have been dropped.
3227 this,
3228 0b00000000);
3231 this,
3232 0b00000000);
3235 this,
3236 0b00000111);
3237
3238 // All MPDUs of A-MPDU 2 should have been received with errors.
3241 this,
3242 0b00000000);
3245 this,
3246 0b00000111);
3249 this,
3250 0b00000000);
3251
3253
3254 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3255 // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3256 // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble
3257 // detection).
3258 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3259
3260 // A-MPDU 1
3263 this,
3264 rxPower,
3265 1000);
3266
3267 // A-MPDU 2
3270 this,
3271 rxPower,
3272 1300);
3273
3274 // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
3277 this,
3278 0b00000000);
3281 this,
3282 0b00000000);
3285 this,
3286 0b00000111);
3287
3288 // All MPDUs of A-MPDU 2 should have been dropped as well.
3291 this,
3292 0b00000000);
3295 this,
3296 0b00000000);
3299 this,
3300 0b00000111);
3301
3303
3304 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3305 // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3
3306 // dB higher. The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during
3307 // preamble detection).
3308 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3309
3310 // A-MPDU 1
3313 this,
3314 rxPower + dB_u{3.0},
3315 1000);
3316
3317 // A-MPDU 2
3320 this,
3321 rxPower,
3322 1300);
3323
3324 // All MPDUs of A-MPDU 1 should have been received with errors.
3327 this,
3328 0b00000000);
3331 this,
3332 0b00000111);
3335 this,
3336 0b00000000);
3337
3338 // All MPDUs of A-MPDU 2 should have been dropped.
3341 this,
3342 0b00000000);
3345 this,
3346 0b00000000);
3349 this,
3350 0b00000111);
3351
3353
3354 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3355 // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3356 // 3 dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e.
3357 // during the frame capture window).
3358 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3359
3360 // A-MPDU 1
3363 this,
3364 rxPower,
3365 1000);
3366
3367 // A-MPDU 2
3370 this,
3371 rxPower + dB_u{3.0},
3372 1300);
3373
3374 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and
3375 // thus incorrect decoding of payload).
3378 this,
3379 0b00000000);
3382 this,
3383 0b00000000);
3386 this,
3387 0b00000111);
3388
3389 // All MPDUs of A-MPDU 2 should have been dropped (even though TX power is higher, it is not
3390 // high enough to get the PHY reception switched)
3393 this,
3394 0b00000000);
3397 this,
3398 0b00000000);
3401 this,
3402 0b00000111);
3403
3405
3406 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3407 // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3408 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame
3409 // capture window).
3410 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3411
3412 // A-MPDU 1
3415 this,
3416 rxPower,
3417 1000);
3418
3419 // A-MPDU 2
3422 this,
3423 rxPower,
3424 1300);
3425
3426 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and
3427 // thus incorrect decoding of payload).
3430 this,
3431 0b00000000);
3434 this,
3435 0b00000000);
3438 this,
3439 0b00000111);
3440
3441 // All MPDUs of A-MPDU 2 should have been dropped as well.
3444 this,
3445 0b00000000);
3448 this,
3449 0b00000000);
3452 this,
3453 0b00000111);
3454
3456
3457 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3458 // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3
3459 // dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during
3460 // the frame capture window).
3461 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3462
3463 // A-MPDU 1
3466 this,
3467 rxPower + dB_u{3.0},
3468 1000);
3469
3470 // A-MPDU 2
3473 this,
3474 rxPower,
3475 1300);
3476
3477 // All MPDUs of A-MPDU 1 should have been received with errors.
3480 this,
3481 0b00000000);
3484 this,
3485 0b00000111);
3488 this,
3489 0b00000000);
3490
3491 // All MPDUs of A-MPDU 2 should have been dropped.
3494 this,
3495 0b00000000);
3498 this,
3499 0b00000000);
3502 this,
3503 0b00000111);
3504
3506
3507 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3508 // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3509 // 6 dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e.
3510 // during the frame capture window).
3511 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3512
3513 // A-MPDU 1
3516 this,
3517 rxPower,
3518 1000);
3519
3520 // A-MPDU 2
3523 this,
3524 rxPower + dB_u{6.0},
3525 1300);
3526
3527 // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
3530 this,
3531 0b00000000);
3534 this,
3535 0b00000000);
3538 this,
3539 0b00000111);
3540
3541 // All MPDUs of A-MPDU 2 should have been successfully received
3544 this,
3545 0b00000111);
3548 this,
3549 0b00000000);
3552 this,
3553 0b00000000);
3554
3556
3557 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3558 // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3559 // dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during
3560 // the frame capture window).
3561 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3562
3563 // A-MPDU 1
3566 this,
3567 rxPower + dB_u{6.0},
3568 1000);
3569
3570 // A-MPDU 2
3573 this,
3574 rxPower,
3575 1300);
3576
3577 // All MPDUs of A-MPDU 1 should have been successfully received.
3580 this,
3581 0b00000111);
3584 this,
3585 0b00000000);
3588 this,
3589 0b00000000);
3590
3591 // All MPDUs of A-MPDU 2 should have been dropped.
3594 this,
3595 0b00000000);
3598 this,
3599 0b00000000);
3602 this,
3603 0b00000111);
3604
3606
3607 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3608 // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3609 // 6 dB higher. The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after
3610 // the frame capture window, but still during PHY header).
3611 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3612
3613 // A-MPDU 1
3616 this,
3617 rxPower,
3618 1000);
3619
3620 // A-MPDU 2
3623 this,
3624 rxPower + dB_u{6.0},
3625 1300);
3626
3627 // All MPDUs of A-MPDU 1 should have been received with errors.
3630 this,
3631 0b00000000);
3634 this,
3635 0b00000000);
3638 this,
3639 0b00000111);
3640
3641 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because
3642 // PHY is already in RX state).
3645 this,
3646 0b00000000);
3649 this,
3650 0b00000000);
3653 this,
3654 0b00000111);
3655
3657
3658 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3659 // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3660 // dB higher. The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after
3661 // the frame capture window, but still during PHY header).
3662 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3663
3664 // A-MPDU 1
3667 this,
3668 rxPower + dB_u{6.0},
3669 1000);
3670
3671 // A-MPDU 2
3674 this,
3675 rxPower,
3676 1300);
3677
3678 // All MPDUs of A-MPDU 1 should have been successfully received.
3681 this,
3682 0b00000111);
3685 this,
3686 0b00000000);
3689 this,
3690 0b00000000);
3691
3692 // All MPDUs of A-MPDU 2 should have been dropped.
3695 this,
3696 0b00000000);
3699 this,
3700 0b00000000);
3703 this,
3704 0b00000111);
3705
3707
3708 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3709 // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3710 // The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after the frame
3711 // capture window, but still during PHY header).
3712 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3713
3714 // A-MPDU 1
3717 this,
3718 rxPower,
3719 1000);
3720
3721 // A-MPDU 2
3724 this,
3725 rxPower,
3726 1300);
3727
3728 // All MPDUs of A-MPDU 1 should have been received with errors.
3731 this,
3732 0b00000000);
3735 this,
3736 0b00000000);
3739 this,
3740 0b00000111);
3741
3742 // All MPDUs of A-MPDU 2 should have been dropped.
3745 this,
3746 0b00000000);
3749 this,
3750 0b00000000);
3753 this,
3754 0b00000111);
3755
3757
3758 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3759 // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3760 // 6 dB higher. The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e.
3761 // during the payload of MPDU #1).
3762 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3763
3764 // A-MPDU 1
3767 this,
3768 rxPower,
3769 1000);
3770
3771 // A-MPDU 2
3774 this,
3775 rxPower + dB_u{6.0},
3776 1300);
3777
3778 // All MPDUs of A-MPDU 1 should have been received with errors.
3781 this,
3782 0b00000000);
3785 this,
3786 0b00000111);
3789 this,
3790 0b00000000);
3791
3792 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because
3793 // PHY is already in RX state).
3796 this,
3797 0b00000000);
3800 this,
3801 0b00000000);
3804 this,
3805 0b00000111);
3806
3808
3809 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3810 // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3811 // dB higher. The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during
3812 // the payload of MPDU #1).
3813 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3814
3815 // A-MPDU 1
3818 this,
3819 rxPower + dB_u{6.0},
3820 1000);
3821
3822 // A-MPDU 2
3825 this,
3826 rxPower,
3827 1300);
3828
3829 // All MPDUs of A-MPDU 1 should have been successfully received.
3832 this,
3833 0b00000111);
3836 this,
3837 0b00000000);
3840 this,
3841 0b00000000);
3842
3843 // All MPDUs of A-MPDU 2 should have been dropped.
3846 this,
3847 0b00000000);
3850 this,
3851 0b00000000);
3854 this,
3855 0b00000111);
3856
3858
3859 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3860 // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3861 // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the
3862 // payload of MPDU #1).
3863 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3864
3865 // A-MPDU 1
3868 this,
3869 rxPower,
3870 1000);
3871
3872 // A-MPDU 2
3875 this,
3876 rxPower,
3877 1300);
3878
3879 // All MPDUs of A-MPDU 1 should have been received with errors.
3882 this,
3883 0b00000000);
3886 this,
3887 0b00000111);
3890 this,
3891 0b00000000);
3892
3893 // All MPDUs of A-MPDU 2 should have been dropped.
3896 this,
3897 0b00000000);
3900 this,
3901 0b00000000);
3904 this,
3905 0b00000111);
3906
3908
3909 ///////////////////////////////////////////////////////////////////////////////
3910 // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3911 // The second A-MPDU is received during the payload of MPDU #2.
3912 ///////////////////////////////////////////////////////////////////////////////
3913
3914 // A-MPDU 1
3917 this,
3918 rxPower,
3919 1000);
3920
3921 // A-MPDU 2
3924 this,
3925 rxPower,
3926 1300);
3927
3928 // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
3929 // The two other MPDUs failed due to interference and are marked as failure (and dropped).
3932 this,
3933 0b00000001);
3936 this,
3937 0b00000110);
3940 this,
3941 0b00000000);
3942
3943 // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving
3944 // A-MPDU 1). The last MPDU of A-MPDU 2 is interference free (A-MPDU 1 transmission is finished)
3945 // but is dropped because its PHY preamble and header were not received.
3948 this,
3949 0b00000000);
3952 this,
3953 0b00000000);
3956 this,
3957 0b00000111);
3958
3960
3963}
3964
3965/**
3966 * @ingroup wifi-test
3967 * @ingroup tests
3968 *
3969 * @brief Unsupported Modulation Reception Test
3970 * This test creates a mixed network, in which an HE STA and a VHT
3971 * STA are associated to an HE AP and send uplink traffic. In the
3972 * simulated deployment the VHT STA's backoff will expire while the
3973 * HE STA is sending a packet, and the VHT STA will access the
3974 * channel anyway. This happens because the HE STA is using an HeMcs
3975 * that the VHT STA is not able to demodulate: the VHT STA will
3976 * correctly stop listening to the HE packet, but it will not update
3977 * its InterferenceHelper with the HE packet. Later on, this leads to
3978 * the STA wrongly assuming the medium is available when its back-off
3979 * expires in the middle of the HE packet. We detect that this is
3980 * happening by looking at the reason why the AP is failing to decode
3981 * the preamble from the VHT STA's transmission: if the reason is
3982 * that it's in RX already, the test fails. The test is based on
3983 * wifi-txop-test.cc.
3984 */
3986{
3987 public:
3990
3991 private:
3992 void DoRun() override;
3993
3994 /**
3995 * Callback invoked when PHY drops an incoming packet
3996 * @param context the context
3997 * @param packet the packet that was dropped
3998 * @param reason the reason the packet was dropped
3999 */
4000 void Dropped(std::string context, Ptr<const Packet> packet, WifiPhyRxfailureReason reason);
4001 /**
4002 * Check correctness of transmitted frames
4003 */
4004 void CheckResults();
4005
4006 uint16_t m_dropped{0}; ///< number of packets dropped by the AP because it was already receiving
4007};
4008
4010 : TestCase("Check correct behavior when a STA is receiving a transmission using an unsupported "
4011 "modulation")
4012{
4013}
4014
4015void
4017 Ptr<const Packet> packet,
4019{
4020 // Print if the test is executed through test-runner
4021 if (reason == RXING)
4022 {
4023 std::cout << "Dropped a packet because already receiving" << std::endl;
4024 m_dropped++;
4025 }
4026}
4027
4028void
4030{
4031 uint16_t m_nStations = 2; ///< number of stations
4032 NetDeviceContainer m_staDevices; ///< container for stations' NetDevices
4033 NetDeviceContainer m_apDevices; ///< container for AP's NetDevice
4034
4035 int64_t streamNumber = 100;
4036
4037 NodeContainer wifiApNode;
4038 wifiApNode.Create(1);
4039
4040 NodeContainer wifiStaNodes;
4041 wifiStaNodes.Create(m_nStations);
4042
4045 spectrumChannel->AddPropagationLossModel(lossModel);
4048 spectrumChannel->SetPropagationDelayModel(delayModel);
4049
4051 phy.SetChannel(spectrumChannel);
4052
4053 Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue(65535));
4054
4055 WifiHelper wifi;
4056 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
4057
4058 WifiMacHelper mac;
4059 mac.SetType("ns3::StaWifiMac",
4060 "QosSupported",
4061 BooleanValue(true),
4062 "Ssid",
4063 SsidValue(Ssid("non-existent-ssid")));
4064
4065 wifi.SetStandard(WIFI_STANDARD_80211ax);
4066 m_staDevices.Add(wifi.Install(phy, mac, wifiStaNodes.Get(0)));
4067 wifi.SetStandard(WIFI_STANDARD_80211ac);
4068 m_staDevices.Add(wifi.Install(phy, mac, wifiStaNodes.Get(1)));
4069
4070 wifi.SetStandard(WIFI_STANDARD_80211ax);
4071 mac.SetType("ns3::ApWifiMac",
4072 "QosSupported",
4073 BooleanValue(true),
4074 "Ssid",
4075 SsidValue(Ssid("wifi-backoff-ssid")),
4076 "BeaconInterval",
4078 "EnableBeaconJitter",
4079 BooleanValue(false));
4080
4081 m_apDevices = wifi.Install(phy, mac, wifiApNode);
4082
4083 // schedule association requests at different times
4084 Time init = MilliSeconds(100);
4086
4087 for (uint16_t i = 0; i < m_nStations; i++)
4088 {
4089 dev = DynamicCast<WifiNetDevice>(m_staDevices.Get(i));
4092 dev->GetMac(),
4093 Ssid("wifi-backoff-ssid"));
4094 }
4095
4096 // Assign fixed streams to random variables in use
4097 WifiHelper::AssignStreams(m_apDevices, streamNumber);
4098
4099 MobilityHelper mobility;
4101
4102 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
4103 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
4104 positionAlloc->Add(Vector(0.0, 1.0, 0.0));
4105 positionAlloc->Add(Vector(-1.0, 0.0, 0.0));
4106 mobility.SetPositionAllocator(positionAlloc);
4107
4108 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
4109 mobility.Install(wifiApNode);
4110 mobility.Install(wifiStaNodes);
4111
4112 // set the TXOP limit on BE AC
4113 dev = DynamicCast<WifiNetDevice>(m_apDevices.Get(0));
4114 PointerValue ptr;
4115 dev->GetMac()->GetAttribute("BE_Txop", ptr);
4116
4117 PacketSocketHelper packetSocket;
4118 packetSocket.Install(wifiApNode);
4119 packetSocket.Install(wifiStaNodes);
4120
4121 // UL Traffic
4122 for (uint16_t i = 0; i < m_nStations; i++)
4123 {
4124 PacketSocketAddress socket;
4125 socket.SetSingleDevice(m_staDevices.Get(0)->GetIfIndex());
4126 socket.SetPhysicalAddress(m_apDevices.Get(0)->GetAddress());
4127 socket.SetProtocol(1);
4129 client->SetAttribute("PacketSize", UintegerValue(1500));
4130 client->SetAttribute("MaxPackets", UintegerValue(200));
4131 client->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
4132 client->SetRemote(socket);
4133 wifiStaNodes.Get(i)->AddApplication(client);
4134 client->SetStartTime(MicroSeconds(400000));
4135 client->SetStopTime(Seconds(1));
4137 legacyStaClient->SetAttribute("PacketSize", UintegerValue(1500));
4138 legacyStaClient->SetAttribute("MaxPackets", UintegerValue(200));
4139 legacyStaClient->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
4140 legacyStaClient->SetRemote(socket);
4141 wifiStaNodes.Get(i)->AddApplication(legacyStaClient);
4142 legacyStaClient->SetStartTime(MicroSeconds(400000));
4143 legacyStaClient->SetStopTime(Seconds(1));
4145 server->SetLocal(socket);
4146 wifiApNode.Get(0)->AddApplication(server);
4147 server->SetStartTime(Seconds(0));
4148 server->SetStopTime(Seconds(1));
4149 }
4150
4151 // Trace dropped packets
4152 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
4154
4157
4158 CheckResults();
4159
4161}
4162
4163void
4165{
4166 NS_TEST_EXPECT_MSG_EQ(m_dropped, 0, "Dropped some packets unexpectedly");
4167}
4168
4169/**
4170 * @ingroup wifi-test
4171 * @ingroup tests
4172 *
4173 * @brief Unsupported Bandwidth Reception Test
4174 * This test checks whether a PHY receiving a PPDU sent over a channel width
4175 * larger than the one supported by the PHY is getting dropped at the expected
4176 * time. The expected time corresponds to the moment the PHY header indicating
4177 * the channel width used to transmit the PPDU is received. Since we are considering
4178 * 802.11ax for this test, this corresponds to the time HE-SIG-A is received.
4179 */
4181{
4182 public:
4184
4185 private:
4186 void DoSetup() override;
4187 void DoTeardown() override;
4188 void DoRun() override;
4189
4190 /**
4191 * Function to create a PPDU
4192 *
4193 * @param centerFreq the center frequency used for the transmission of the PPDU
4194 * @param bandwidth the bandwidth used for the transmission of the PPDU
4195 */
4196 void SendPpdu(MHz_u centerFreq, MHz_u bandwidth);
4197
4198 /**
4199 * Function called upon a PSDU received successfully
4200 * @param psdu the PSDU
4201 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
4202 * @param txVector the transmit vector
4203 * @param statusPerMpdu reception status per MPDU
4204 */
4206 RxSignalInfo rxSignalInfo,
4207 const WifiTxVector& txVector,
4208 const std::vector<bool>& statusPerMpdu);
4209
4210 /**
4211 * Function called upon a PSDU received unsuccessfully
4212 * @param psdu the PSDU
4213 */
4214 void RxFailure(Ptr<const WifiPsdu> psdu);
4215
4216 /**
4217 * Function called upon a PSDU dropped by the PHY
4218 * @param packet the packet that was dropped
4219 * @param reason the reason the packet was dropped
4220 */
4222
4223 /**
4224 * Check the reception results
4225 * @param expectedCountRxSuccess the expected number of RX success
4226 * @param expectedCountRxFailure the expected number of RX failure
4227 * @param expectedCountRxDropped the expected number of RX drop
4228 * @param expectedLastRxSucceeded the expected time the last RX success occurred or std::nullopt
4229 * if the expected number of RX success is not strictly positive \param expectedLastRxFailed the
4230 * expected time the last RX failure occurred or std::nullopt if the expected number of RX
4231 * failure is not strictly positive \param expectedLastRxDropped the expected time the last RX
4232 * drop occurred or std::nullopt if the expected number of RX drop is not strictly positive
4233 */
4234 void CheckRx(uint32_t expectedCountRxSuccess,
4235 uint32_t expectedCountRxFailure,
4236 uint32_t expectedCountRxDropped,
4237 std::optional<Time> expectedLastRxSucceeded,
4238 std::optional<Time> expectedLastRxFailed,
4239 std::optional<Time> expectedLastRxDropped);
4240
4241 uint32_t m_countRxSuccess; ///< count RX success
4242 uint32_t m_countRxFailure; ///< count RX failure
4243 uint32_t m_countRxDropped; ///< count RX drop
4244
4245 std::optional<Time> m_lastRxSucceeded; ///< time of last RX success, if any
4246 std::optional<Time> m_lastRxFailed; ///< time of last RX failure, if any
4247 std::optional<Time> m_lastRxDropped; ///< time of last RX drop, if any
4248
4251};
4252
4254 : TestCase("Check correct behavior when a STA is receiving a transmission using an unsupported "
4255 "bandwidth"),
4259 m_lastRxSucceeded(std::nullopt),
4260 m_lastRxFailed(std::nullopt),
4261 m_lastRxDropped(std::nullopt)
4262{
4263}
4264
4265void
4267{
4268 auto txVector = WifiTxVector(HePhy::GetHeMcs0(),
4271 NanoSeconds(800),
4272 1,
4273 1,
4274 0,
4275 bandwidth,
4276 false);
4277
4278 auto pkt = Create<Packet>(1000);
4279 WifiMacHeader hdr;
4280
4282 hdr.SetQosTid(0);
4283
4284 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
4285 Time txDuration =
4286 SpectrumWifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, m_rxPhy->GetPhyBand());
4287
4288 auto ppdu = Create<HePpdu>(psdu, txVector, m_txPhy->GetOperatingChannel(), txDuration, 0);
4289
4290 auto txPowerSpectrum =
4292 bandwidth,
4293 DbmToW(dBm_u{-50}),
4294 bandwidth);
4295
4296 auto txParams = Create<WifiSpectrumSignalParameters>();
4297 txParams->psd = txPowerSpectrum;
4298 txParams->txPhy = nullptr;
4299 txParams->duration = txDuration;
4300 txParams->ppdu = ppdu;
4301
4302 m_rxPhy->StartRx(txParams, nullptr);
4303}
4304
4305void
4307 RxSignalInfo rxSignalInfo,
4308 const WifiTxVector& txVector,
4309 const std::vector<bool>& statusPerMpdu)
4310{
4311 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
4314}
4315
4316void
4323
4324void
4332
4333void
4335 uint32_t expectedCountRxFailure,
4336 uint32_t expectedCountRxDropped,
4337 std::optional<Time> expectedLastRxSucceeded,
4338 std::optional<Time> expectedLastRxFailed,
4339 std::optional<Time> expectedLastRxDropped)
4340{
4342 expectedCountRxSuccess,
4343 "Didn't receive right number of successful packets");
4344
4346 expectedCountRxFailure,
4347 "Didn't receive right number of unsuccessful packets");
4348
4350 expectedCountRxDropped,
4351 "Didn't receive right number of dropped packets");
4352
4353 if (expectedCountRxSuccess > 0)
4354 {
4355 NS_ASSERT(m_lastRxSucceeded.has_value());
4356 NS_ASSERT(expectedLastRxSucceeded.has_value());
4358 expectedLastRxSucceeded.value(),
4359 "Didn't receive the last successful packet at the expected time");
4360 }
4361
4362 if (expectedCountRxFailure > 0)
4363 {
4364 NS_ASSERT(m_lastRxFailed.has_value());
4365 NS_ASSERT(expectedLastRxFailed.has_value());
4367 expectedLastRxFailed.value(),
4368 "Didn't receive the last unsuccessful packet at the expected time");
4369 }
4370
4371 if (expectedCountRxDropped > 0)
4372 {
4373 NS_ASSERT(m_lastRxDropped.has_value());
4374 NS_ASSERT(expectedLastRxDropped.has_value());
4376 expectedLastRxDropped.value(),
4377 "Didn't drop the last filtered packet at the expected time");
4378 }
4379}
4380
4381void
4383{
4388 auto rxInterferenceHelper = CreateObject<InterferenceHelper>();
4389 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
4390 auto rxErrorRateModel = CreateObject<NistErrorRateModel>();
4391 m_rxPhy->SetErrorRateModel(rxErrorRateModel);
4392 m_rxPhy->SetDevice(dev);
4393 m_rxPhy->AddChannel(spectrumChannel);
4394 m_rxPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4395 dev->SetPhy(m_rxPhy);
4396 node->AddDevice(dev);
4397
4398 m_rxPhy->SetReceiveOkCallback(
4400 m_rxPhy->SetReceiveErrorCallback(
4402 m_rxPhy->TraceConnectWithoutContext(
4403 "PhyRxDrop",
4405
4407 auto txInterferenceHelper = CreateObject<InterferenceHelper>();
4408 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
4409 auto txErrorRateModel = CreateObject<NistErrorRateModel>();
4410 m_txPhy->SetErrorRateModel(txErrorRateModel);
4411 m_txPhy->AddChannel(spectrumChannel);
4412 m_txPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4413}
4414
4415void
4417{
4418 m_rxPhy->Dispose();
4419 m_rxPhy = nullptr;
4420
4421 m_txPhy->Dispose();
4422 m_txPhy = nullptr;
4423}
4424
4425void
4427{
4430
4431 int64_t streamNumber = 0;
4432 m_rxPhy->AssignStreams(streamNumber);
4433
4434 // Case 1: the PHY is operating on channel 36 (20 MHz) and receives a 40 MHz PPDU (channel 38).
4435 // The PPDU should be dropped once HE-SIG-A is successfully received, since it contains
4436 // indication about the BW used for the transmission and the PHY shall detect it is larger than
4437 // its operating BW.
4438 m_txPhy->SetOperatingChannel(WifiPhy::ChannelTuple{38, 40, WIFI_PHY_BAND_5GHZ, 0});
4439 m_rxPhy->SetOperatingChannel(WifiPhy::ChannelTuple{36, 20, WIFI_PHY_BAND_5GHZ, 0});
4440
4443 this,
4444 MHz_u{5190},
4445 MHz_u{40});
4446
4447 auto heSigAExpectedRxTime = Seconds(1) + MicroSeconds(32);
4450 this,
4451 0,
4452 0,
4453 1,
4454 std::nullopt,
4455 std::nullopt,
4456 heSigAExpectedRxTime);
4457
4458 // TODO: this test can be extended with other scenarios
4459
4462}
4463
4464/**
4465 * @ingroup wifi-test
4466 * @ingroup tests
4467 *
4468 * @brief Primary 20 MHz Covered By Ppdu Test
4469 * This test checks whether the functions WifiPpdu::DoesOverlapChannel and
4470 * WifiPpdu::DoesCoverChannel are returning the expected results.
4471 */
4473{
4474 public:
4476
4477 private:
4478 void DoSetup() override;
4479 void DoRun() override;
4480 void DoTeardown() override;
4481
4482 /**
4483 * Function to create a PPDU
4484 *
4485 * @param ppduCenterFreq the center frequency used for the transmission of the PPDU
4486 * @return the created PPDU
4487 */
4488 Ptr<HePpdu> CreatePpdu(MHz_u ppduCenterFreq);
4489
4490 /**
4491 * Run one function
4492 *
4493 * @param band the PHY band to use
4494 * @param phyCenterFreq the operating center frequency of the PHY
4495 * @param p20Index the primary20 index
4496 * @param ppduCenterFreq the center frequency used for the transmission of the PPDU
4497 * @param expectedP20Overlap flag whether the primary 20 MHz channel is expected to be fully
4498 * covered by the bandwidth of the incoming PPDU
4499 * @param expectedP20Covered flag whether the
4500 * primary 20 MHz channel is expected to overlap with the bandwidth of the incoming PPDU
4501 */
4502 void RunOne(WifiPhyBand band,
4503 MHz_u phyCenterFreq,
4504 uint8_t p20Index,
4505 MHz_u ppduCenterFreq,
4506 bool expectedP20Overlap,
4507 bool expectedP20Covered);
4508
4511};
4512
4514 : TestCase("Check correct detection of whether P20 is fully covered (hence it can be received) "
4515 "or overlaps with the bandwidth of an incoming PPDU")
4516{
4517}
4518
4521{
4522 const auto& channelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
4523 ppduCenterFreq,
4524 MHz_u{0},
4526 m_rxPhy->GetPhyBand()));
4527 m_txPhy->SetOperatingChannel(
4528 WifiPhy::ChannelTuple{channelInfo.number, channelInfo.width, channelInfo.band, 0});
4529 auto txVector = WifiTxVector(HePhy::GetHeMcs7(),
4532 NanoSeconds(800),
4533 1,
4534 1,
4535 0,
4536 channelInfo.width,
4537 false);
4538
4539 auto pkt = Create<Packet>(1000);
4541
4542 auto psdu = Create<WifiPsdu>(pkt, hdr);
4543 auto txDuration =
4544 SpectrumWifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, channelInfo.band);
4545
4546 return Create<HePpdu>(psdu, txVector, m_txPhy->GetOperatingChannel(), txDuration, 0);
4547}
4548
4549void
4551{
4553 auto rxInterferenceHelper = CreateObject<InterferenceHelper>();
4554 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
4555 auto rxErrorRateModel = CreateObject<NistErrorRateModel>();
4556 m_rxPhy->SetErrorRateModel(rxErrorRateModel);
4558 m_rxPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4559
4561 auto txInterferenceHelper = CreateObject<InterferenceHelper>();
4562 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
4563 auto txErrorRateModel = CreateObject<NistErrorRateModel>();
4564 m_txPhy->SetErrorRateModel(txErrorRateModel);
4566 m_txPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4567}
4568
4569void
4571{
4572 m_rxPhy->Dispose();
4573 m_rxPhy = nullptr;
4574 m_txPhy->Dispose();
4575 m_txPhy = nullptr;
4576}
4577
4578void
4580 MHz_u phyCenterFreq,
4581 uint8_t p20Index,
4582 MHz_u ppduCenterFreq,
4583 bool expectedP20Overlap,
4584 bool expectedP20Covered)
4585{
4586 const auto& channelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
4587 phyCenterFreq,
4588 MHz_u{0},
4590 band));
4591
4592 m_rxPhy->SetOperatingChannel(
4593 WifiPhy::ChannelTuple{channelInfo.number, channelInfo.width, channelInfo.band, p20Index});
4594 auto p20CenterFreq = m_rxPhy->GetOperatingChannel().GetPrimaryChannelCenterFrequency(MHz_u{20});
4595 auto p20MinFreq = p20CenterFreq - MHz_u{10};
4596 auto p20MaxFreq = p20CenterFreq + MHz_u{10};
4597
4598 auto ppdu = CreatePpdu(ppduCenterFreq);
4599
4600 auto p20Overlap = ppdu->DoesOverlapChannel(p20MinFreq, p20MaxFreq);
4601 NS_TEST_ASSERT_MSG_EQ(p20Overlap,
4602 expectedP20Overlap,
4603 "PPDU is " << (expectedP20Overlap ? "expected" : "not expected")
4604 << " to overlap with the P20");
4605
4606 auto p20Covered = m_rxPhy->GetPhyEntity(WIFI_STANDARD_80211ax)
4607 ->CanStartRx(ppdu); // CanStartRx returns true is the P20 is fully covered
4608 NS_TEST_ASSERT_MSG_EQ(p20Covered,
4609 expectedP20Covered,
4610 "PPDU is " << (expectedP20Covered ? "expected" : "not expected")
4611 << " to cover the whole P20");
4612}
4613
4614void
4616{
4617 /*
4618 * Receiver PHY Operating Channel: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4619 * Transmitted 20 MHz PPDU: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4620 * Overlap with primary 20 MHz: yes
4621 * Primary 20 MHz fully covered: yes
4622 */
4623 RunOne(WIFI_PHY_BAND_2_4GHZ, MHz_u{2427}, 0, MHz_u{2427}, true, true);
4624
4625 /*
4626 * Receiver PHY Operating Channel: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4627 * Transmitted 20 MHz PPDU: 2.4 GHz Channel 6 (2427 MHz – 2447 MHz)
4628 * Overlap with primary 20 MHz: yes
4629 * Primary 20 MHz fully covered: no
4630 */
4631 RunOne(WIFI_PHY_BAND_2_4GHZ, MHz_u{2427}, 0, MHz_u{2437}, true, false);
4632
4633 /*
4634 * Receiver PHY Operating Channel: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4635 * Transmitted 40 MHz PPDU: 5 GHz Channel 38 (5170 MHz – 5210 MHz)
4636 * Overlap with primary 20 MHz: yes
4637 * Primary 20 MHz fully covered: yes
4638 */
4639 RunOne(WIFI_PHY_BAND_5GHZ, MHz_u{5180}, 0, MHz_u{5190}, true, true);
4640
4641 /*
4642 * Receiver PHY Operating Channel: 5 GHz Channel 36 (5170 MHz–5190 MHz)
4643 * Transmitted 20 MHz PPDU: 5 GHz Channel 40 (5190 MHz – 5210 MHz)
4644 * Overlap with primary 20 MHz: no
4645 * Primary 20 MHz fully covered: no
4646 */
4647 RunOne(WIFI_PHY_BAND_5GHZ, MHz_u{5180}, 0, MHz_u{5200}, false, false);
4648
4649 /*
4650 * Receiver PHY Operating Channel: 5 GHz Channel 38 (5170 MHz – 5210 MHz) with P20 index 0
4651 * Transmitted 20 MHz PPDU: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4652 * Overlap with primary 20 MHz: yes
4653 * Primary 20 MHz fully covered: yes
4654 */
4655 RunOne(WIFI_PHY_BAND_5GHZ, MHz_u{5190}, 0, MHz_u{5180}, true, true);
4656
4657 /*
4658 * Receiver PHY Operating Channel: 5 GHz Channel 38 (5170 MHz – 5210 MHz) with P20 index 1
4659 * Transmitted 20 MHz PPDU: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4660 * Overlap with primary 20 MHz: no
4661 * Primary 20 MHz fully covered: no
4662 */
4663 RunOne(WIFI_PHY_BAND_5GHZ, MHz_u{5190}, 1, MHz_u{5180}, false, false);
4664
4666}
4667
4668/**
4669 * @ingroup wifi-test
4670 * @ingroup tests
4671 *
4672 * @brief This test verifies the correct function of the WifiBandwidthFilter. 2 SpectrumWifiPhy are
4673 * setup and connected on the same spectrum channel. The test will
4674 * send a packet over the channel and if the signal plus guardband overlaps the channel the
4675 * filter will not discard the signal but if there is no overlap the filter will filter it out.
4676 */
4678{
4679 public:
4680 /**
4681 * Constructor
4682 *
4683 * @param channel channel to be used by transmitter
4684 * @param expectedValue expected number of received packets
4685 */
4686 TestSpectrumChannelWithBandwidthFilter(uint8_t channel, uint16_t expectedValue);
4687
4688 protected:
4689 void DoSetup() override;
4690 void DoTeardown() override;
4691
4692 private:
4693 /**
4694 * Callback invoked when the PHY model starts to process a signal
4695 *
4696 * @param signal the arriving signal
4697 * @param senderNodeId node Id of the sender of the signal
4698 * @param rxPower received signal power
4699 * @param duration signal duration
4700 */
4702 uint32_t senderNodeId,
4703 double rxPower,
4704 Time duration);
4705
4706 /**
4707 * Send function (sends a single packet)
4708 */
4709 void Send() const;
4710
4711 /**
4712 * Event scheduled at end of simulation for validation
4713 *
4714 * @param expectedValue expected number of receive events
4715 */
4716 void CheckRxPacketCount(uint16_t expectedValue);
4717
4718 void DoRun() override;
4719
4720 Ptr<SpectrumWifiPhy> m_tx{nullptr}; ///< transmit function
4721 Ptr<SpectrumWifiPhy> m_rx{nullptr}; ///< receive function
4722 uint32_t m_countRxBegin{0}; ///< count of receive events
4723 uint8_t m_channel{36}; ///< channel for packet transmission
4724 uint16_t m_expectedValue{0}; ///< expected count of receive events
4725};
4726
4728 uint8_t channel,
4729 uint16_t expectedValue)
4730 : TestCase("Test for early discard of signal in single-model-spectrum-channel::StartTx()"),
4731 m_channel(channel),
4732 m_expectedValue(expectedValue)
4733{
4734}
4735
4736void
4738{
4742 NanoSeconds(800),
4743 1,
4744 1,
4745 0,
4746 MHz_u{20},
4747 false);
4748
4749 Ptr<Packet> pkt = Create<Packet>(1000);
4750 WifiMacHeader hdr;
4751
4753 hdr.SetQosTid(0);
4754
4755 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
4756 m_tx->Send(psdu, txVector);
4757}
4758
4759void
4761{
4763 expectedValue,
4764 "Received a different amount of packets than expected.");
4765}
4766
4767void
4769 [[maybe_unused]],
4770 uint32_t senderNodeId [[maybe_unused]],
4771 double rxPower [[maybe_unused]],
4772 Time duration [[maybe_unused]])
4773{
4774 NS_LOG_FUNCTION(this << signal << senderNodeId << rxPower << duration);
4776}
4777
4778void
4780{
4781 NS_LOG_FUNCTION(this);
4783
4785 channel->AddSpectrumTransmitFilter(wifiFilter);
4786
4790 m_tx->SetDevice(dev);
4791 m_tx->SetTxPowerStart(dBm_u{20});
4792 m_tx->SetTxPowerEnd(dBm_u{20});
4793
4794 Ptr<Node> nodeRx = CreateObject<Node>();
4797 m_rx->SetDevice(devRx);
4798
4800 m_tx->SetInterferenceHelper(interferenceTx);
4802 m_tx->SetErrorRateModel(errorTx);
4803
4805 m_rx->SetInterferenceHelper(interferenceRx);
4807 m_rx->SetErrorRateModel(errorRx);
4808
4809 m_tx->AddChannel(channel);
4810 m_rx->AddChannel(channel);
4811
4812 m_tx->ConfigureStandard(WIFI_STANDARD_80211ax);
4813 m_rx->ConfigureStandard(WIFI_STANDARD_80211ax);
4814
4815 dev->SetPhy(m_tx);
4816 node->AddDevice(dev);
4817 devRx->SetPhy(m_rx);
4818 nodeRx->AddDevice(devRx);
4819
4820 m_rx->TraceConnectWithoutContext(
4821 "SignalArrival",
4823}
4824
4825void
4827{
4828 m_tx->Dispose();
4829 m_rx->Dispose();
4830}
4831
4832void
4848
4849/**
4850 * @ingroup wifi-test
4851 * @ingroup tests
4852 *
4853 * @brief This test verifies that the WifiPhyRxfailureReason distinguishes between two cases: 1) a
4854 * drop due to transmitting during the signal detection interval, and 2) a drop due to transmitting
4855 * after the receiver has detected a preamble but is waiting for the end of the preamble. 2
4856 * SpectrumWifiPhy are setup and connected on the same spectrum channel. The test will send a packet
4857 * over the channel and after a controlled amount of transmit delay (to check both cases) the
4858 * receiver of the packet will send its own packet. If delay is less than preamble detection period,
4859 * the signal detection should be aborted by transmission. If delay is greater than preamble
4860 * detection period, the signal reception should be aborted by transmission.
4861 */
4863{
4864 public:
4865 /**
4866 * Constructor
4867 *
4868 * @param delay delay in microseconds to send second packet
4869 * @param expectedReason expected failure reason
4870 */
4871 TestPhyDropDueToTx(Time delay, WifiPhyRxfailureReason expectedReason);
4872
4873 protected:
4874 void DoSetup() override;
4875 void DoTeardown() override;
4876
4877 private:
4878 /**
4879 * RX dropped function
4880 * @param p the packet
4881 * @param reason the reason
4882 */
4884
4885 /**
4886 * Send function (sends a single packet)
4887 * @param phy the WifiPhy object to send the packet
4888 */
4889 void Send(Ptr<WifiPhy> phy) const;
4890
4891 /**
4892 * Event scheduled at end of simulation for validation
4893 */
4894 void CheckDropReason();
4895
4896 void DoRun() override;
4897
4898 Ptr<SpectrumWifiPhy> m_phyA{nullptr}; ///< transmit function
4899 Ptr<SpectrumWifiPhy> m_phyB{nullptr}; ///< transmit/receive function
4900
4901 Time m_delay; ///< delay between transmissions in MicroSeconds
4902
4903 WifiPhyRxfailureReason m_expectedReason; ///< expected WifiPhyRxfailureReason
4904 WifiPhyRxfailureReason m_observedReason; ///< observed WifiPhyRxfailureReason
4905};
4906
4908 : TestCase("Test for correct WifiPhyRxfailureReason from PhyRxDrop trace"),
4909 m_delay(delay),
4910 m_expectedReason(expectedReason)
4911{
4912}
4913
4914void
4916{
4917 const auto txVector = WifiTxVector(HePhy::GetHeMcs0(),
4920 NanoSeconds(800),
4921 1,
4922 1,
4923 0,
4924 MHz_u{20},
4925 false);
4926
4927 auto pkt = Create<Packet>(1000);
4928 WifiMacHeader hdr;
4929
4931 hdr.SetQosTid(0);
4932
4933 auto psdu = Create<WifiPsdu>(pkt, hdr);
4934 phy->Send(psdu, txVector);
4935}
4936
4937void
4939{
4942 "Packet was dropped due to the wrong drop reason reported ");
4943}
4944
4945void
4951
4952void
4954{
4955 NS_LOG_FUNCTION(this);
4957
4958 auto node = CreateObject<Node>();
4959 auto devA = CreateObject<WifiNetDevice>();
4961 m_phyA->SetDevice(devA);
4962 m_phyA->SetTxPowerStart(dBm_u{20});
4963 m_phyA->SetTxPowerEnd(dBm_u{20});
4964
4965 auto nodeRx = CreateObject<Node>();
4966 auto devB = CreateObject<WifiNetDevice>();
4968 m_phyB->SetDevice(devB);
4969 m_phyB->SetTxPowerStart(dBm_u{20});
4970 m_phyB->SetTxPowerEnd(dBm_u{20});
4971
4972 auto interferenceTx = CreateObject<InterferenceHelper>();
4973 m_phyA->SetInterferenceHelper(interferenceTx);
4974 auto errorTx = CreateObject<NistErrorRateModel>();
4975 m_phyA->SetErrorRateModel(errorTx);
4976
4977 auto interferenceRx = CreateObject<InterferenceHelper>();
4978 m_phyB->SetInterferenceHelper(interferenceRx);
4979 auto errorRx = CreateObject<NistErrorRateModel>();
4980 m_phyB->SetErrorRateModel(errorRx);
4981
4982 m_phyA->AddChannel(channel);
4983 m_phyB->AddChannel(channel);
4984
4985 m_phyA->ConfigureStandard(WIFI_STANDARD_80211ax);
4986 m_phyA->SetOperatingChannel(WifiPhy::ChannelTuple{36, 0, WIFI_PHY_BAND_5GHZ, 0});
4987
4988 m_phyB->ConfigureStandard(WIFI_STANDARD_80211ax);
4989 m_phyB->SetOperatingChannel(WifiPhy::ChannelTuple{36, 0, WIFI_PHY_BAND_5GHZ, 0});
4990
4991 devA->SetPhy(m_phyA);
4992 node->AddDevice(devA);
4993 devB->SetPhy(m_phyB);
4994 nodeRx->AddDevice(devB);
4995
4996 m_phyB->TraceConnectWithoutContext("PhyRxDrop",
4998}
4999
5000void
5002{
5003 m_phyA->Dispose();
5004 m_phyB->Dispose();
5005}
5006
5007void
5009{
5010 NS_LOG_FUNCTION(this);
5011
5014
5015 // Upon transmitting the second packet from m_phyB, the reception from
5016 // m_phyA will be immediately dropped. Check the drop reason a short
5017 // while later (1 ns is sufficient)
5019
5022}
5023
5024/**
5025 * @ingroup wifi-test
5026 * @ingroup tests
5027 *
5028 * @brief wifi PHY reception Test Suite
5029 */
5031{
5032 public:
5034};
5035
5037 : TestSuite("wifi-phy-reception", Type::UNIT)
5038{
5047 // The below three test cases are related. The test involves a receiver tuned to
5048 // channel 36 and a transmitter sending on channels 36, 40, and 44, respectively.
5049 // The second argument corresponds to the number of signals expected to be received.
5050 // Signals on channel 36 and 40 will fall within the receiver bandwidth, while
5051 // a signal on channel 44 will fall completely outside and will be filtered.
5058 // 4 Microseconds is just less than the preamble detection period since there is no
5059 // propagation delay model
5064}
5065
A-MPDU reception test.
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 RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
RX success function.
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, const WifiTxVector &txVector, const 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 DoRun() override
Implementation to actually run this TestCase.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Spectrum wifi receive success function.
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, const WifiTxVector &txVector, const 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 RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Function called upon a PSDU received successfully.
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 unsuccessfully.
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
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
AttributeValue implementation for Boolean.
Definition boolean.h:26
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.
Definition pointer.h:37
Ptr< T > Get() const
Definition pointer.h:224
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
static void Run()
Run the simulation.
Definition simulator.cc:161
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:614
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
AttributeValue implementation for Ssid.
Definition ssid.h:85
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
@ QUICK
Fast test.
Definition test.h:1057
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
Type
Type of test.
Definition test.h:1271
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
AttributeValue implementation for Time.
Definition nstime.h:1375
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:527
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition wifi-phy.cc:1574
WifiChannelConfig::SegmentWithoutUnits ChannelTuple
kept for backward compatibility, can be deprecated when using strong types
Definition wifi-phy.h:954
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=GetFrequencyChannels().begin())
Find the first frequency segment matching the specified parameters.
This objects implements the PHY state machine of the Wifi device.
static Ptr< SpectrumValue > CreateHeOfdmTxPowerSpectralDensity(MHz_u centerFrequency, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=dBr_u{-20}, dBr_u minOuterband=dBr_u{-28}, dBr_u lowestPoint=dBr_u{-40}, const std::vector< bool > &puncturedSubchannels={})
Create a transmit power spectral density corresponding to OFDM High Efficiency (HE/EHT) (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
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:690
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:886
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:970
#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:194
#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:627
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:133
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:240
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1307
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1324
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1290
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.
@ IDLE
The PHY layer is IDLE.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ RX
The PHY layer is receiving a packet.
static constexpr uint8_t WIFI_MIN_TX_PWR_LEVEL
minimum TX power level value
double MHz_u
MHz weak type.
Definition wifi-units.h:31
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
double dBm_u
dBm weak type
Definition wifi-units.h:27
@ WIFI_MAC_QOSDATA
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:32
double dB_u
dB weak type
Definition wifi-units.h:28
const Time DEFAULT_BEACON_INTERVAL
Default Beacon interval.
STL namespace.
static const uint8_t CHANNEL_NUMBER
static const MHz_u GUARD_WIDTH
static const MHz_u CHANNEL_WIDTH
RxSignalInfo structure containing info on the received signal.
Definition wifi-types.h:84
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.