A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-phy-reception-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7 */
8
9#include "ns3/ampdu-tag.h"
10#include "ns3/ap-wifi-mac.h"
11#include "ns3/boolean.h"
12#include "ns3/config.h"
13#include "ns3/double.h"
14#include "ns3/he-phy.h"
15#include "ns3/he-ppdu.h"
16#include "ns3/interference-helper.h"
17#include "ns3/log.h"
18#include "ns3/mobility-helper.h"
19#include "ns3/mpdu-aggregator.h"
20#include "ns3/multi-model-spectrum-channel.h"
21#include "ns3/nist-error-rate-model.h"
22#include "ns3/packet-socket-address.h"
23#include "ns3/packet-socket-client.h"
24#include "ns3/packet-socket-helper.h"
25#include "ns3/packet-socket-server.h"
26#include "ns3/pointer.h"
27#include "ns3/rng-seed-manager.h"
28#include "ns3/simple-frame-capture-model.h"
29#include "ns3/single-model-spectrum-channel.h"
30#include "ns3/spectrum-wifi-helper.h"
31#include "ns3/spectrum-wifi-phy.h"
32#include "ns3/test.h"
33#include "ns3/threshold-preamble-detection-model.h"
34#include "ns3/wifi-bandwidth-filter.h"
35#include "ns3/wifi-mac-header.h"
36#include "ns3/wifi-mpdu.h"
37#include "ns3/wifi-net-device.h"
38#include "ns3/wifi-psdu.h"
39#include "ns3/wifi-spectrum-phy-interface.h"
40#include "ns3/wifi-spectrum-signal-parameters.h"
41#include "ns3/wifi-spectrum-value-helper.h"
42#include "ns3/wifi-utils.h"
43
44#include <optional>
45
46using namespace ns3;
47
48NS_LOG_COMPONENT_DEFINE("WifiPhyReceptionTest");
49
50static const uint8_t CHANNEL_NUMBER = 36;
51static const MHz_u FREQUENCY{5180};
52static const MHz_u CHANNEL_WIDTH{20};
53static const MHz_u GUARD_WIDTH = CHANNEL_WIDTH; // expanded to channel width to model spectrum mask
54
55/**
56 * @ingroup wifi-test
57 * @ingroup tests
58 *
59 * @brief Wifi Phy Reception Test base class
60 */
62{
63 public:
64 /**
65 * Constructor
66 *
67 * @param test_name the test name
68 */
69 WifiPhyReceptionTest(std::string test_name);
70 /**
71 * Destructor
72 */
73 ~WifiPhyReceptionTest() override = default;
74
75 protected:
76 void DoSetup() override;
77 void DoTeardown() override;
78
79 /**
80 * Send packet function
81 * @param rxPower the transmit power
82 * @param packetSize the size of the packet in bytes
83 * @param mcs the MCS to transmit the packet
84 */
85 void SendPacket(dBm_u rxPower, uint32_t packetSize, uint8_t mcs);
86
87 /**
88 * Schedule now to check the PHY state
89 * @param expectedState the expected PHY state
90 */
91 void CheckPhyState(WifiPhyState expectedState);
92 /**
93 * Check the PHY state now
94 * @param expectedState the expected PHY state
95 */
96 void DoCheckPhyState(WifiPhyState expectedState);
97
99 uint64_t m_uid{0}; //!< the UID to use for the PPDU
100};
101
103 : TestCase{test_name}
104{
105}
106
107void
109{
111 0,
113 NanoSeconds(800),
114 1,
115 1,
116 0,
117 MHz_u{20},
118 false);
119
121 WifiMacHeader hdr;
122
124 hdr.SetQosTid(0);
125
126 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
127 Time txDuration =
128 SpectrumWifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
129
130 Ptr<WifiPpdu> ppdu =
131 Create<HePpdu>(psdu, txVector, m_phy->GetOperatingChannel(), txDuration, m_uid++);
132
133 Ptr<SpectrumValue> txPowerSpectrum =
136 DbmToW(rxPower),
138
140 txParams->psd = txPowerSpectrum;
141 txParams->txPhy = nullptr;
142 txParams->duration = txDuration;
143 txParams->ppdu = ppdu;
144
145 m_phy->StartRx(txParams, nullptr);
146}
147
148void
150{
151 // This is needed to make sure PHY state will be checked as the last event if a state change
152 // occurred at the exact same time as the check
154}
155
156void
158{
159 WifiPhyState currentState;
160 PointerValue ptr;
161 m_phy->GetAttribute("State", ptr);
163 currentState = state->GetState();
164 NS_LOG_FUNCTION(this << currentState);
165 NS_TEST_ASSERT_MSG_EQ(currentState,
166 expectedState,
167 "PHY State " << currentState << " does not match expected state "
168 << expectedState << " at " << Simulator::Now());
169}
170
171void
173{
179 m_phy->SetInterferenceHelper(interferenceHelper);
181 m_phy->SetErrorRateModel(error);
182 m_phy->SetDevice(dev);
183 m_phy->AddChannel(spectrumChannel);
184 m_phy->SetOperatingChannel(WifiPhy::ChannelTuple{CHANNEL_NUMBER, 0, WIFI_PHY_BAND_5GHZ, 0});
185 m_phy->ConfigureStandard(WIFI_STANDARD_80211ax);
186 dev->SetPhy(m_phy);
187 node->AddDevice(dev);
188}
189
190void
192{
193 m_phy->Dispose();
194 m_phy = nullptr;
195}
196
197/**
198 * @ingroup wifi-test
199 * @ingroup tests
200 *
201 * @brief Preamble detection test w/o frame capture
202 */
204{
205 public:
207
208 protected:
209 void DoSetup() override;
210
211 /**
212 * Spectrum wifi receive success function
213 * @param psdu the PSDU
214 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
215 * @param txVector the transmit vector
216 * @param statusPerMpdu reception status per MPDU
217 */
219 RxSignalInfo rxSignalInfo,
220 const WifiTxVector& txVector,
221 const std::vector<bool>& statusPerMpdu);
222 /**
223 * Spectrum wifi receive failure function
224 * @param psdu the PSDU
225 */
227 uint32_t m_countRxSuccess{0}; ///< count RX success
228 uint32_t m_countRxFailure{0}; ///< count RX failure
229
230 private:
231 void DoRun() override;
232
233 /**
234 * Check the number of received packets
235 * @param expectedSuccessCount the number of successfully received packets
236 * @param expectedFailureCount the number of unsuccessfully received packets
237 */
238 void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
239};
240
244 "Threshold preamble detection model test when no frame capture model is applied")
245{
246}
247
248void
250 uint32_t expectedFailureCount)
251{
253 expectedSuccessCount,
254 "Didn't receive right number of successful packets");
256 expectedFailureCount,
257 "Didn't receive right number of unsuccessful packets");
258}
259
260void
262 RxSignalInfo rxSignalInfo,
263 const WifiTxVector& txVector,
264 const std::vector<bool>& statusPerMpdu)
265{
266 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
268}
269
270void
276
277void
279{
281
282 m_phy->SetReceiveOkCallback(
284 m_phy->SetReceiveErrorCallback(
286
287 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
289 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(4));
290 preambleDetectionModel->SetAttribute("MinimumRssi", DoubleValue(-82));
291 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
292}
293
294void
296{
299 int64_t streamNumber = 0;
300 m_phy->AssignStreams(streamNumber);
301
302 // RX power > CCA-ED > CCA-PD
303 dBm_u rxPower{-50};
304
305 // CASE 1: send one packet and check PHY state:
306 // All reception stages should succeed and PHY state should be RX for the duration of the packet
307 // minus the time to detect the preamble, otherwise it should be IDLE.
308
311 this,
312 rxPower,
313 1000,
314 7);
315 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
316 // CCA_BUSY
319 this,
320 WifiPhyState::IDLE);
323 this,
324 WifiPhyState::CCA_BUSY);
325 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
326 // CCA_BUSY to RX
329 this,
330 WifiPhyState::CCA_BUSY);
333 this,
334 WifiPhyState::RX);
335 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
338 this,
339 WifiPhyState::RX);
342 this,
343 WifiPhyState::IDLE);
344 // Packet should have been successfully received
347 this,
348 1,
349 0);
350
351 // CASE 2: send two packets with same power within the 4us window and check PHY state:
352 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
353 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
354 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
355 // time to detect the preamble.
356
359 this,
360 rxPower,
361 1000,
362 7);
365 this,
366 rxPower,
367 1000,
368 7);
369 // At 4us, no preamble is successfully detected and STA PHY STATE should move from IDLE to
370 // CCA_BUSY
373 this,
374 WifiPhyState::IDLE);
377 this,
378 WifiPhyState::CCA_BUSY);
379 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
380 // = 154.8us
383 this,
384 WifiPhyState::CCA_BUSY);
387 this,
388 WifiPhyState::IDLE);
389 // No more packet should have been successfully received, and since preamble detection did not
390 // pass, the packet should not have been counted as a failure
393 this,
394 1,
395 0);
396
397 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY
398 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
399 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
400 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
401 // time to detect the preamble.
402
405 this,
406 rxPower,
407 1000,
408 7);
411 this,
412 rxPower - dB_u{3},
413 1000,
414 7);
415 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
416 // CCA_BUSY
419 this,
420 WifiPhyState::IDLE);
423 this,
424 WifiPhyState::CCA_BUSY);
425 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
426 // = 154.8us
429 this,
430 WifiPhyState::CCA_BUSY);
433 this,
434 WifiPhyState::IDLE);
435 // No more packet should have been successfully received, and since preamble detection did not
436 // pass the packet should not have been counted as a failure
439 this,
440 1,
441 0);
442
443 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY
444 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
445 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
446 // decode the modulation).
447
450 this,
451 rxPower,
452 1000,
453 7);
456 this,
457 rxPower - dB_u{6},
458 1000,
459 7);
460 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
461 // CCA_BUSY
464 this,
465 WifiPhyState::IDLE);
468 this,
469 WifiPhyState::CCA_BUSY);
470 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
471 // CCA_BUSY to RX
474 this,
475 WifiPhyState::CCA_BUSY);
478 this,
479 WifiPhyState::RX);
480 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
481 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
482 // should first be seen as CCA_BUSY for 2us.
485 this,
486 WifiPhyState::RX);
489 this,
490 WifiPhyState::CCA_BUSY);
493 this,
494 WifiPhyState::CCA_BUSY);
497 this,
498 WifiPhyState::IDLE);
499 // In this case, the first packet should be marked as a failure
502 this,
503 1,
504 1);
505
506 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY
507 // state: PHY preamble detection should fail because SNR is too low (around -3 dB, which is
508 // lower than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is
509 // above CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus
510 // the time to detect the preamble.
511
514 this,
515 rxPower,
516 1000,
517 7);
520 this,
521 rxPower + dB_u{3.0},
522 1000,
523 7);
524 // At 6us (hence 4us after the last signal is received), no preamble is successfully detected,
525 // hence STA PHY STATE should move from IDLE to CCA_BUSY
528 this,
529 WifiPhyState::IDLE);
532 this,
533 WifiPhyState::CCA_BUSY);
534 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
535 // = 154.8us
538 this,
539 WifiPhyState::CCA_BUSY);
542 this,
543 WifiPhyState::IDLE);
544 // No more packet should have been successfully received, and since preamble detection did not
545 // pass the packet should not have been counted as a failure
548 this,
549 1,
550 1);
551
552 // CCA-PD < RX power < CCA-ED
553 rxPower = dBm_u{-70};
554
555 // CASE 6: send one packet and check PHY state:
556 // All reception stages should succeed and PHY state should be RX for the duration of the packet
557 // minus the time to detect the preamble, otherwise it should be IDLE.
558
561 this,
562 rxPower,
563 1000,
564 7);
565 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
566 // CCA_BUSY
569 this,
570 WifiPhyState::IDLE);
573 this,
574 WifiPhyState::CCA_BUSY);
575 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
576 // CCA_BUSY to RX
579 this,
580 WifiPhyState::CCA_BUSY);
583 this,
584 WifiPhyState::RX);
585 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
588 this,
589 WifiPhyState::RX);
592 this,
593 WifiPhyState::IDLE);
594 // Packet should have been successfully received
597 this,
598 2,
599 1);
600
601 // CASE 7: send two packets with same power within the 4us window and check PHY state:
602 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
603 // the threshold of 4 dB), and PHY state should be CCA_BUSY since it should detect the start of
604 // a valid OFDM transmission at a receive level greater than or equal to the minimum modulation
605 // and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
606
609 this,
610 rxPower,
611 1000,
612 7);
615 this,
616 rxPower,
617 1000,
618 7);
619 // At 4us, STA PHY STATE should stay IDLE
622 this,
623 WifiPhyState::CCA_BUSY);
624 // No more packet should have been successfully received, and since preamble detection did not
625 // pass the packet should not have been counted as a failure
628 this,
629 2,
630 1);
631
632 // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY
633 // state: PHY preamble detection should fail PHY preamble detection should fail because SNR is
634 // too low (around 3 dB, which is lower than the threshold of 4 dB), and PHY state should be
635 // CCA_BUSY since it should detect the start of a valid OFDM transmission at a receive level
636 // greater than or equal to the minimum modulation and coding rate sensitivity (–82 dBm for 20
637 // MHz channel spacing).
638
641 this,
642 rxPower,
643 1000,
644 7);
647 this,
648 rxPower - dB_u{3},
649 1000,
650 7);
651 // At 4us, STA PHY STATE should stay IDLE
654 this,
655 WifiPhyState::CCA_BUSY);
656 // No more packet should have been successfully received, and since preamble detection did not
657 // pass the packet should not have been counted as a failure
660 this,
661 2,
662 1);
663
664 // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY
665 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
666 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
667 // decode the modulation).
668
671 this,
672 rxPower,
673 1000,
674 7);
677 this,
678 rxPower - dB_u{6},
679 1000,
680 7);
681 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
682 // CCA_BUSY
685 this,
686 WifiPhyState::IDLE);
689 this,
690 WifiPhyState::CCA_BUSY);
691 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
692 // CCA_BUSY to RX
695 this,
696 WifiPhyState::CCA_BUSY);
699 this,
700 WifiPhyState::RX);
701 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
702 // 152.8us.
705 this,
706 WifiPhyState::RX);
709 this,
710 WifiPhyState::CCA_BUSY);
711 // In this case, the first packet should be marked as a failure
714 this,
715 2,
716 2);
717
718 // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY
719 // state: PHY preamble detection should fail because SNR is too low (around -3 dB, which is
720 // lower than the threshold of 4 dB), and PHY state should stay IDLE since the total energy is
721 // below CCA-ED (-62 dBm).
722
725 this,
726 rxPower,
727 1000,
728 7);
731 this,
732 rxPower + dB_u{3.0},
733 1000,
734 7);
735 // At 4us, STA PHY STATE should stay IDLE
738 this,
739 WifiPhyState::IDLE);
740 // No more packet should have been successfully received, and since preamble detection did not
741 // pass the packet should not have been counted as a failure
744 this,
745 2,
746 2);
747
748 // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble
749 // detection (-82 dBm) and check PHY state: preamble detection should succeed and PHY state
750 // should move to RX.
751
752 rxPower = dBm_u{-81};
753
756 this,
757 rxPower,
758 1000,
759 7);
760 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
761 // CCA_BUSY
764 this,
765 WifiPhyState::IDLE);
768 this,
769 WifiPhyState::CCA_BUSY);
770 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
771 // CCA_BUSY to RX
774 this,
775 WifiPhyState::CCA_BUSY);
778 this,
779 WifiPhyState::RX);
780 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
783 this,
784 WifiPhyState::RX);
787 this,
788 WifiPhyState::IDLE);
789
790 // RX power < CCA-PD < CCA-ED
791 rxPower = dBm_u{-83};
792
793 // CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble
794 // detection (-82 dBm) and check PHY state: preamble detection should fail and PHY should be
795 // kept in IDLE state.
796
799 this,
800 rxPower,
801 1000,
802 7);
803 // At 4us, STA PHY state should be IDLE
806 this,
807 WifiPhyState::IDLE);
808
811}
812
813/**
814 * @ingroup wifi-test
815 * @ingroup tests
816 *
817 * @brief Preamble detection test w/o frame capture
818 */
820{
821 public:
823
824 protected:
825 void DoSetup() override;
826
827 /**
828 * Spectrum wifi receive success function
829 * @param psdu the PSDU
830 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
831 * @param txVector the transmit vector
832 * @param statusPerMpdu reception status per MPDU
833 */
835 RxSignalInfo rxSignalInfo,
836 const WifiTxVector& txVector,
837 const std::vector<bool>& statusPerMpdu);
838 /**
839 * Spectrum wifi receive failure function
840 * @param psdu the PSDU
841 */
843 uint32_t m_countRxSuccess{0}; ///< count RX success
844 uint32_t m_countRxFailure{0}; ///< count RX failure
845
846 private:
847 void DoRun() override;
848
849 /**
850 * Check the number of received packets
851 * @param expectedSuccessCount the number of successfully received packets
852 * @param expectedFailureCount the number of unsuccessfuly received packets
853 */
854 void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
855};
856
859 "Threshold preamble detection model test when simple frame capture model is applied")
860{
861}
862
863void
865 uint32_t expectedFailureCount)
866{
868 expectedSuccessCount,
869 "Didn't receive right number of successful packets");
871 expectedFailureCount,
872 "Didn't receive right number of unsuccessful packets");
873}
874
875void
877 RxSignalInfo rxSignalInfo,
878 const WifiTxVector& txVector,
879 const std::vector<bool>& statusPerMpdu)
880{
881 NS_LOG_FUNCTION(this << *psdu << txVector);
883}
884
885void
891
892void
894{
896
897 m_phy->SetReceiveOkCallback(
899 m_phy->SetReceiveErrorCallback(
901
902 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
904 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(4));
905 preambleDetectionModel->SetAttribute("MinimumRssi", DoubleValue(-82));
906 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
907
909 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
910 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
911 m_phy->SetFrameCaptureModel(frameCaptureModel);
912}
913
914void
916{
919 int64_t streamNumber = 1;
920 m_phy->AssignStreams(streamNumber);
921
922 // RX power > CCA-ED > CCA-PD
923 dBm_u rxPower{-50};
924
925 // CASE 1: send one packet and check PHY state:
926 // All reception stages should succeed and PHY state should be RX for the duration of the packet
927 // minus the time to detect the preamble, otherwise it should be IDLE.
928
931 this,
932 rxPower,
933 1000,
934 7);
935 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
936 // CCA_BUSY
939 this,
940 WifiPhyState::IDLE);
943 this,
944 WifiPhyState::CCA_BUSY);
945 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
946 // CCA_BUSY to RX
949 this,
950 WifiPhyState::CCA_BUSY);
953 this,
954 WifiPhyState::RX);
955 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
958 this,
959 WifiPhyState::RX);
962 this,
963 WifiPhyState::IDLE);
964 // Packet should have been successfully received
967 this,
968 1,
969 0);
970
971 // CASE 2: send two packets with same power within the 4us window and check PHY state:
972 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
973 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
974 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
975 // time to detect the preamble.
976
979 this,
980 rxPower,
981 1000,
982 7);
985 this,
986 rxPower,
987 1000,
988 7);
989 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
990 // CCA_BUSY
993 this,
994 WifiPhyState::IDLE);
997 this,
998 WifiPhyState::CCA_BUSY);
999 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1000 // = 154.8us
1003 this,
1004 WifiPhyState::CCA_BUSY);
1007 this,
1008 WifiPhyState::IDLE);
1009 // No more packet should have been successfully received, and since preamble detection did not
1010 // pass the packet should not have been counted as a failure
1013 this,
1014 1,
1015 0);
1016
1017 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY
1018 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
1019 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1020 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1021 // time to detect the preamble.
1022
1025 this,
1026 rxPower,
1027 1000,
1028 7);
1031 this,
1032 rxPower - dB_u{3},
1033 1000,
1034 7);
1035 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1036 // CCA_BUSY
1039 this,
1040 WifiPhyState::IDLE);
1043 this,
1044 WifiPhyState::CCA_BUSY);
1045 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1046 // = 154.8us
1049 this,
1050 WifiPhyState::CCA_BUSY);
1053 this,
1054 WifiPhyState::IDLE);
1055 // No more packet should have been successfully received, and since preamble detection did not
1056 // pass the packet should not have been counted as a failure
1059 this,
1060 1,
1061 0);
1062
1063 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY
1064 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1065 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1066 // decode the modulation).
1067
1070 this,
1071 rxPower,
1072 1000,
1073 7);
1076 this,
1077 rxPower - dB_u{6},
1078 1000,
1079 7);
1080 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1081 // CCA_BUSY
1084 this,
1085 WifiPhyState::IDLE);
1088 this,
1089 WifiPhyState::CCA_BUSY);
1090 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1091 // CCA_BUSY to RX
1094 this,
1095 WifiPhyState::CCA_BUSY);
1098 this,
1099 WifiPhyState::RX);
1100 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1101 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
1102 // should first be seen as CCA_BUSY for 2us.
1105 this,
1106 WifiPhyState::RX);
1109 this,
1110 WifiPhyState::CCA_BUSY);
1113 this,
1114 WifiPhyState::CCA_BUSY);
1117 this,
1118 WifiPhyState::IDLE);
1119 // In this case, the first packet should be marked as a failure
1122 this,
1123 1,
1124 1);
1125
1126 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY
1127 // state: PHY preamble detection should switch because a higher packet is received within the
1128 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1129 // lower than the threshold of 4 dB), PHY state should be CCA_BUSY since the total energy is
1130 // above CCA-ED (-62 dBm).
1131
1134 this,
1135 rxPower,
1136 1000,
1137 7);
1140 this,
1141 rxPower + dB_u{3.0},
1142 1000,
1143 7);
1144 // At 4us, STA PHY STATE should stay IDLE
1147 this,
1148 WifiPhyState::IDLE);
1149 // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
1152 this,
1153 WifiPhyState::IDLE);
1156 this,
1157 WifiPhyState::CCA_BUSY);
1158 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1159 // = 154.8us
1162 this,
1163 WifiPhyState::CCA_BUSY);
1166 this,
1167 WifiPhyState::IDLE);
1168 // No more packet should have been successfully received, and since preamble detection did not
1169 // pass the packet should not have been counted as a failure
1172 this,
1173 1,
1174 1);
1175
1176 // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY
1177 // state: PHY preamble detection should switch because a higher packet is received within the
1178 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1179 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1180 // decode the modulation).
1181
1184 this,
1185 rxPower,
1186 1000,
1187 7);
1190 this,
1191 rxPower + dB_u{6.0},
1192 1000,
1193 7);
1194 // At 4us, STA PHY STATE should stay IDLE
1197 this,
1198 WifiPhyState::IDLE);
1199 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1200 // CCA_BUSY
1203 this,
1204 WifiPhyState::IDLE);
1207 this,
1208 WifiPhyState::CCA_BUSY);
1209 // At 46us, PHY header should be successfully received and STA PHY STATE should move from
1210 // CCA_BUSY to RX
1213 this,
1214 WifiPhyState::CCA_BUSY);
1217 this,
1218 WifiPhyState::RX);
1219 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1220 // = 154.8us
1223 this,
1224 WifiPhyState::RX);
1227 this,
1228 WifiPhyState::IDLE);
1229 // In this case, the second packet should be marked as a failure
1232 this,
1233 1,
1234 2);
1235
1236 // CASE 7: send two packets with same power at the exact same time and check PHY state:
1237 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
1238 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1239 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1240 // time to detect the preamble.
1241
1244 this,
1245 rxPower,
1246 1000,
1247 7);
1250 this,
1251 rxPower,
1252 1000,
1253 7);
1254 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1255 // CCA_BUSY
1258 this,
1259 WifiPhyState::IDLE);
1262 this,
1263 WifiPhyState::CCA_BUSY);
1264 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1265 // = 154.8us
1268 this,
1269 WifiPhyState::CCA_BUSY);
1272 this,
1273 WifiPhyState::IDLE);
1274 // No more packet should have been successfully received, and since preamble detection did not
1275 // pass the packet should not have been counted as a failure
1278 this,
1279 1,
1280 2);
1281
1282 // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY
1283 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
1284 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1285 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1286 // time to detect the preamble.
1287
1290 this,
1291 rxPower,
1292 1000,
1293 7);
1296 this,
1297 rxPower - dB_u{3},
1298 1000,
1299 7);
1300 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1301 // CCA_BUSY
1304 this,
1305 WifiPhyState::IDLE);
1308 this,
1309 WifiPhyState::CCA_BUSY);
1310 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1313 this,
1314 WifiPhyState::CCA_BUSY);
1317 this,
1318 WifiPhyState::IDLE);
1319 // No more packet should have been successfully received, and since preamble detection did not
1320 // pass the packet should not have been counted as a failure
1323 this,
1324 1,
1325 2);
1326
1327 // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY
1328 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1329 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1330 // decode the modulation).
1331
1334 this,
1335 rxPower,
1336 1000,
1337 7);
1340 this,
1341 rxPower - dB_u{6},
1342 1000,
1343 7);
1344 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1345 // CCA_BUSY
1348 this,
1349 WifiPhyState::IDLE);
1352 this,
1353 WifiPhyState::CCA_BUSY);
1354 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1355 // CCA_BUSY to RX
1358 this,
1359 WifiPhyState::CCA_BUSY);
1362 this,
1363 WifiPhyState::RX);
1364 // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
1367 this,
1368 WifiPhyState::RX);
1371 this,
1372 WifiPhyState::IDLE);
1373 // In this case, the first packet should be marked as a failure
1376 this,
1377 1,
1378 3);
1379
1380 // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY
1381 // state: PHY preamble detection should switch because a higher packet is received within the
1382 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1383 // lower than the threshold of 4 dB), PHY state should be CCA_BUSY since the total energy is
1384 // above CCA-ED (-62 dBm).
1385
1388 this,
1389 rxPower,
1390 1000,
1391 7);
1394 this,
1395 rxPower + dB_u{3.0},
1396 1000,
1397 7);
1398 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1399 // CCA_BUSY
1402 this,
1403 WifiPhyState::IDLE);
1406 this,
1407 WifiPhyState::CCA_BUSY);
1408 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1411 this,
1412 WifiPhyState::CCA_BUSY);
1415 this,
1416 WifiPhyState::IDLE);
1417 // No more packet should have been successfully received, and since preamble detection did not
1418 // pass the packet should not have been counted as a failure
1421 this,
1422 1,
1423 3);
1424
1425 // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY
1426 // state: PHY preamble detection should switch because a higher packet is received within the
1427 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1428 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1429 // decode the modulation).
1430
1433 this,
1434 rxPower,
1435 1000,
1436 7);
1439 this,
1440 rxPower + dB_u{6.0},
1441 1000,
1442 7);
1443 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1444 // CCA_BUSY
1447 this,
1448 WifiPhyState::IDLE);
1451 this,
1452 WifiPhyState::CCA_BUSY);
1453 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1454 // CCA_BUSY to RX
1457 this,
1458 WifiPhyState::CCA_BUSY);
1461 this,
1462 WifiPhyState::RX);
1463 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1466 this,
1467 WifiPhyState::RX);
1470 this,
1471 WifiPhyState::IDLE);
1472 // In this case, the second packet should be marked as a failure
1475 this,
1476 1,
1477 4);
1478
1479 // CCA-PD < RX power < CCA-ED
1480 rxPower = dBm_u{-70};
1481
1482 // CASE 12: send one packet and check PHY state:
1483 // All reception stages should succeed and PHY state should be RX for the duration of the packet
1484 // minus the time to detect the preamble, otherwise it should be IDLE.
1485
1488 this,
1489 rxPower,
1490 1000,
1491 7);
1492 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1493 // CCA_BUSY
1496 this,
1497 WifiPhyState::IDLE);
1500 this,
1501 WifiPhyState::CCA_BUSY);
1502 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1503 // CCA_BUSY to RX
1506 this,
1507 WifiPhyState::CCA_BUSY);
1510 this,
1511 WifiPhyState::RX);
1512 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
1515 this,
1516 WifiPhyState::RX);
1519 this,
1520 WifiPhyState::IDLE);
1521 // Packet should have been successfully received
1524 this,
1525 2,
1526 4);
1527
1528 // CASE 13: send two packets with same power within the 4us window and check PHY state:
1529 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
1530 // the threshold of 4 dB), and PHY state should be CCA_BUSY since it should detect the start of
1531 // a valid OFDM transmission at a receive level greater than or equal to the minimum modulation
1532 // and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
1533
1536 this,
1537 rxPower,
1538 1000,
1539 7);
1542 this,
1543 rxPower,
1544 1000,
1545 7);
1546 // At 4us, STA PHY STATE should stay IDLE
1549 this,
1550 WifiPhyState::CCA_BUSY);
1551 // No more packet should have been successfully received, and since preamble detection did not
1552 // pass the packet should not have been counted as a failure
1555 this,
1556 2,
1557 4);
1558
1559 // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY
1560 // state: PHY preamble detection should fail PHY preamble detection should fail because SNR is
1561 // too low (around 3 dB, which is lower than the threshold of 4 dB), and PHY state should be
1562 // CCA_BUSY since it should detect the start of a valid OFDM transmission at a receive level
1563 // greater than or equal to the minimum modulation and coding rate sensitivity (–82 dBm for 20
1564 // MHz channel spacing).
1565
1568 this,
1569 rxPower,
1570 1000,
1571 7);
1574 this,
1575 rxPower - dB_u{3},
1576 1000,
1577 7);
1578 // At 4us, STA PHY STATE should stay IDLE
1581 this,
1582 WifiPhyState::CCA_BUSY);
1583 // No more packet should have been successfully received, and since preamble detection did not
1584 // pass the packet should not have been counted as a failure
1587 this,
1588 2,
1589 4);
1590
1591 // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY
1592 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1593 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1594 // decode the modulation).
1595
1598 this,
1599 rxPower,
1600 1000,
1601 7);
1604 this,
1605 rxPower - dB_u{6},
1606 1000,
1607 7);
1608 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1609 // CCA_BUSY
1612 this,
1613 WifiPhyState::IDLE);
1616 this,
1617 WifiPhyState::CCA_BUSY);
1618 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1619 // CCA_BUSY to RX
1622 this,
1623 WifiPhyState::CCA_BUSY);
1626 this,
1627 WifiPhyState::RX);
1628 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
1629 // 152.8us.
1632 this,
1633 WifiPhyState::RX);
1636 this,
1637 WifiPhyState::CCA_BUSY);
1638 // In this case, the first packet should be marked as a failure
1641 this,
1642 2,
1643 5);
1644
1645 // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY
1646 // state: PHY preamble detection should switch because a higher packet is received within the
1647 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1648 // lower than the threshold of 4 dB). and PHY state should be CCA_BUSY since it should detect
1649 // the start of a valid OFDM transmission at a receive level greater than or equal to the
1650 // minimum modulation and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
1651
1654 this,
1655 rxPower,
1656 1000,
1657 7);
1660 this,
1661 rxPower + dB_u{3.0},
1662 1000,
1663 7);
1664 // At 4us, STA PHY STATE should stay IDLE
1667 this,
1668 WifiPhyState::IDLE);
1669 // At 6us, STA PHY STATE should be CCA_BUSY
1672 this,
1673 WifiPhyState::CCA_BUSY);
1674 // No more packet should have been successfully received, and since preamble detection did not
1675 // pass the packet should not have been counted as a failure
1678 this,
1679 2,
1680 5);
1681
1682 // CASE 17: send two packets with second one 6 dB higher within the 4us window and check PHY
1683 // state: PHY preamble detection should switch because a higher packet is received within the
1684 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1685 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1686 // decode the modulation).
1687
1690 this,
1691 rxPower,
1692 1000,
1693 7);
1696 this,
1697 rxPower + dB_u{6.0},
1698 1000,
1699 7);
1700 // At 4us, STA PHY STATE should stay IDLE
1703 this,
1704 WifiPhyState::IDLE);
1705 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1706 // CCA_BUSY
1709 this,
1710 WifiPhyState::IDLE);
1713 this,
1714 WifiPhyState::CCA_BUSY);
1715 // At 46us, PHY header should be successfully received and STA PHY STATE should move from
1716 // CCA_BUSY to RX
1719 this,
1720 WifiPhyState::CCA_BUSY);
1723 this,
1724 WifiPhyState::RX);
1725 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1726 // = 154.8us
1729 this,
1730 WifiPhyState::RX);
1733 this,
1734 WifiPhyState::IDLE);
1735 // In this case, the second packet should be marked as a failure
1738 this,
1739 2,
1740 6);
1741
1742 rxPower = dBm_u{-50};
1743 // CASE 18: send two packets with second one 50 dB higher within the 4us window
1744
1747 this,
1748 rxPower,
1749 1000,
1750 7);
1753 this,
1754 rxPower + dB_u{50.0},
1755 1000,
1756 7);
1757 // The second packet should be received successfully
1760 this,
1761 3,
1762 6);
1763
1764 // CASE 19: send two packets with second one 10 dB higher within the 4us window
1765
1768 this,
1769 rxPower,
1770 1000,
1771 7);
1774 this,
1775 rxPower + dB_u{10.0},
1776 1000,
1777 7);
1778 // The second packet should be captured, but not decoded since SNR to low for used MCS
1781 this,
1782 3,
1783 7);
1784
1785 // CASE 20: send two packets with second one 50 dB higher in the same time
1786
1789 this,
1790 rxPower,
1791 1000,
1792 7);
1795 this,
1796 rxPower + dB_u{50.0},
1797 1000,
1798 7);
1799 // The second packet should be received successfully, same as in CASE 13
1802 this,
1803 4,
1804 7);
1805
1806 // CASE 21: send two packets with second one 10 dB higher in the same time
1807
1810 this,
1811 rxPower,
1812 1000,
1813 7);
1816 this,
1817 rxPower + dB_u{10.0},
1818 1000,
1819 7);
1820 // The second packet should be captured, but not decoded since SNR to low for used MCS, same as
1821 // in CASE 19
1824 this,
1825 4,
1826 8);
1827
1830}
1831
1832/**
1833 * @ingroup wifi-test
1834 * @ingroup tests
1835 *
1836 * @brief Simple frame capture model test
1837 */
1839{
1840 public:
1842
1843 private:
1844 void DoSetup() override;
1845 void DoRun() override;
1846
1847 /**
1848 * Reset function
1849 */
1850 void Reset();
1851 /**
1852 * Spectrum wifi receive success function
1853 * @param psdu the PSDU
1854 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
1855 * @param txVector the transmit vector
1856 * @param statusPerMpdu reception status per MPDU
1857 */
1859 RxSignalInfo rxSignalInfo,
1860 const WifiTxVector& txVector,
1861 const std::vector<bool>& statusPerMpdu);
1862 /**
1863 * RX dropped function
1864 * @param p the packet
1865 * @param reason the reason
1866 */
1868
1869 /**
1870 * Verify whether 1000 bytes packet has been received
1871 */
1873 /**
1874 * Verify whether 1500 bytes packet has been received
1875 */
1877 /**
1878 * Verify whether 1000 bytes packet has been dropped
1879 */
1881 /**
1882 * Verify whether 1500 bytes packet has been dropped
1883 */
1885
1886 bool m_rxSuccess1000B{false}; ///< count received packets with 1000B payload
1887 bool m_rxSuccess1500B{false}; ///< count received packets with 1500B payload
1888 bool m_rxDropped1000B{false}; ///< count dropped packets with 1000B payload
1889 bool m_rxDropped1500B{false}; ///< count dropped packets with 1500B payload
1890};
1891
1893 : WifiPhyReceptionTest("Simple frame capture model test")
1894{
1895}
1896
1897void
1899 RxSignalInfo rxSignalInfo,
1900 const WifiTxVector& txVector,
1901 const std::vector<bool>& statusPerMpdu)
1902{
1903 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
1904 NS_ASSERT(!psdu->IsAggregate() || psdu->IsSingle());
1905 if (psdu->GetSize() == 1030)
1906 {
1907 m_rxSuccess1000B = true;
1908 }
1909 else if (psdu->GetSize() == 1530)
1910 {
1911 m_rxSuccess1500B = true;
1912 }
1913}
1914
1915void
1917{
1918 NS_LOG_FUNCTION(this << p << reason);
1919 if (p->GetSize() == 1030)
1920 {
1921 m_rxDropped1000B = true;
1922 }
1923 else if (p->GetSize() == 1530)
1924 {
1925 m_rxDropped1500B = true;
1926 }
1927}
1928
1929void
1931{
1932 m_rxSuccess1000B = false;
1933 m_rxSuccess1500B = false;
1934 m_rxDropped1000B = false;
1935 m_rxDropped1500B = false;
1936}
1937
1938void
1943
1944void
1949
1950void
1955
1956void
1961
1962void
1964{
1966
1967 m_phy->SetReceiveOkCallback(MakeCallback(&TestSimpleFrameCaptureModel::RxSuccess, this));
1968 m_phy->TraceConnectWithoutContext("PhyRxDrop",
1970
1971 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
1973 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(2));
1974 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
1975
1977 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
1978 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
1979 m_phy->SetFrameCaptureModel(frameCaptureModel);
1980}
1981
1982void
1984{
1987 int64_t streamNumber = 2;
1988 dBm_u rxPower{-30};
1989 m_phy->AssignStreams(streamNumber);
1990
1991 // CASE 1: send two packets with same power within the capture window:
1992 // PHY should not switch reception because they have same power.
1993
1996 this,
1997 rxPower,
1998 1000,
1999 0);
2002 this,
2003 rxPower,
2004 1500,
2005 0);
2008
2009 // CASE 2: send two packets with second one 6 dB weaker within the capture window:
2010 // PHY should not switch reception because first one has higher power.
2011
2014 this,
2015 rxPower,
2016 1000,
2017 0);
2020 this,
2021 rxPower - dB_u{6},
2022 1500,
2023 0);
2026 this);
2029
2030 // CASE 3: send two packets with second one 6 dB higher within the capture window:
2031 // PHY should switch reception because the second one has a higher power.
2032
2035 this,
2036 rxPower,
2037 1000,
2038 0);
2041 this,
2042 rxPower + dB_u{6.0},
2043 1500,
2044 0);
2048 this);
2050
2051 // CASE 4: send two packets with second one 6 dB higher after the capture window:
2052 // PHY should not switch reception because capture window duration has elapsed when the second
2053 // packet arrives.
2054
2057 this,
2058 rxPower,
2059 1000,
2060 0);
2063 this,
2064 rxPower + dB_u{6.0},
2065 1500,
2066 0);
2069
2072}
2073
2074/**
2075 * @ingroup wifi-test
2076 * @ingroup tests
2077 *
2078 * @brief Test PHY state upon success or failure of L-SIG and SIG-A
2079 */
2081{
2082 public:
2084
2085 private:
2086 void DoRun() override;
2087};
2088
2090 : WifiPhyReceptionTest("PHY headers reception test")
2091{
2092}
2093
2094void
2096{
2099 int64_t streamNumber = 0;
2100 m_phy->AssignStreams(streamNumber);
2101
2102 // RX power > CCA-ED
2103 dBm_u rxPower{-50};
2104
2105 // CASE 1: send one packet followed by a second one with same power between the end of the 4us
2106 // preamble detection window and the start of L-SIG of the first packet: reception should be
2107 // aborted since L-SIG cannot be decoded (SNR too low).
2108
2112 this,
2113 rxPower,
2114 1000,
2115 7);
2116 // At 10 us, STA PHY STATE should be CCA_BUSY.
2119 this,
2120 WifiPhyState::CCA_BUSY);
2121 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX and be kept to
2122 // CCA_BUSY.
2125 this,
2126 WifiPhyState::CCA_BUSY);
2127 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10
2128 // = 162.8us.
2131 this,
2132 WifiPhyState::CCA_BUSY);
2135 this,
2136 WifiPhyState::IDLE);
2137
2138 // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us
2139 // preamble detection window and the start of L-SIG of the first packet: reception should not be
2140 // aborted since L-SIG can be decoded (SNR high enough).
2141
2145 this,
2146 rxPower - dB_u{3},
2147 1000,
2148 7);
2149 // At 10 us, STA PHY STATE should be CCA_BUSY.
2152 this,
2153 WifiPhyState::CCA_BUSY);
2154 // At 44us (end of PHY header), STA PHY STATE should have moved to RX since PHY header reception
2155 // should have succeeded.
2158 this,
2159 WifiPhyState::CCA_BUSY);
2162 this,
2163 WifiPhyState::RX);
2164 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
2165 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
2166 // should first be seen as CCA_BUSY for 10us.
2169 this,
2170 WifiPhyState::RX);
2173 this,
2174 WifiPhyState::CCA_BUSY);
2177 this,
2178 WifiPhyState::CCA_BUSY);
2181 this,
2182 WifiPhyState::IDLE);
2183
2184 // CASE 3: send one packet followed by a second one with same power between the end of L-SIG and
2185 // the start of HE-SIG of the first packet: PHY header reception should not succeed but PHY
2186 // should stay in RX state for the duration estimated from L-SIG.
2187
2191 this,
2192 rxPower,
2193 1000,
2194 7);
2195 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX (HE-SIG failed) and be
2196 // kept to CCA_BUSY.
2199 this,
2200 WifiPhyState::CCA_BUSY);
2201 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed,
2202 // i.e. at 152.8us. However, since there is a second packet transmitted with a power above
2203 // CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
2206 this,
2207 WifiPhyState::CCA_BUSY);
2210 this,
2211 WifiPhyState::CCA_BUSY);
2214 this,
2215 WifiPhyState::CCA_BUSY);
2218 this,
2219 WifiPhyState::IDLE);
2220
2221 // CASE 4: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the
2222 // start of HE-SIG of the first packet: PHY header reception should succeed.
2223
2227 this,
2228 rxPower - dB_u{3},
2229 1000,
2230 7);
2231 // At 10 us, STA PHY STATE should be CCA_BUSY.
2234 this,
2235 WifiPhyState::CCA_BUSY);
2236 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2237 // should have succeeded.
2240 this,
2241 WifiPhyState::CCA_BUSY);
2244 this,
2245 WifiPhyState::RX);
2246 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed,
2247 // i.e. at 152.8us. However, since there is a second packet transmitted with a power above
2248 // CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
2251 this,
2252 WifiPhyState::RX);
2255 this,
2256 WifiPhyState::CCA_BUSY);
2259 this,
2260 WifiPhyState::CCA_BUSY);
2263 this,
2264 WifiPhyState::IDLE);
2265
2266 // RX power < CCA-ED
2267 rxPower = dBm_u{-70};
2268
2269 // CASE 5: send one packet followed by a second one with same power between the end of the 4us
2270 // preamble detection window and the start of L-SIG of the first packet: reception should be
2271 // aborted since L-SIG cannot be decoded (SNR too low).
2272
2276 this,
2277 rxPower,
2278 1000,
2279 7);
2280 // At 10 us, STA PHY STATE should be CCA_BUSY.
2283 this,
2284 WifiPhyState::CCA_BUSY);
2285 // At 24us (end of L-SIG), STA PHY STATE stay CCA_BUSY because L-SIG reception failed and the
2286 // start of a valid OFDM transmission has been detected
2289 this,
2290 WifiPhyState::CCA_BUSY);
2291
2292 // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us
2293 // preamble detection window and the start of L-SIG of the first packet: reception should not be
2294 // aborted since L-SIG can be decoded (SNR high enough).
2295
2299 this,
2300 rxPower - dB_u{3},
2301 1000,
2302 7);
2303 // At 10 us, STA PHY STATE should be CCA_BUSY.
2306 this,
2307 WifiPhyState::CCA_BUSY);
2308 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2309 // succeeded.
2312 this,
2313 WifiPhyState::CCA_BUSY);
2314 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2315 // should have succeeded.
2318 this,
2319 WifiPhyState::CCA_BUSY);
2322 this,
2323 WifiPhyState::RX);
2324 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
2325 // 152.8us.
2328 this,
2329 WifiPhyState::RX);
2332 this,
2333 WifiPhyState::CCA_BUSY);
2334
2335 // CASE 7: send one packet followed by a second one with same power between the end of L-SIG and
2336 // the start of HE-SIG of the first packet: PHY header reception should not succeed but PHY
2337 // should stay in RX state for the duration estimated from L-SIG.
2338
2342 this,
2343 rxPower,
2344 1000,
2345 7);
2346 // At 10 us, STA PHY STATE should be CCA_BUSY.
2349 this,
2350 WifiPhyState::CCA_BUSY);
2351 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2352 // succeeded.
2355 this,
2356 WifiPhyState::CCA_BUSY);
2357 // At 44 us (end of HE-SIG), STA PHY STATE should be not have moved to RX since reception of
2358 // HE-SIG should have failed.
2361 this,
2362 WifiPhyState::CCA_BUSY);
2363 // STA PHY STATE should keep CCA_BUSY once the duration estimated from L-SIG has elapsed, i.e.
2364 // at 152.8us.
2367 this,
2368 WifiPhyState::CCA_BUSY);
2369
2370 // CASE 8: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the
2371 // start of HE-SIG of the first packet: PHY header reception should succeed.
2372
2376 this,
2377 rxPower - dB_u{3},
2378 1000,
2379 7);
2380 // At 10 us, STA PHY STATE should be CCA_BUSY.
2383 this,
2384 WifiPhyState::CCA_BUSY);
2385 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2386 // succeeded.
2389 this,
2390 WifiPhyState::CCA_BUSY);
2391 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2392 // should have succeeded.
2395 this,
2396 WifiPhyState::CCA_BUSY);
2399 this,
2400 WifiPhyState::RX);
2401 // STA PHY STATE should move back to CCA_BUSY once the duration estimated from L-SIG has
2402 // elapsed, i.e. at 152.8us.
2405 this,
2406 WifiPhyState::RX);
2409 this,
2410 WifiPhyState::CCA_BUSY);
2411
2414}
2415
2416/**
2417 * @ingroup wifi-test
2418 * @ingroup tests
2419 *
2420 * @brief A-MPDU reception test
2421 */
2423{
2424 public:
2426
2427 private:
2428 void DoSetup() override;
2429 void DoRun() override;
2430
2431 /**
2432 * RX success function
2433 * @param psdu the PSDU
2434 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
2435 * @param txVector the transmit vector
2436 * @param statusPerMpdu reception status per MPDU
2437 */
2439 RxSignalInfo rxSignalInfo,
2440 const WifiTxVector& txVector,
2441 const std::vector<bool>& statusPerMpdu);
2442 /**
2443 * RX failure function
2444 * @param psdu the PSDU
2445 */
2446 void RxFailure(Ptr<const WifiPsdu> psdu);
2447 /**
2448 * RX dropped function
2449 * @param p the packet
2450 * @param reason the reason
2451 */
2453 /**
2454 * Increment reception success bitmap.
2455 * @param size the size of the received packet
2456 */
2458 /**
2459 * Increment reception failure bitmap.
2460 * @param size the size of the received packet
2461 */
2463
2464 /**
2465 * Reset bitmaps function
2466 */
2467 void ResetBitmaps();
2468
2469 /**
2470 * Send A-MPDU with 3 MPDUs of different size (i-th MSDU will have 100 bytes more than
2471 * (i-1)-th).
2472 * @param rxPower the transmit power
2473 * @param referencePacketSize the reference size of the packets in bytes (i-th MSDU will have
2474 * 100 bytes more than (i-1)-th)
2475 */
2476 void SendAmpduWithThreeMpdus(dBm_u rxPower, uint32_t referencePacketSize);
2477
2478 /**
2479 * Check the RX success bitmap for A-MPDU 1
2480 * @param expected the expected bitmap
2481 */
2482 void CheckRxSuccessBitmapAmpdu1(uint8_t expected);
2483 /**
2484 * Check the RX success bitmap for A-MPDU 2
2485 * @param expected the expected bitmap
2486 */
2487 void CheckRxSuccessBitmapAmpdu2(uint8_t expected);
2488 /**
2489 * Check the RX failure bitmap for A-MPDU 1
2490 * @param expected the expected bitmap
2491 */
2492 void CheckRxFailureBitmapAmpdu1(uint8_t expected);
2493 /**
2494 * Check the RX failure bitmap for A-MPDU 2
2495 * @param expected the expected bitmap
2496 */
2497 void CheckRxFailureBitmapAmpdu2(uint8_t expected);
2498 /**
2499 * Check the RX dropped bitmap for A-MPDU 1
2500 * @param expected the expected bitmap
2501 */
2502 void CheckRxDroppedBitmapAmpdu1(uint8_t expected);
2503 /**
2504 * Check the RX dropped bitmap for A-MPDU 2
2505 * @param expected the expected bitmap
2506 */
2507 void CheckRxDroppedBitmapAmpdu2(uint8_t expected);
2508
2509 /**
2510 * Check the PHY state
2511 * @param expectedState the expected PHY state
2512 */
2513 void CheckPhyState(WifiPhyState expectedState);
2514
2515 uint8_t m_rxSuccessBitmapAmpdu1{0}; ///< bitmap of successfully received MPDUs in A-MPDU #1
2516 uint8_t m_rxSuccessBitmapAmpdu2{0}; ///< bitmap of successfully received MPDUs in A-MPDU #2
2517
2518 uint8_t m_rxFailureBitmapAmpdu1{0}; ///< bitmap of unsuccessfully received MPDUs in A-MPDU #1
2519 uint8_t m_rxFailureBitmapAmpdu2{0}; ///< bitmap of unsuccessfully received MPDUs in A-MPDU #2
2520
2521 uint8_t m_rxDroppedBitmapAmpdu1{0}; ///< bitmap of dropped MPDUs in A-MPDU #1
2522 uint8_t m_rxDroppedBitmapAmpdu2{0}; ///< bitmap of dropped MPDUs in A-MPDU #2
2523};
2524
2526 : WifiPhyReceptionTest("A-MPDU reception test")
2527{
2528}
2529
2530void
2540
2541void
2543 RxSignalInfo rxSignalInfo,
2544 const WifiTxVector& txVector,
2545 const std::vector<bool>& statusPerMpdu)
2546{
2547 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
2548 if (statusPerMpdu.empty()) // wait for the whole A-MPDU
2549 {
2550 return;
2551 }
2552 NS_ABORT_MSG_IF(psdu->GetNMpdus() != statusPerMpdu.size(),
2553 "Should have one receive status per MPDU");
2554 auto rxOkForMpdu = statusPerMpdu.begin();
2555 for (auto mpdu = psdu->begin(); mpdu != psdu->end(); ++mpdu)
2556 {
2557 if (*rxOkForMpdu)
2558 {
2559 IncrementSuccessBitmap((*mpdu)->GetSize());
2560 }
2561 else
2562 {
2563 IncrementFailureBitmap((*mpdu)->GetSize());
2564 }
2565 ++rxOkForMpdu;
2566 }
2567}
2568
2569void
2571{
2572 if (size == 1030) // A-MPDU 1 - MPDU #1
2573 {
2575 }
2576 else if (size == 1130) // A-MPDU 1 - MPDU #2
2577 {
2578 m_rxSuccessBitmapAmpdu1 |= (1 << 1);
2579 }
2580 else if (size == 1230) // A-MPDU 1 - MPDU #3
2581 {
2582 m_rxSuccessBitmapAmpdu1 |= (1 << 2);
2583 }
2584 else if (size == 1330) // A-MPDU 2 - MPDU #1
2585 {
2587 }
2588 else if (size == 1430) // A-MPDU 2 - MPDU #2
2589 {
2590 m_rxSuccessBitmapAmpdu2 |= (1 << 1);
2591 }
2592 else if (size == 1530) // A-MPDU 2 - MPDU #3
2593 {
2594 m_rxSuccessBitmapAmpdu2 |= (1 << 2);
2595 }
2596}
2597
2598void
2600{
2601 NS_LOG_FUNCTION(this << *psdu);
2602 for (auto mpdu = psdu->begin(); mpdu != psdu->end(); ++mpdu)
2603 {
2604 IncrementFailureBitmap((*mpdu)->GetSize());
2605 }
2606}
2607
2608void
2610{
2611 if (size == 1030) // A-MPDU 1 - MPDU #1
2612 {
2614 }
2615 else if (size == 1130) // A-MPDU 1 - MPDU #2
2616 {
2617 m_rxFailureBitmapAmpdu1 |= (1 << 1);
2618 }
2619 else if (size == 1230) // A-MPDU 1 - MPDU #3
2620 {
2621 m_rxFailureBitmapAmpdu1 |= (1 << 2);
2622 }
2623 else if (size == 1330) // A-MPDU 2 - MPDU #1
2624 {
2626 }
2627 else if (size == 1430) // A-MPDU 2 - MPDU #2
2628 {
2629 m_rxFailureBitmapAmpdu2 |= (1 << 1);
2630 }
2631 else if (size == 1530) // A-MPDU 2 - MPDU #3
2632 {
2633 m_rxFailureBitmapAmpdu2 |= (1 << 2);
2634 }
2635}
2636
2637void
2639{
2640 NS_LOG_FUNCTION(this << p << reason);
2641 if (p->GetSize() == 1030) // A-MPDU 1 - MPDU #1
2642 {
2644 }
2645 else if (p->GetSize() == 1130) // A-MPDU 1 - MPDU #2
2646 {
2647 m_rxDroppedBitmapAmpdu1 |= (1 << 1);
2648 }
2649 else if (p->GetSize() == 1230) // A-MPDU 1 - MPDU #3
2650 {
2651 m_rxDroppedBitmapAmpdu1 |= (1 << 2);
2652 }
2653 else if (p->GetSize() == 1330) // A-MPDU 2 - MPDU #1
2654 {
2656 }
2657 else if (p->GetSize() == 1430) // A-MPDU 2 - MPDU #2
2658 {
2659 m_rxDroppedBitmapAmpdu2 |= (1 << 1);
2660 }
2661 else if (p->GetSize() == 1530) // A-MPDU 2 - MPDU #3
2662 {
2663 m_rxDroppedBitmapAmpdu2 |= (1 << 2);
2664 }
2665}
2666
2667void
2669{
2671 expected,
2672 "RX success bitmap for A-MPDU 1 is not as expected");
2673}
2674
2675void
2677{
2679 expected,
2680 "RX success bitmap for A-MPDU 2 is not as expected");
2681}
2682
2683void
2685{
2687 expected,
2688 "RX failure bitmap for A-MPDU 1 is not as expected");
2689}
2690
2691void
2693{
2695 expected,
2696 "RX failure bitmap for A-MPDU 2 is not as expected");
2697}
2698
2699void
2701{
2703 expected,
2704 "RX dropped bitmap for A-MPDU 1 is not as expected");
2705}
2706
2707void
2709{
2711 expected,
2712 "RX dropped bitmap for A-MPDU 2 is not as expected");
2713}
2714
2715void
2717{
2718 WifiPhyState currentState;
2719 PointerValue ptr;
2720 m_phy->GetAttribute("State", ptr);
2722 currentState = state->GetState();
2723 NS_TEST_ASSERT_MSG_EQ(currentState,
2724 expectedState,
2725 "PHY State " << currentState << " does not match expected state "
2726 << expectedState << " at " << Simulator::Now());
2727}
2728
2729void
2731{
2733 0,
2735 NanoSeconds(800),
2736 1,
2737 1,
2738 0,
2739 MHz_u{20},
2740 true);
2741
2742 WifiMacHeader hdr;
2744 hdr.SetQosTid(0);
2745
2746 std::vector<Ptr<WifiMpdu>> mpduList;
2747 for (size_t i = 0; i < 3; ++i)
2748 {
2749 Ptr<Packet> p = Create<Packet>(referencePacketSize + i * 100);
2750 mpduList.push_back(Create<WifiMpdu>(p, hdr));
2751 }
2752 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(mpduList);
2753
2754 Time txDuration =
2755 SpectrumWifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
2756
2757 Ptr<WifiPpdu> ppdu =
2758 Create<HePpdu>(psdu, txVector, m_phy->GetOperatingChannel(), txDuration, m_uid++);
2759
2760 Ptr<SpectrumValue> txPowerSpectrum =
2763 DbmToW(rxPower),
2764 GUARD_WIDTH);
2765
2767 txParams->psd = txPowerSpectrum;
2768 txParams->txPhy = nullptr;
2769 txParams->duration = txDuration;
2770 txParams->ppdu = ppdu;
2771
2772 m_phy->StartRx(txParams, nullptr);
2773}
2774
2775void
2777{
2779
2780 m_phy->SetReceiveOkCallback(MakeCallback(&TestAmpduReception::RxSuccess, this));
2781 m_phy->SetReceiveErrorCallback(MakeCallback(&TestAmpduReception::RxFailure, this));
2782 m_phy->TraceConnectWithoutContext("PhyRxDrop",
2784
2785 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
2787 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(2));
2788 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
2789
2791 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
2792 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
2793 m_phy->SetFrameCaptureModel(frameCaptureModel);
2794}
2795
2796void
2798{
2801 int64_t streamNumber = 1;
2802 dBm_u rxPower{-30};
2803 m_phy->AssignStreams(streamNumber);
2804
2805 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2806 // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
2807 // power under RX sensitivity. The second A-MPDU is received 2 microseconds after the first
2808 // A-MPDU (i.e. during preamble detection).
2809 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2810
2811 // A-MPDU 1
2814 this,
2815 rxPower - dB_u{100},
2816 1000);
2817
2818 // A-MPDU 2
2821 this,
2822 rxPower,
2823 1300);
2824
2825 // All MPDUs of A-MPDU 1 should have been ignored.
2828 this,
2829 0b00000000);
2832 this,
2833 0b00000000);
2836 this,
2837 0b00000000);
2838
2839 // All MPDUs of A-MPDU 2 should have been successfully received.
2842 this,
2843 0b00000111);
2846 this,
2847 0b00000000);
2850 this,
2851 0b00000000);
2852
2854
2855 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2856 // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
2857 // with power under RX sensitivity. The second A-MPDU is received 2 microseconds after the first
2858 // A-MPDU (i.e. during preamble detection).
2859 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2860
2861 // A-MPDU 1
2864 this,
2865 rxPower,
2866 1000);
2867
2868 // A-MPDU 2
2871 this,
2872 rxPower - dB_u{100},
2873 1300);
2874
2875 // All MPDUs of A-MPDU 1 should have been received.
2878 this,
2879 0b00000111);
2882 this,
2883 0b00000000);
2886 this,
2887 0b00000000);
2888
2889 // All MPDUs of A-MPDU 2 should have been ignored.
2892 this,
2893 0b00000000);
2896 this,
2897 0b00000000);
2900 this,
2901 0b00000000);
2902
2904
2905 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2906 // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
2907 // power under RX sensitivity. The second A-MPDU is received 10 microseconds after the first
2908 // A-MPDU (i.e. during the frame capture window).
2909 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2910
2911 // A-MPDU 1
2914 this,
2915 rxPower - dB_u{100},
2916 1000);
2917
2918 // A-MPDU 2
2921 this,
2922 rxPower,
2923 1300);
2924
2925 // All MPDUs of A-MPDU 1 should have been ignored.
2928 this,
2929 0b00000000);
2932 this,
2933 0b00000000);
2936 this,
2937 0b00000000);
2938
2939 // All MPDUs of A-MPDU 2 should have been successfully received.
2942 this,
2943 0b00000111);
2946 this,
2947 0b00000000);
2950 this,
2951 0b00000000);
2952
2954
2955 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2956 // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
2957 // with power under RX sensitivity. The second A-MPDU is received 10 microseconds after the
2958 // first A-MPDU (i.e. during the frame capture window).
2959 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2960
2961 // A-MPDU 1
2964 this,
2965 rxPower,
2966 1000);
2967
2968 // A-MPDU 2
2971 this,
2972 rxPower - dB_u{100},
2973 1300);
2974
2975 // All MPDUs of A-MPDU 1 should have been received.
2978 this,
2979 0b00000111);
2982 this,
2983 0b00000000);
2986 this,
2987 0b00000000);
2988
2989 // All MPDUs of A-MPDU 2 should have been ignored.
2992 this,
2993 0b00000000);
2996 this,
2997 0b00000000);
3000 this,
3001 0b00000000);
3002
3004
3005 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3006 // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
3007 // power under RX sensitivity. The second A-MPDU is received 100 microseconds after the first
3008 // A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
3009 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3010
3011 // A-MPDU 1
3014 this,
3015 rxPower - dB_u{100},
3016 1000);
3017
3018 // A-MPDU 2
3021 this,
3022 rxPower,
3023 1300);
3024
3025 // All MPDUs of A-MPDU 1 should have been ignored.
3028 this,
3029 0b00000000);
3032 this,
3033 0b00000000);
3036 this,
3037 0b00000000);
3038
3039 // All MPDUs of A-MPDU 2 should have been successfully received.
3042 this,
3043 0b00000111);
3046 this,
3047 0b00000000);
3050 this,
3051 0b00000000);
3052
3054
3055 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3056 // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
3057 // with power under RX sensitivity. The second A-MPDU is received 100 microseconds after the
3058 // first A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
3059 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3060
3061 // A-MPDU 1
3064 this,
3065 rxPower,
3066 1000);
3067
3068 // A-MPDU 2
3071 this,
3072 rxPower - dB_u{100},
3073 1300);
3074
3075 // All MPDUs of A-MPDU 1 should have been received.
3078 this,
3079 0b00000111);
3082 this,
3083 0b00000000);
3086 this,
3087 0b00000000);
3088
3089 // All MPDUs of A-MPDU 2 should have been ignored.
3092 this,
3093 0b00000000);
3096 this,
3097 0b00000000);
3100 this,
3101 0b00000000);
3102
3104
3105 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3106 // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
3107 // power under RX sensitivity. The second A-MPDU is received during the payload of MPDU #2.
3108 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3109
3110 // A-MPDU 1
3113 this,
3114 rxPower - dB_u{100},
3115 1000);
3116
3117 // A-MPDU 2
3120 this,
3121 rxPower,
3122 1300);
3123
3124 // All MPDUs of A-MPDU 1 should have been ignored.
3127 this,
3128 0b00000000);
3131 this,
3132 0b00000000);
3135 this,
3136 0b00000000);
3137
3138 // All MPDUs of A-MPDU 2 should have been successfully received.
3141 this,
3142 0b00000111);
3145 this,
3146 0b00000000);
3149 this,
3150 0b00000000);
3151
3153
3154 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3155 // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
3156 // with power under RX sensitivity. The second A-MPDU is received during the payload of MPDU #2.
3157 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3158
3159 // A-MPDU 1
3162 this,
3163 rxPower,
3164 1000);
3165
3166 // A-MPDU 2
3169 this,
3170 rxPower - dB_u{100},
3171 1300);
3172
3173 // All MPDUs of A-MPDU 1 should have been received.
3176 this,
3177 0b00000111);
3180 this,
3181 0b00000000);
3184 this,
3185 0b00000000);
3186
3187 // All MPDUs of A-MPDU 2 should have been ignored.
3190 this,
3191 0b00000000);
3194 this,
3195 0b00000000);
3198 this,
3199 0b00000000);
3200
3202
3203 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3204 // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3
3205 // dB higher. The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during
3206 // preamble detection).
3207 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3208
3209 // A-MPDU 1
3212 this,
3213 rxPower,
3214 1000);
3215
3216 // A-MPDU 2
3219 this,
3220 rxPower + dB_u{3.0},
3221 1300);
3222
3223 // All MPDUs of A-MPDU 1 should have been dropped.
3226 this,
3227 0b00000000);
3230 this,
3231 0b00000000);
3234 this,
3235 0b00000111);
3236
3237 // All MPDUs of A-MPDU 2 should have been received with errors.
3240 this,
3241 0b00000000);
3244 this,
3245 0b00000111);
3248 this,
3249 0b00000000);
3250
3252
3253 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3254 // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3255 // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble
3256 // detection).
3257 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3258
3259 // A-MPDU 1
3262 this,
3263 rxPower,
3264 1000);
3265
3266 // A-MPDU 2
3269 this,
3270 rxPower,
3271 1300);
3272
3273 // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
3276 this,
3277 0b00000000);
3280 this,
3281 0b00000000);
3284 this,
3285 0b00000111);
3286
3287 // All MPDUs of A-MPDU 2 should have been dropped as well.
3290 this,
3291 0b00000000);
3294 this,
3295 0b00000000);
3298 this,
3299 0b00000111);
3300
3302
3303 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3304 // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3
3305 // dB higher. The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during
3306 // preamble detection).
3307 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
3308
3309 // A-MPDU 1
3312 this,
3313 rxPower + dB_u{3.0},
3314 1000);
3315
3316 // A-MPDU 2
3319 this,
3320 rxPower,
3321 1300);
3322
3323 // All MPDUs of A-MPDU 1 should have been received with errors.
3326 this,
3327 0b00000000);
3330 this,
3331 0b00000111);
3334 this,
3335 0b00000000);
3336
3337 // All MPDUs of A-MPDU 2 should have been dropped.
3340 this,
3341 0b00000000);
3344 this,
3345 0b00000000);
3348 this,
3349 0b00000111);
3350
3352
3353 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3354 // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3355 // 3 dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e.
3356 // during the frame capture window).
3357 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3358
3359 // A-MPDU 1
3362 this,
3363 rxPower,
3364 1000);
3365
3366 // A-MPDU 2
3369 this,
3370 rxPower + dB_u{3.0},
3371 1300);
3372
3373 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and
3374 // thus incorrect decoding of payload).
3377 this,
3378 0b00000000);
3381 this,
3382 0b00000000);
3385 this,
3386 0b00000111);
3387
3388 // All MPDUs of A-MPDU 2 should have been dropped (even though TX power is higher, it is not
3389 // high enough to get the PHY reception switched)
3392 this,
3393 0b00000000);
3396 this,
3397 0b00000000);
3400 this,
3401 0b00000111);
3402
3404
3405 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3406 // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3407 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame
3408 // capture window).
3409 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3410
3411 // A-MPDU 1
3414 this,
3415 rxPower,
3416 1000);
3417
3418 // A-MPDU 2
3421 this,
3422 rxPower,
3423 1300);
3424
3425 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and
3426 // thus incorrect decoding of payload).
3429 this,
3430 0b00000000);
3433 this,
3434 0b00000000);
3437 this,
3438 0b00000111);
3439
3440 // All MPDUs of A-MPDU 2 should have been dropped as well.
3443 this,
3444 0b00000000);
3447 this,
3448 0b00000000);
3451 this,
3452 0b00000111);
3453
3455
3456 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3457 // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3
3458 // dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during
3459 // the frame capture window).
3460 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3461
3462 // A-MPDU 1
3465 this,
3466 rxPower + dB_u{3.0},
3467 1000);
3468
3469 // A-MPDU 2
3472 this,
3473 rxPower,
3474 1300);
3475
3476 // All MPDUs of A-MPDU 1 should have been received with errors.
3479 this,
3480 0b00000000);
3483 this,
3484 0b00000111);
3487 this,
3488 0b00000000);
3489
3490 // All MPDUs of A-MPDU 2 should have been dropped.
3493 this,
3494 0b00000000);
3497 this,
3498 0b00000000);
3501 this,
3502 0b00000111);
3503
3505
3506 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3507 // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3508 // 6 dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e.
3509 // during the frame capture window).
3510 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3511
3512 // A-MPDU 1
3515 this,
3516 rxPower,
3517 1000);
3518
3519 // A-MPDU 2
3522 this,
3523 rxPower + dB_u{6.0},
3524 1300);
3525
3526 // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
3529 this,
3530 0b00000000);
3533 this,
3534 0b00000000);
3537 this,
3538 0b00000111);
3539
3540 // All MPDUs of A-MPDU 2 should have been successfully received
3543 this,
3544 0b00000111);
3547 this,
3548 0b00000000);
3551 this,
3552 0b00000000);
3553
3555
3556 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3557 // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3558 // dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during
3559 // the frame capture window).
3560 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
3561
3562 // A-MPDU 1
3565 this,
3566 rxPower + dB_u{6.0},
3567 1000);
3568
3569 // A-MPDU 2
3572 this,
3573 rxPower,
3574 1300);
3575
3576 // All MPDUs of A-MPDU 1 should have been successfully received.
3579 this,
3580 0b00000111);
3583 this,
3584 0b00000000);
3587 this,
3588 0b00000000);
3589
3590 // All MPDUs of A-MPDU 2 should have been dropped.
3593 this,
3594 0b00000000);
3597 this,
3598 0b00000000);
3601 this,
3602 0b00000111);
3603
3605
3606 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3607 // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3608 // 6 dB higher. The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after
3609 // the frame capture window, but still during PHY header).
3610 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3611
3612 // A-MPDU 1
3615 this,
3616 rxPower,
3617 1000);
3618
3619 // A-MPDU 2
3622 this,
3623 rxPower + dB_u{6.0},
3624 1300);
3625
3626 // All MPDUs of A-MPDU 1 should have been received with errors.
3629 this,
3630 0b00000000);
3633 this,
3634 0b00000000);
3637 this,
3638 0b00000111);
3639
3640 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because
3641 // PHY is already in RX state).
3644 this,
3645 0b00000000);
3648 this,
3649 0b00000000);
3652 this,
3653 0b00000111);
3654
3656
3657 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3658 // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3659 // dB higher. The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after
3660 // the frame capture window, but still during PHY header).
3661 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3662
3663 // A-MPDU 1
3666 this,
3667 rxPower + dB_u{6.0},
3668 1000);
3669
3670 // A-MPDU 2
3673 this,
3674 rxPower,
3675 1300);
3676
3677 // All MPDUs of A-MPDU 1 should have been successfully received.
3680 this,
3681 0b00000111);
3684 this,
3685 0b00000000);
3688 this,
3689 0b00000000);
3690
3691 // All MPDUs of A-MPDU 2 should have been dropped.
3694 this,
3695 0b00000000);
3698 this,
3699 0b00000000);
3702 this,
3703 0b00000111);
3704
3706
3707 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3708 // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3709 // The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after the frame
3710 // capture window, but still during PHY header).
3711 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3712
3713 // A-MPDU 1
3716 this,
3717 rxPower,
3718 1000);
3719
3720 // A-MPDU 2
3723 this,
3724 rxPower,
3725 1300);
3726
3727 // All MPDUs of A-MPDU 1 should have been received with errors.
3730 this,
3731 0b00000000);
3734 this,
3735 0b00000000);
3738 this,
3739 0b00000111);
3740
3741 // All MPDUs of A-MPDU 2 should have been dropped.
3744 this,
3745 0b00000000);
3748 this,
3749 0b00000000);
3752 this,
3753 0b00000111);
3754
3756
3757 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3758 // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3759 // 6 dB higher. The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e.
3760 // during the payload of MPDU #1).
3761 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3762
3763 // A-MPDU 1
3766 this,
3767 rxPower,
3768 1000);
3769
3770 // A-MPDU 2
3773 this,
3774 rxPower + dB_u{6.0},
3775 1300);
3776
3777 // All MPDUs of A-MPDU 1 should have been received with errors.
3780 this,
3781 0b00000000);
3784 this,
3785 0b00000111);
3788 this,
3789 0b00000000);
3790
3791 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because
3792 // PHY is already in RX state).
3795 this,
3796 0b00000000);
3799 this,
3800 0b00000000);
3803 this,
3804 0b00000111);
3805
3807
3808 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3809 // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3810 // dB higher. The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during
3811 // the payload of MPDU #1).
3812 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3813
3814 // A-MPDU 1
3817 this,
3818 rxPower + dB_u{6.0},
3819 1000);
3820
3821 // A-MPDU 2
3824 this,
3825 rxPower,
3826 1300);
3827
3828 // All MPDUs of A-MPDU 1 should have been successfully received.
3831 this,
3832 0b00000111);
3835 this,
3836 0b00000000);
3839 this,
3840 0b00000000);
3841
3842 // All MPDUs of A-MPDU 2 should have been dropped.
3845 this,
3846 0b00000000);
3849 this,
3850 0b00000000);
3853 this,
3854 0b00000111);
3855
3857
3858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3859 // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3860 // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the
3861 // payload of MPDU #1).
3862 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
3863
3864 // A-MPDU 1
3867 this,
3868 rxPower,
3869 1000);
3870
3871 // A-MPDU 2
3874 this,
3875 rxPower,
3876 1300);
3877
3878 // All MPDUs of A-MPDU 1 should have been received with errors.
3881 this,
3882 0b00000000);
3885 this,
3886 0b00000111);
3889 this,
3890 0b00000000);
3891
3892 // All MPDUs of A-MPDU 2 should have been dropped.
3895 this,
3896 0b00000000);
3899 this,
3900 0b00000000);
3903 this,
3904 0b00000111);
3905
3907
3908 ///////////////////////////////////////////////////////////////////////////////
3909 // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3910 // The second A-MPDU is received during the payload of MPDU #2.
3911 ///////////////////////////////////////////////////////////////////////////////
3912
3913 // A-MPDU 1
3916 this,
3917 rxPower,
3918 1000);
3919
3920 // A-MPDU 2
3923 this,
3924 rxPower,
3925 1300);
3926
3927 // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
3928 // The two other MPDUs failed due to interference and are marked as failure (and dropped).
3931 this,
3932 0b00000001);
3935 this,
3936 0b00000110);
3939 this,
3940 0b00000000);
3941
3942 // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving
3943 // A-MPDU 1). The last MPDU of A-MPDU 2 is interference free (A-MPDU 1 transmission is finished)
3944 // but is dropped because its PHY preamble and header were not received.
3947 this,
3948 0b00000000);
3951 this,
3952 0b00000000);
3955 this,
3956 0b00000111);
3957
3959
3962}
3963
3964/**
3965 * @ingroup wifi-test
3966 * @ingroup tests
3967 *
3968 * @brief Unsupported Modulation Reception Test
3969 * This test creates a mixed network, in which an HE STA and a VHT
3970 * STA are associated to an HE AP and send uplink traffic. In the
3971 * simulated deployment the VHT STA's backoff will expire while the
3972 * HE STA is sending a packet, and the VHT STA will access the
3973 * channel anyway. This happens because the HE STA is using an HeMcs
3974 * that the VHT STA is not able to demodulate: the VHT STA will
3975 * correctly stop listening to the HE packet, but it will not update
3976 * its InterferenceHelper with the HE packet. Later on, this leads to
3977 * the STA wrongly assuming the medium is available when its back-off
3978 * expires in the middle of the HE packet. We detect that this is
3979 * happening by looking at the reason why the AP is failing to decode
3980 * the preamble from the VHT STA's transmission: if the reason is
3981 * that it's in RX already, the test fails. The test is based on
3982 * wifi-txop-test.cc.
3983 */
3985{
3986 public:
3989
3990 private:
3991 void DoRun() override;
3992
3993 /**
3994 * Callback invoked when PHY drops an incoming packet
3995 * @param context the context
3996 * @param packet the packet that was dropped
3997 * @param reason the reason the packet was dropped
3998 */
3999 void Dropped(std::string context, Ptr<const Packet> packet, WifiPhyRxfailureReason reason);
4000 /**
4001 * Check correctness of transmitted frames
4002 */
4003 void CheckResults();
4004
4005 uint16_t m_dropped{0}; ///< number of packets dropped by the AP because it was already receiving
4006};
4007
4009 : TestCase("Check correct behavior when a STA is receiving a transmission using an unsupported "
4010 "modulation")
4011{
4012}
4013
4014void
4016 Ptr<const Packet> packet,
4018{
4019 // Print if the test is executed through test-runner
4020 if (reason == RXING)
4021 {
4022 std::cout << "Dropped a packet because already receiving" << std::endl;
4023 m_dropped++;
4024 }
4025}
4026
4027void
4029{
4030 uint16_t m_nStations = 2; ///< number of stations
4031 NetDeviceContainer m_staDevices; ///< container for stations' NetDevices
4032 NetDeviceContainer m_apDevices; ///< container for AP's NetDevice
4033
4034 int64_t streamNumber = 100;
4035
4036 NodeContainer wifiApNode;
4037 wifiApNode.Create(1);
4038
4039 NodeContainer wifiStaNodes;
4040 wifiStaNodes.Create(m_nStations);
4041
4044 spectrumChannel->AddPropagationLossModel(lossModel);
4047 spectrumChannel->SetPropagationDelayModel(delayModel);
4048
4050 phy.SetChannel(spectrumChannel);
4051
4052 Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue(65535));
4053
4054 WifiHelper wifi;
4055 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
4056
4057 WifiMacHelper mac;
4058 mac.SetType("ns3::StaWifiMac",
4059 "QosSupported",
4060 BooleanValue(true),
4061 "Ssid",
4062 SsidValue(Ssid("non-existent-ssid")));
4063
4064 wifi.SetStandard(WIFI_STANDARD_80211ax);
4065 m_staDevices.Add(wifi.Install(phy, mac, wifiStaNodes.Get(0)));
4066 wifi.SetStandard(WIFI_STANDARD_80211ac);
4067 m_staDevices.Add(wifi.Install(phy, mac, wifiStaNodes.Get(1)));
4068
4069 wifi.SetStandard(WIFI_STANDARD_80211ax);
4070 mac.SetType("ns3::ApWifiMac",
4071 "QosSupported",
4072 BooleanValue(true),
4073 "Ssid",
4074 SsidValue(Ssid("wifi-backoff-ssid")),
4075 "BeaconInterval",
4076 TimeValue(MicroSeconds(102400)),
4077 "EnableBeaconJitter",
4078 BooleanValue(false));
4079
4080 m_apDevices = wifi.Install(phy, mac, wifiApNode);
4081
4082 // schedule association requests at different times
4083 Time init = MilliSeconds(100);
4085
4086 for (uint16_t i = 0; i < m_nStations; i++)
4087 {
4088 dev = DynamicCast<WifiNetDevice>(m_staDevices.Get(i));
4089 Simulator::Schedule(init + i * MicroSeconds(102400),
4091 dev->GetMac(),
4092 Ssid("wifi-backoff-ssid"));
4093 }
4094
4095 // Assign fixed streams to random variables in use
4096 WifiHelper::AssignStreams(m_apDevices, streamNumber);
4097
4098 MobilityHelper mobility;
4100
4101 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
4102 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
4103 positionAlloc->Add(Vector(0.0, 1.0, 0.0));
4104 positionAlloc->Add(Vector(-1.0, 0.0, 0.0));
4105 mobility.SetPositionAllocator(positionAlloc);
4106
4107 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
4108 mobility.Install(wifiApNode);
4109 mobility.Install(wifiStaNodes);
4110
4111 // set the TXOP limit on BE AC
4112 dev = DynamicCast<WifiNetDevice>(m_apDevices.Get(0));
4113 PointerValue ptr;
4114 dev->GetMac()->GetAttribute("BE_Txop", ptr);
4115
4116 PacketSocketHelper packetSocket;
4117 packetSocket.Install(wifiApNode);
4118 packetSocket.Install(wifiStaNodes);
4119
4120 // UL Traffic
4121 for (uint16_t i = 0; i < m_nStations; i++)
4122 {
4123 PacketSocketAddress socket;
4124 socket.SetSingleDevice(m_staDevices.Get(0)->GetIfIndex());
4125 socket.SetPhysicalAddress(m_apDevices.Get(0)->GetAddress());
4126 socket.SetProtocol(1);
4128 client->SetAttribute("PacketSize", UintegerValue(1500));
4129 client->SetAttribute("MaxPackets", UintegerValue(200));
4130 client->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
4131 client->SetRemote(socket);
4132 wifiStaNodes.Get(i)->AddApplication(client);
4133 client->SetStartTime(MicroSeconds(400000));
4134 client->SetStopTime(Seconds(1));
4136 legacyStaClient->SetAttribute("PacketSize", UintegerValue(1500));
4137 legacyStaClient->SetAttribute("MaxPackets", UintegerValue(200));
4138 legacyStaClient->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
4139 legacyStaClient->SetRemote(socket);
4140 wifiStaNodes.Get(i)->AddApplication(legacyStaClient);
4141 legacyStaClient->SetStartTime(MicroSeconds(400000));
4142 legacyStaClient->SetStopTime(Seconds(1));
4144 server->SetLocal(socket);
4145 wifiApNode.Get(0)->AddApplication(server);
4146 server->SetStartTime(Seconds(0));
4147 server->SetStopTime(Seconds(1));
4148 }
4149
4150 // Trace dropped packets
4151 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
4153
4156
4157 CheckResults();
4158
4160}
4161
4162void
4164{
4165 NS_TEST_EXPECT_MSG_EQ(m_dropped, 0, "Dropped some packets unexpectedly");
4166}
4167
4168/**
4169 * @ingroup wifi-test
4170 * @ingroup tests
4171 *
4172 * @brief Unsupported Bandwidth Reception Test
4173 * This test checks whether a PHY receiving a PPDU sent over a channel width
4174 * larger than the one supported by the PHY is getting dropped at the expected
4175 * time. The expected time corresponds to the moment the PHY header indicating
4176 * the channel width used to transmit the PPDU is received. Since we are considering
4177 * 802.11ax for this test, this corresponds to the time HE-SIG-A is received.
4178 */
4180{
4181 public:
4183
4184 private:
4185 void DoSetup() override;
4186 void DoTeardown() override;
4187 void DoRun() override;
4188
4189 /**
4190 * Function to create a PPDU
4191 *
4192 * @param centerFreq the center frequency used for the transmission of the PPDU
4193 * @param bandwidth the bandwidth used for the transmission of the PPDU
4194 */
4195 void SendPpdu(MHz_u centerFreq, MHz_u bandwidth);
4196
4197 /**
4198 * Function called upon a PSDU received successfully
4199 * @param psdu the PSDU
4200 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
4201 * @param txVector the transmit vector
4202 * @param statusPerMpdu reception status per MPDU
4203 */
4205 RxSignalInfo rxSignalInfo,
4206 const WifiTxVector& txVector,
4207 const std::vector<bool>& statusPerMpdu);
4208
4209 /**
4210 * Function called upon a PSDU received unsuccessfuly
4211 * @param psdu the PSDU
4212 */
4213 void RxFailure(Ptr<const WifiPsdu> psdu);
4214
4215 /**
4216 * Function called upon a PSDU dropped by the PHY
4217 * @param packet the packet that was dropped
4218 * @param reason the reason the packet was dropped
4219 */
4221
4222 /**
4223 * Check the reception results
4224 * @param expectedCountRxSuccess the expected number of RX success
4225 * @param expectedCountRxFailure the expected number of RX failure
4226 * @param expectedCountRxDropped the expected number of RX drop
4227 * @param expectedLastRxSucceeded the expected time the last RX success occurred or std::nullopt
4228 * if the expected number of RX success is not strictly positive \param expectedLastRxFailed the
4229 * expected time the last RX failure occurred or std::nullopt if the expected number of RX
4230 * failure is not strictly positive \param expectedLastRxDropped the expected time the last RX
4231 * drop occurred or std::nullopt if the expected number of RX drop is not strictly positive
4232 */
4233 void CheckRx(uint32_t expectedCountRxSuccess,
4234 uint32_t expectedCountRxFailure,
4235 uint32_t expectedCountRxDropped,
4236 std::optional<Time> expectedLastRxSucceeded,
4237 std::optional<Time> expectedLastRxFailed,
4238 std::optional<Time> expectedLastRxDropped);
4239
4240 uint32_t m_countRxSuccess; ///< count RX success
4241 uint32_t m_countRxFailure; ///< count RX failure
4242 uint32_t m_countRxDropped; ///< count RX drop
4243
4244 std::optional<Time> m_lastRxSucceeded; ///< time of last RX success, if any
4245 std::optional<Time> m_lastRxFailed; ///< time of last RX failure, if any
4246 std::optional<Time> m_lastRxDropped; ///< time of last RX drop, if any
4247
4250};
4251
4253 : TestCase("Check correct behavior when a STA is receiving a transmission using an unsupported "
4254 "bandwidth"),
4255 m_countRxSuccess(0),
4256 m_countRxFailure(0),
4257 m_countRxDropped(0),
4258 m_lastRxSucceeded(std::nullopt),
4259 m_lastRxFailed(std::nullopt),
4260 m_lastRxDropped(std::nullopt)
4261{
4262}
4263
4264void
4266{
4267 auto txVector = WifiTxVector(HePhy::GetHeMcs0(),
4268 0,
4270 NanoSeconds(800),
4271 1,
4272 1,
4273 0,
4274 bandwidth,
4275 false);
4276
4277 auto pkt = Create<Packet>(1000);
4278 WifiMacHeader hdr;
4279
4281 hdr.SetQosTid(0);
4282
4283 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
4284 Time txDuration =
4285 SpectrumWifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, m_rxPhy->GetPhyBand());
4286
4287 auto ppdu = Create<HePpdu>(psdu, txVector, m_txPhy->GetOperatingChannel(), txDuration, 0);
4288
4289 auto txPowerSpectrum =
4291 bandwidth,
4292 DbmToW(dBm_u{-50}),
4293 bandwidth);
4294
4295 auto txParams = Create<WifiSpectrumSignalParameters>();
4296 txParams->psd = txPowerSpectrum;
4297 txParams->txPhy = nullptr;
4298 txParams->duration = txDuration;
4299 txParams->ppdu = ppdu;
4300
4301 m_rxPhy->StartRx(txParams, nullptr);
4302}
4303
4304void
4306 RxSignalInfo rxSignalInfo,
4307 const WifiTxVector& txVector,
4308 const std::vector<bool>& statusPerMpdu)
4309{
4310 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
4313}
4314
4315void
4322
4323void
4331
4332void
4334 uint32_t expectedCountRxFailure,
4335 uint32_t expectedCountRxDropped,
4336 std::optional<Time> expectedLastRxSucceeded,
4337 std::optional<Time> expectedLastRxFailed,
4338 std::optional<Time> expectedLastRxDropped)
4339{
4341 expectedCountRxSuccess,
4342 "Didn't receive right number of successful packets");
4343
4345 expectedCountRxFailure,
4346 "Didn't receive right number of unsuccessful packets");
4347
4349 expectedCountRxDropped,
4350 "Didn't receive right number of dropped packets");
4351
4352 if (expectedCountRxSuccess > 0)
4353 {
4354 NS_ASSERT(m_lastRxSucceeded.has_value());
4355 NS_ASSERT(expectedLastRxSucceeded.has_value());
4357 expectedLastRxSucceeded.value(),
4358 "Didn't receive the last successful packet at the expected time");
4359 }
4360
4361 if (expectedCountRxFailure > 0)
4362 {
4363 NS_ASSERT(m_lastRxFailed.has_value());
4364 NS_ASSERT(expectedLastRxFailed.has_value());
4366 expectedLastRxFailed.value(),
4367 "Didn't receive the last unsuccessful packet at the expected time");
4368 }
4369
4370 if (expectedCountRxDropped > 0)
4371 {
4372 NS_ASSERT(m_lastRxDropped.has_value());
4373 NS_ASSERT(expectedLastRxDropped.has_value());
4375 expectedLastRxDropped.value(),
4376 "Didn't drop the last filtered packet at the expected time");
4377 }
4378}
4379
4380void
4382{
4387 auto rxInterferenceHelper = CreateObject<InterferenceHelper>();
4388 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
4389 auto rxErrorRateModel = CreateObject<NistErrorRateModel>();
4390 m_rxPhy->SetErrorRateModel(rxErrorRateModel);
4391 m_rxPhy->SetDevice(dev);
4392 m_rxPhy->AddChannel(spectrumChannel);
4393 m_rxPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4394 dev->SetPhy(m_rxPhy);
4395 node->AddDevice(dev);
4396
4397 m_rxPhy->SetReceiveOkCallback(
4399 m_rxPhy->SetReceiveErrorCallback(
4401 m_rxPhy->TraceConnectWithoutContext(
4402 "PhyRxDrop",
4404
4406 auto txInterferenceHelper = CreateObject<InterferenceHelper>();
4407 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
4408 auto txErrorRateModel = CreateObject<NistErrorRateModel>();
4409 m_txPhy->SetErrorRateModel(txErrorRateModel);
4410 m_txPhy->AddChannel(spectrumChannel);
4411 m_txPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4412}
4413
4414void
4416{
4417 m_rxPhy->Dispose();
4418 m_rxPhy = nullptr;
4419
4420 m_txPhy->Dispose();
4421 m_txPhy = nullptr;
4422}
4423
4424void
4426{
4429
4430 int64_t streamNumber = 0;
4431 m_rxPhy->AssignStreams(streamNumber);
4432
4433 // Case 1: the PHY is operating on channel 36 (20 MHz) and receives a 40 MHz PPDU (channel 38).
4434 // The PPDU should be dropped once HE-SIG-A is successfully received, since it contains
4435 // indication about the BW used for the transmission and the PHY shall detect it is larger than
4436 // its operating BW.
4437 m_txPhy->SetOperatingChannel(WifiPhy::ChannelTuple{38, 40, WIFI_PHY_BAND_5GHZ, 0});
4438 m_rxPhy->SetOperatingChannel(WifiPhy::ChannelTuple{36, 20, WIFI_PHY_BAND_5GHZ, 0});
4439
4442 this,
4443 MHz_u{5190},
4444 MHz_u{40});
4445
4446 auto heSigAExpectedRxTime = Seconds(1) + MicroSeconds(32);
4449 this,
4450 0,
4451 0,
4452 1,
4453 std::nullopt,
4454 std::nullopt,
4455 heSigAExpectedRxTime);
4456
4457 // TODO: this test can be extended with other scenarios
4458
4461}
4462
4463/**
4464 * @ingroup wifi-test
4465 * @ingroup tests
4466 *
4467 * @brief Primary 20 MHz Covered By Ppdu Test
4468 * This test checks whether the functions WifiPpdu::DoesOverlapChannel and
4469 * WifiPpdu::DoesCoverChannel are returning the expected results.
4470 */
4472{
4473 public:
4475
4476 private:
4477 void DoSetup() override;
4478 void DoRun() override;
4479 void DoTeardown() override;
4480
4481 /**
4482 * Function to create a PPDU
4483 *
4484 * @param ppduCenterFreq the center frequency used for the transmission of the PPDU
4485 * @return the created PPDU
4486 */
4487 Ptr<HePpdu> CreatePpdu(MHz_u ppduCenterFreq);
4488
4489 /**
4490 * Run one function
4491 *
4492 * @param band the PHY band to use
4493 * @param phyCenterFreq the operating center frequency of the PHY
4494 * @param p20Index the primary20 index
4495 * @param ppduCenterFreq the center frequency used for the transmission of the PPDU
4496 * @param expectedP20Overlap flag whether the primary 20 MHz channel is expected to be fully
4497 * covered by the bandwidth of the incoming PPDU
4498 * @param expectedP20Covered flag whether the
4499 * primary 20 MHz channel is expected to overlap with the bandwidth of the incoming PPDU
4500 */
4501 void RunOne(WifiPhyBand band,
4502 MHz_u phyCenterFreq,
4503 uint8_t p20Index,
4504 MHz_u ppduCenterFreq,
4505 bool expectedP20Overlap,
4506 bool expectedP20Covered);
4507
4510};
4511
4513 : TestCase("Check correct detection of whether P20 is fully covered (hence it can be received) "
4514 "or overlaps with the bandwidth of an incoming PPDU")
4515{
4516}
4517
4520{
4521 const auto& channelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
4522 ppduCenterFreq,
4523 MHz_u{0},
4525 m_rxPhy->GetPhyBand()));
4526 m_txPhy->SetOperatingChannel(
4527 WifiPhy::ChannelTuple{channelInfo.number, channelInfo.width, channelInfo.band, 0});
4528 auto txVector = WifiTxVector(HePhy::GetHeMcs7(),
4529 0,
4531 NanoSeconds(800),
4532 1,
4533 1,
4534 0,
4535 channelInfo.width,
4536 false);
4537
4538 auto pkt = Create<Packet>(1000);
4540
4541 auto psdu = Create<WifiPsdu>(pkt, hdr);
4542 auto txDuration =
4543 SpectrumWifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, channelInfo.band);
4544
4545 return Create<HePpdu>(psdu, txVector, m_txPhy->GetOperatingChannel(), txDuration, 0);
4546}
4547
4548void
4550{
4552 auto rxInterferenceHelper = CreateObject<InterferenceHelper>();
4553 m_rxPhy->SetInterferenceHelper(rxInterferenceHelper);
4554 auto rxErrorRateModel = CreateObject<NistErrorRateModel>();
4555 m_rxPhy->SetErrorRateModel(rxErrorRateModel);
4557 m_rxPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4558
4560 auto txInterferenceHelper = CreateObject<InterferenceHelper>();
4561 m_txPhy->SetInterferenceHelper(txInterferenceHelper);
4562 auto txErrorRateModel = CreateObject<NistErrorRateModel>();
4563 m_txPhy->SetErrorRateModel(txErrorRateModel);
4565 m_txPhy->ConfigureStandard(WIFI_STANDARD_80211ax);
4566}
4567
4568void
4570{
4571 m_rxPhy->Dispose();
4572 m_rxPhy = nullptr;
4573 m_txPhy->Dispose();
4574 m_txPhy = nullptr;
4575}
4576
4577void
4579 MHz_u phyCenterFreq,
4580 uint8_t p20Index,
4581 MHz_u ppduCenterFreq,
4582 bool expectedP20Overlap,
4583 bool expectedP20Covered)
4584{
4585 const auto& channelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
4586 phyCenterFreq,
4587 MHz_u{0},
4589 band));
4590
4591 m_rxPhy->SetOperatingChannel(
4592 WifiPhy::ChannelTuple{channelInfo.number, channelInfo.width, channelInfo.band, p20Index});
4593 auto p20CenterFreq = m_rxPhy->GetOperatingChannel().GetPrimaryChannelCenterFrequency(MHz_u{20});
4594 auto p20MinFreq = p20CenterFreq - MHz_u{10};
4595 auto p20MaxFreq = p20CenterFreq + MHz_u{10};
4596
4597 auto ppdu = CreatePpdu(ppduCenterFreq);
4598
4599 auto p20Overlap = ppdu->DoesOverlapChannel(p20MinFreq, p20MaxFreq);
4600 NS_TEST_ASSERT_MSG_EQ(p20Overlap,
4601 expectedP20Overlap,
4602 "PPDU is " << (expectedP20Overlap ? "expected" : "not expected")
4603 << " to overlap with the P20");
4604
4605 auto p20Covered = m_rxPhy->GetPhyEntity(WIFI_STANDARD_80211ax)
4606 ->CanStartRx(ppdu); // CanStartRx returns true is the P20 is fully covered
4607 NS_TEST_ASSERT_MSG_EQ(p20Covered,
4608 expectedP20Covered,
4609 "PPDU is " << (expectedP20Covered ? "expected" : "not expected")
4610 << " to cover the whole P20");
4611}
4612
4613void
4615{
4616 /*
4617 * Receiver PHY Operating Channel: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4618 * Transmitted 20 MHz PPDU: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4619 * Overlap with primary 20 MHz: yes
4620 * Primary 20 MHz fully covered: yes
4621 */
4622 RunOne(WIFI_PHY_BAND_2_4GHZ, MHz_u{2427}, 0, MHz_u{2427}, true, true);
4623
4624 /*
4625 * Receiver PHY Operating Channel: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4626 * Transmitted 20 MHz PPDU: 2.4 GHz Channel 6 (2427 MHz – 2447 MHz)
4627 * Overlap with primary 20 MHz: yes
4628 * Primary 20 MHz fully covered: no
4629 */
4630 RunOne(WIFI_PHY_BAND_2_4GHZ, MHz_u{2427}, 0, MHz_u{2437}, true, false);
4631
4632 /*
4633 * Receiver PHY Operating Channel: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4634 * Transmitted 40 MHz PPDU: 5 GHz Channel 38 (5170 MHz – 5210 MHz)
4635 * Overlap with primary 20 MHz: yes
4636 * Primary 20 MHz fully covered: yes
4637 */
4638 RunOne(WIFI_PHY_BAND_5GHZ, MHz_u{5180}, 0, MHz_u{5190}, true, true);
4639
4640 /*
4641 * Receiver PHY Operating Channel: 5 GHz Channel 36 (5170 MHz–5190 MHz)
4642 * Transmitted 20 MHz PPDU: 5 GHz Channel 40 (5190 MHz – 5210 MHz)
4643 * Overlap with primary 20 MHz: no
4644 * Primary 20 MHz fully covered: no
4645 */
4646 RunOne(WIFI_PHY_BAND_5GHZ, MHz_u{5180}, 0, MHz_u{5200}, false, false);
4647
4648 /*
4649 * Receiver PHY Operating Channel: 5 GHz Channel 38 (5170 MHz – 5210 MHz) with P20 index 0
4650 * Transmitted 20 MHz PPDU: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4651 * Overlap with primary 20 MHz: yes
4652 * Primary 20 MHz fully covered: yes
4653 */
4654 RunOne(WIFI_PHY_BAND_5GHZ, MHz_u{5190}, 0, MHz_u{5180}, true, true);
4655
4656 /*
4657 * Receiver PHY Operating Channel: 5 GHz Channel 38 (5170 MHz – 5210 MHz) with P20 index 1
4658 * Transmitted 20 MHz PPDU: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4659 * Overlap with primary 20 MHz: no
4660 * Primary 20 MHz fully covered: no
4661 */
4662 RunOne(WIFI_PHY_BAND_5GHZ, MHz_u{5190}, 1, MHz_u{5180}, false, false);
4663
4665}
4666
4667/**
4668 * @ingroup wifi-test
4669 * @ingroup tests
4670 *
4671 * @brief This test verifies the correct function of the WifiBandwidthFilter. 2 SpectrumWifiPhy are
4672 * setup and connected on the same spectrum channel. The test will
4673 * send a packet over the channel and if the signal plus guardband overlaps the channel the
4674 * filter will not discard the signal but if there is no overlap the filter will filter it out.
4675 */
4677{
4678 public:
4679 /**
4680 * Constructor
4681 *
4682 * @param channel channel to be used by transmitter
4683 * @param expectedValue expected number of received packets
4684 */
4685 TestSpectrumChannelWithBandwidthFilter(uint8_t channel, uint16_t expectedValue);
4686
4687 protected:
4688 void DoSetup() override;
4689 void DoTeardown() override;
4690
4691 private:
4692 /**
4693 * Callback invoked when the PHY model starts to process a signal
4694 *
4695 * @param signal the arriving signal
4696 * @param senderNodeId node Id of the sender of the signal
4697 * @param rxPower received signal power
4698 * @param duration signal duration
4699 */
4701 uint32_t senderNodeId,
4702 double rxPower,
4703 Time duration);
4704
4705 /**
4706 * Send function (sends a single packet)
4707 */
4708 void Send() const;
4709
4710 /**
4711 * Event scheduled at end of simulation for validation
4712 *
4713 * @param expectedValue expected number of receive events
4714 */
4715 void CheckRxPacketCount(uint16_t expectedValue);
4716
4717 void DoRun() override;
4718
4719 Ptr<SpectrumWifiPhy> m_tx{nullptr}; ///< transmit function
4720 Ptr<SpectrumWifiPhy> m_rx{nullptr}; ///< receive function
4721 uint32_t m_countRxBegin{0}; ///< count of receive events
4722 uint8_t m_channel{36}; ///< channel for packet transmission
4723 uint16_t m_expectedValue{0}; ///< expected count of receive events
4724};
4725
4727 uint8_t channel,
4728 uint16_t expectedValue)
4729 : TestCase("Test for early discard of signal in single-model-spectrum-channel::StartTx()"),
4730 m_channel(channel),
4731 m_expectedValue(expectedValue)
4732{
4733}
4734
4735void
4737{
4739 0,
4741 NanoSeconds(800),
4742 1,
4743 1,
4744 0,
4745 MHz_u{20},
4746 false);
4747
4748 Ptr<Packet> pkt = Create<Packet>(1000);
4749 WifiMacHeader hdr;
4750
4752 hdr.SetQosTid(0);
4753
4754 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
4755 m_tx->Send(psdu, txVector);
4756}
4757
4758void
4760{
4762 expectedValue,
4763 "Received a different amount of packets than expected.");
4764}
4765
4766void
4768 [[maybe_unused]],
4769 uint32_t senderNodeId [[maybe_unused]],
4770 double rxPower [[maybe_unused]],
4771 Time duration [[maybe_unused]])
4772{
4773 NS_LOG_FUNCTION(this << signal << senderNodeId << rxPower << duration);
4775}
4776
4777void
4779{
4780 NS_LOG_FUNCTION(this);
4782
4784 channel->AddSpectrumTransmitFilter(wifiFilter);
4785
4789 m_tx->SetDevice(dev);
4790 m_tx->SetTxPowerStart(dBm_u{20});
4791 m_tx->SetTxPowerEnd(dBm_u{20});
4792
4793 Ptr<Node> nodeRx = CreateObject<Node>();
4796 m_rx->SetDevice(devRx);
4797
4799 m_tx->SetInterferenceHelper(interferenceTx);
4801 m_tx->SetErrorRateModel(errorTx);
4802
4804 m_rx->SetInterferenceHelper(interferenceRx);
4806 m_rx->SetErrorRateModel(errorRx);
4807
4808 m_tx->AddChannel(channel);
4809 m_rx->AddChannel(channel);
4810
4811 m_tx->ConfigureStandard(WIFI_STANDARD_80211ax);
4812 m_rx->ConfigureStandard(WIFI_STANDARD_80211ax);
4813
4814 dev->SetPhy(m_tx);
4815 node->AddDevice(dev);
4816 devRx->SetPhy(m_rx);
4817 nodeRx->AddDevice(devRx);
4818
4819 m_rx->TraceConnectWithoutContext(
4820 "SignalArrival",
4822}
4823
4824void
4826{
4827 m_tx->Dispose();
4828 m_rx->Dispose();
4829}
4830
4831void
4847
4848/**
4849 * @ingroup wifi-test
4850 * @ingroup tests
4851 *
4852 * @brief This test verifies that the WifiPhyRxfailureReason distinguishes between two cases: 1) a
4853 * drop due to transmitting during the signal detection interval, and 2) a drop due to transmitting
4854 * after the receiver has detected a preamble but is waiting for the end of the preamble. 2
4855 * SpectrumWifiPhy are setup and connected on the same spectrum channel. The test will send a packet
4856 * over the channel and after a controlled amount of transmit delay (to check both cases) the
4857 * receiver of the packet will send its own packet. If delay is less than preamble detection period,
4858 * the signal detection should be aborted by transmission. If delay is greater than preamble
4859 * detection period, the signal reception should be aborted by transmission.
4860 */
4862{
4863 public:
4864 /**
4865 * Constructor
4866 *
4867 * @param delay delay in microseconds to send second packet
4868 * @param expectedReason expected failure reason
4869 */
4870 TestPhyDropDueToTx(Time delay, WifiPhyRxfailureReason expectedReason);
4871
4872 protected:
4873 void DoSetup() override;
4874 void DoTeardown() override;
4875
4876 private:
4877 /**
4878 * RX dropped function
4879 * @param p the packet
4880 * @param reason the reason
4881 */
4883
4884 /**
4885 * Send function (sends a single packet)
4886 * @param phy the WifiPhy object to send the packet
4887 */
4888 void Send(Ptr<WifiPhy> phy) const;
4889
4890 /**
4891 * Event scheduled at end of simulation for validation
4892 */
4893 void CheckDropReason();
4894
4895 void DoRun() override;
4896
4897 Ptr<SpectrumWifiPhy> m_phyA{nullptr}; ///< transmit function
4898 Ptr<SpectrumWifiPhy> m_phyB{nullptr}; ///< transmit/receive function
4899
4900 Time m_delay; ///< delay between transmissions in MicroSeconds
4901
4902 WifiPhyRxfailureReason m_expectedReason; ///< expected WifiPhyRxfailureReason
4903 WifiPhyRxfailureReason m_observedReason; ///< observed WifiPhyRxfailureReason
4904};
4905
4907 : TestCase("Test for correct WifiPhyRxfailureReason from PhyRxDrop trace"),
4908 m_delay(delay),
4909 m_expectedReason(expectedReason)
4910{
4911}
4912
4913void
4915{
4916 const auto txVector = WifiTxVector(HePhy::GetHeMcs0(),
4917 0,
4919 NanoSeconds(800),
4920 1,
4921 1,
4922 0,
4923 MHz_u{20},
4924 false);
4925
4926 auto pkt = Create<Packet>(1000);
4927 WifiMacHeader hdr;
4928
4930 hdr.SetQosTid(0);
4931
4932 auto psdu = Create<WifiPsdu>(pkt, hdr);
4933 phy->Send(psdu, txVector);
4934}
4935
4936void
4938{
4941 "Packet was dropped due to the wrong drop reason reported ");
4942}
4943
4944void
4950
4951void
4953{
4954 NS_LOG_FUNCTION(this);
4956
4957 auto node = CreateObject<Node>();
4958 auto devA = CreateObject<WifiNetDevice>();
4960 m_phyA->SetDevice(devA);
4961 m_phyA->SetTxPowerStart(dBm_u{20});
4962 m_phyA->SetTxPowerEnd(dBm_u{20});
4963
4964 auto nodeRx = CreateObject<Node>();
4965 auto devB = CreateObject<WifiNetDevice>();
4967 m_phyB->SetDevice(devB);
4968 m_phyB->SetTxPowerStart(dBm_u{20});
4969 m_phyB->SetTxPowerEnd(dBm_u{20});
4970
4971 auto interferenceTx = CreateObject<InterferenceHelper>();
4972 m_phyA->SetInterferenceHelper(interferenceTx);
4973 auto errorTx = CreateObject<NistErrorRateModel>();
4974 m_phyA->SetErrorRateModel(errorTx);
4975
4976 auto interferenceRx = CreateObject<InterferenceHelper>();
4977 m_phyB->SetInterferenceHelper(interferenceRx);
4978 auto errorRx = CreateObject<NistErrorRateModel>();
4979 m_phyB->SetErrorRateModel(errorRx);
4980
4981 m_phyA->AddChannel(channel);
4982 m_phyB->AddChannel(channel);
4983
4984 m_phyA->ConfigureStandard(WIFI_STANDARD_80211ax);
4985 m_phyA->SetOperatingChannel(WifiPhy::ChannelTuple{36, 0, WIFI_PHY_BAND_5GHZ, 0});
4986
4987 m_phyB->ConfigureStandard(WIFI_STANDARD_80211ax);
4988 m_phyB->SetOperatingChannel(WifiPhy::ChannelTuple{36, 0, WIFI_PHY_BAND_5GHZ, 0});
4989
4990 devA->SetPhy(m_phyA);
4991 node->AddDevice(devA);
4992 devB->SetPhy(m_phyB);
4993 nodeRx->AddDevice(devB);
4994
4995 m_phyB->TraceConnectWithoutContext("PhyRxDrop",
4997}
4998
4999void
5001{
5002 m_phyA->Dispose();
5003 m_phyB->Dispose();
5004}
5005
5006void
5008{
5009 NS_LOG_FUNCTION(this);
5010
5013
5014 // Upon transmitting the second packet from m_phyB, the reception from
5015 // m_phyA will be immediately dropped. Check the drop reason a short
5016 // while later (1 ns is sufficient)
5018
5021}
5022
5023/**
5024 * @ingroup wifi-test
5025 * @ingroup tests
5026 *
5027 * @brief wifi PHY reception Test Suite
5028 */
5030{
5031 public:
5033};
5034
5036 : TestSuite("wifi-phy-reception", Type::UNIT)
5037{
5038 AddTestCase(new TestThresholdPreambleDetectionWithoutFrameCapture, TestCase::Duration::QUICK);
5039 AddTestCase(new TestThresholdPreambleDetectionWithFrameCapture, TestCase::Duration::QUICK);
5040 AddTestCase(new TestSimpleFrameCaptureModel, TestCase::Duration::QUICK);
5041 AddTestCase(new TestPhyHeadersReception, TestCase::Duration::QUICK);
5042 AddTestCase(new TestAmpduReception, TestCase::Duration::QUICK);
5043 AddTestCase(new TestUnsupportedModulationReception(), TestCase::Duration::QUICK);
5044 AddTestCase(new TestUnsupportedBandwidthReception(), TestCase::Duration::QUICK);
5045 AddTestCase(new TestPrimary20CoveredByPpdu(), TestCase::Duration::QUICK);
5046 // The below three test cases are related. The test involves a receiver tuned to
5047 // channel 36 and a transmitter sending on channels 36, 40, and 44, respectively.
5048 // The second argument corresponds to the number of signals expected to be received.
5049 // Signals on channel 36 and 40 will fall within the receiver bandwidth, while
5050 // a signal on channel 44 will fall completely outside and will be filtered.
5051 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(36, 1), TestCase::Duration::QUICK);
5052 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(40, 1), TestCase::Duration::QUICK);
5053 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(44, 0), TestCase::Duration::QUICK);
5054 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(36, 1), TestCase::Duration::QUICK);
5055 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(40, 1), TestCase::Duration::QUICK);
5056 AddTestCase(new TestSpectrumChannelWithBandwidthFilter(44, 0), TestCase::Duration::QUICK);
5057 // 4 Microseconds is just less than the preamble detection period since there is no
5058 // propagation delay model
5060 TestCase::Duration::QUICK);
5062 TestCase::Duration::QUICK);
5063}
5064
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 unsuccessfuly.
void DoRun() override
Implementation to actually run this TestCase.
std::optional< Time > m_lastRxFailed
time of last RX failure, if any
void SendPpdu(MHz_u centerFreq, MHz_u bandwidth)
Function to create a PPDU.
void RxDropped(Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Function called upon a PSDU dropped by the PHY.
Unsupported Modulation Reception Test This test creates a mixed network, in which an HE STA and a VHT...
void DoRun() override
Implementation to actually run this TestCase.
void CheckResults()
Check correctness of transmitted frames.
void Dropped(std::string context, Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Callback invoked when PHY drops an incoming packet.
~TestUnsupportedModulationReception() override=default
uint16_t m_dropped
number of packets dropped by the AP because it was already receiving
Wifi Phy Reception Test base class.
WifiPhyReceptionTest(std::string test_name)
Constructor.
void SendPacket(dBm_u rxPower, uint32_t packetSize, uint8_t mcs)
Send packet function.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
~WifiPhyReceptionTest() override=default
Destructor.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
uint64_t m_uid
the UID to use for the PPDU
Ptr< SpectrumWifiPhy > m_phy
the PHY
void DoSetup() override
Implementation to do any local setup required for this TestCase.
wifi PHY reception Test Suite
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:1544
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
static WifiMode GetHeMcs7()
Return MCS 7 from HE MCS values.
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
AttributeValue implementation for Pointer.
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:595
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
AttributeValue implementation for Ssid.
Definition ssid.h:85
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
AttributeValue implementation for Time.
Definition nstime.h:1432
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
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:940
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first frequency segment matching the specified parameters.
This objects implements the PHY state machine of the Wifi device.
static Ptr< SpectrumValue > CreateHeOfdmTxPowerSpectralDensity(MHz_u centerFrequency, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=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) (802....
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc: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:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:241
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1357
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPhyBand
Identifies the PHY band.
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ UNSUPPORTED_SETTINGS
@ SIGNAL_DETECTION_ABORTED_BY_TX
@ RECEPTION_ABORTED_BY_TX
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyState
The state of the PHY layer.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
@ WIFI_MAC_QOSDATA
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:33
STL namespace.
RxSignalInfo structure containing info on the received signal.
Definition wifi-types.h:72
static const uint8_t CHANNEL_NUMBER
static const MHz_u FREQUENCY
static WifiPhyReceptionTestSuite wifiPhyReceptionTestSuite
the test suite
static const MHz_u GUARD_WIDTH
static const MHz_u CHANNEL_WIDTH
static const uint32_t packetSize
Packet size generated at the AP.