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