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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
18 */
19
20#include "ns3/ampdu-tag.h"
21#include "ns3/ap-wifi-mac.h"
22#include "ns3/boolean.h"
23#include "ns3/config.h"
24#include "ns3/double.h"
25#include "ns3/he-phy.h"
26#include "ns3/he-ppdu.h"
27#include "ns3/interference-helper.h"
28#include "ns3/log.h"
29#include "ns3/mobility-helper.h"
30#include "ns3/mpdu-aggregator.h"
31#include "ns3/multi-model-spectrum-channel.h"
32#include "ns3/nist-error-rate-model.h"
33#include "ns3/packet-socket-address.h"
34#include "ns3/packet-socket-client.h"
35#include "ns3/packet-socket-helper.h"
36#include "ns3/packet-socket-server.h"
37#include "ns3/pointer.h"
38#include "ns3/rng-seed-manager.h"
39#include "ns3/simple-frame-capture-model.h"
40#include "ns3/spectrum-wifi-helper.h"
41#include "ns3/spectrum-wifi-phy.h"
42#include "ns3/test.h"
43#include "ns3/threshold-preamble-detection-model.h"
44#include "ns3/wifi-mac-header.h"
45#include "ns3/wifi-mpdu.h"
46#include "ns3/wifi-net-device.h"
47#include "ns3/wifi-psdu.h"
48#include "ns3/wifi-spectrum-signal-parameters.h"
49#include "ns3/wifi-spectrum-value-helper.h"
50#include "ns3/wifi-utils.h"
51
52#include <optional>
53
54using namespace ns3;
55
56NS_LOG_COMPONENT_DEFINE("WifiPhyReceptionTest");
57
58static const uint8_t CHANNEL_NUMBER = 36;
59static const uint32_t FREQUENCY = 5180; // MHz
60static const uint16_t CHANNEL_WIDTH = 20; // MHz
61static const uint16_t GUARD_WIDTH =
62 CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
63
71{
72 public:
75
76 protected:
77 void DoSetup() override;
78 void DoTeardown() override;
84 void SendPacket(double rxPowerDbm);
93 RxSignalInfo rxSignalInfo,
94 WifiTxVector txVector,
95 std::vector<bool> statusPerMpdu);
103
104 private:
105 void DoRun() override;
106
111 void CheckPhyState(WifiPhyState expectedState);
116 void DoCheckPhyState(WifiPhyState expectedState);
122 void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
123
124 uint64_t m_uid;
125};
126
129 : TestCase("Threshold preamble detection model test when no frame capture model is applied"),
130 m_countRxSuccess(0),
131 m_countRxFailure(0),
132 m_uid(0)
133{
134}
135
136void
138{
139 WifiTxVector txVector =
140 WifiTxVector(HePhy::GetHeMcs7(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
141
142 Ptr<Packet> pkt = Create<Packet>(1000);
143 WifiMacHeader hdr;
144
146 hdr.SetQosTid(0);
147
148 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
149 Time txDuration = m_phy->CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
150
151 Ptr<WifiPpdu> ppdu =
152 Create<HePpdu>(psdu, txVector, FREQUENCY, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
153
154 Ptr<SpectrumValue> txPowerSpectrum =
157 DbmToW(rxPowerDbm),
159
160 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters>();
161 txParams->psd = txPowerSpectrum;
162 txParams->txPhy = nullptr;
163 txParams->duration = txDuration;
164 txParams->ppdu = ppdu;
165 txParams->txWidth = CHANNEL_WIDTH;
166
167 m_phy->StartRx(txParams);
168}
169
170void
172{
173 // This is needed to make sure PHY state will be checked as the last event if a state change
174 // occurred at the exact same time as the check
176 this,
177 expectedState);
178}
179
180void
182{
183 WifiPhyState currentState;
184 PointerValue ptr;
185 m_phy->GetAttribute("State", ptr);
186 Ptr<WifiPhyStateHelper> state = DynamicCast<WifiPhyStateHelper>(ptr.Get<WifiPhyStateHelper>());
187 currentState = state->GetState();
188 NS_LOG_FUNCTION(this << currentState);
189 NS_TEST_ASSERT_MSG_EQ(currentState,
190 expectedState,
191 "PHY State " << currentState << " does not match expected state "
192 << expectedState << " at " << Simulator::Now());
193}
194
195void
197 uint32_t expectedFailureCount)
198{
200 expectedSuccessCount,
201 "Didn't receive right number of successful packets");
203 expectedFailureCount,
204 "Didn't receive right number of unsuccessful packets");
205}
206
207void
209 RxSignalInfo rxSignalInfo,
210 WifiTxVector txVector,
211 std::vector<bool> statusPerMpdu)
212{
213 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
215}
216
217void
219{
220 NS_LOG_FUNCTION(this << *psdu);
222}
223
226{
227 m_phy = nullptr;
228}
229
230void
232{
233 m_phy = CreateObject<SpectrumWifiPhy>();
235 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
236 m_phy->SetInterferenceHelper(interferenceHelper);
237 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel>();
238 m_phy->SetErrorRateModel(error);
244
245 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
246 CreateObject<ThresholdPreambleDetectionModel>();
247 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(4));
248 preambleDetectionModel->SetAttribute("MinimumRssi", DoubleValue(-82));
249 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
250}
251
252void
254{
255 m_phy->Dispose();
256 m_phy = nullptr;
257}
258
259void
261{
264 int64_t streamNumber = 0;
265 m_phy->AssignStreams(streamNumber);
266
267 // RX power > CCA-ED > CCA-PD
268 double rxPowerDbm = -50;
269
270 // CASE 1: send one packet and check PHY state:
271 // All reception stages should succeed and PHY state should be RX for the duration of the packet
272 // minus the time to detect the preamble, otherwise it should be IDLE.
273
276 this,
277 rxPowerDbm);
278 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
279 // CCA_BUSY
282 this,
283 WifiPhyState::IDLE);
286 this,
287 WifiPhyState::CCA_BUSY);
288 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
289 // CCA_BUSY to RX
292 this,
293 WifiPhyState::CCA_BUSY);
296 this,
297 WifiPhyState::RX);
298 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
301 this,
302 WifiPhyState::RX);
305 this,
306 WifiPhyState::IDLE);
307 // Packet should have been successfully received
310 this,
311 1,
312 0);
313
314 // CASE 2: send two packets with same power within the 4us window and check PHY state:
315 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
316 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
317 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
318 // time to detect the preamble.
319
322 this,
323 rxPowerDbm);
326 this,
327 rxPowerDbm);
328 // At 4us, no preamble is successfully detected and STA PHY STATE should move from IDLE to
329 // CCA_BUSY
332 this,
333 WifiPhyState::IDLE);
336 this,
337 WifiPhyState::CCA_BUSY);
338 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
339 // = 154.8us
342 this,
343 WifiPhyState::CCA_BUSY);
346 this,
347 WifiPhyState::IDLE);
348 // No more packet should have been successfully received, and since preamble detection did not
349 // pass, the packet should not have been counted as a failure
352 this,
353 1,
354 0);
355
356 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY
357 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
358 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
359 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
360 // time to detect the preamble.
361
364 this,
365 rxPowerDbm);
368 this,
369 rxPowerDbm - 3);
370 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
371 // CCA_BUSY
374 this,
375 WifiPhyState::IDLE);
378 this,
379 WifiPhyState::CCA_BUSY);
380 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
381 // = 154.8us
384 this,
385 WifiPhyState::CCA_BUSY);
388 this,
389 WifiPhyState::IDLE);
390 // No more packet should have been successfully received, and since preamble detection did not
391 // pass the packet should not have been counted as a failure
394 this,
395 1,
396 0);
397
398 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY
399 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
400 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
401 // decode the modulation).
402
405 this,
406 rxPowerDbm);
409 this,
410 rxPowerDbm - 6);
411 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
412 // CCA_BUSY
415 this,
416 WifiPhyState::IDLE);
419 this,
420 WifiPhyState::CCA_BUSY);
421 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
422 // CCA_BUSY to RX
425 this,
426 WifiPhyState::CCA_BUSY);
429 this,
430 WifiPhyState::RX);
431 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
432 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
433 // should first be seen as CCA_BUSY for 2us.
436 this,
437 WifiPhyState::RX);
440 this,
441 WifiPhyState::CCA_BUSY);
444 this,
445 WifiPhyState::CCA_BUSY);
448 this,
449 WifiPhyState::IDLE);
450 // In this case, the first packet should be marked as a failure
453 this,
454 1,
455 1);
456
457 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY
458 // state: PHY preamble detection should fail because SNR is too low (around -3 dB, which is
459 // lower than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is
460 // above CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus
461 // the time to detect the preamble.
462
465 this,
466 rxPowerDbm);
469 this,
470 rxPowerDbm + 3);
471 // At 6us (hence 4us after the last signal is received), no preamble is successfully detected,
472 // hence STA PHY STATE should move from IDLE to CCA_BUSY
475 this,
476 WifiPhyState::IDLE);
479 this,
480 WifiPhyState::CCA_BUSY);
481 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
482 // = 154.8us
485 this,
486 WifiPhyState::CCA_BUSY);
489 this,
490 WifiPhyState::IDLE);
491 // No more packet should have been successfully received, and since preamble detection did not
492 // pass the packet should not have been counted as a failure
495 this,
496 1,
497 1);
498
499 // CCA-PD < RX power < CCA-ED
500 rxPowerDbm = -70;
501
502 // CASE 6: send one packet and check PHY state:
503 // All reception stages should succeed and PHY state should be RX for the duration of the packet
504 // minus the time to detect the preamble, otherwise it should be IDLE.
505
508 this,
509 rxPowerDbm);
510 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
511 // CCA_BUSY
514 this,
515 WifiPhyState::IDLE);
518 this,
519 WifiPhyState::CCA_BUSY);
520 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
521 // CCA_BUSY to RX
524 this,
525 WifiPhyState::CCA_BUSY);
528 this,
529 WifiPhyState::RX);
530 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
533 this,
534 WifiPhyState::RX);
537 this,
538 WifiPhyState::IDLE);
539 // Packet should have been successfully received
542 this,
543 2,
544 1);
545
546 // CASE 7: send two packets with same power within the 4us window and check PHY state:
547 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
548 // the threshold of 4 dB), and PHY state should be CCA_BUSY since it should detect the start of
549 // a valid OFDM transmission at a receive level greater than or equal to the minimum modulation
550 // and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
551
554 this,
555 rxPowerDbm);
558 this,
559 rxPowerDbm);
560 // At 4us, STA PHY STATE should stay IDLE
563 this,
564 WifiPhyState::CCA_BUSY);
565 // No more packet should have been successfully received, and since preamble detection did not
566 // pass the packet should not have been counted as a failure
569 this,
570 2,
571 1);
572
573 // CASE 8: send two packets with second one 3 dB weaker within the 4us window and check PHY
574 // state: PHY preamble detection should fail PHY preamble detection should fail because SNR is
575 // too low (around 3 dB, which is lower than the threshold of 4 dB), and PHY state should be
576 // CCA_BUSY since it should detect the start of a valid OFDM transmission at a receive level
577 // greater than or equal to the minimum modulation and coding rate sensitivity (–82 dBm for 20
578 // MHz channel spacing).
579
582 this,
583 rxPowerDbm);
586 this,
587 rxPowerDbm - 3);
588 // At 4us, STA PHY STATE should stay IDLE
591 this,
592 WifiPhyState::CCA_BUSY);
593 // No more packet should have been successfully received, and since preamble detection did not
594 // pass the packet should not have been counted as a failure
597 this,
598 2,
599 1);
600
601 // CASE 9: send two packets with second one 6 dB weaker within the 4us window and check PHY
602 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
603 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
604 // decode the modulation).
605
608 this,
609 rxPowerDbm);
612 this,
613 rxPowerDbm - 6);
614 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
615 // CCA_BUSY
618 this,
619 WifiPhyState::IDLE);
622 this,
623 WifiPhyState::CCA_BUSY);
624 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
625 // CCA_BUSY to RX
628 this,
629 WifiPhyState::CCA_BUSY);
632 this,
633 WifiPhyState::RX);
634 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
635 // 152.8us.
638 this,
639 WifiPhyState::RX);
642 this,
643 WifiPhyState::CCA_BUSY);
644 // In this case, the first packet should be marked as a failure
647 this,
648 2,
649 2);
650
651 // CASE 10: send two packets with second one 3 dB higher within the 4us window and check PHY
652 // state: PHY preamble detection should fail because SNR is too low (around -3 dB, which is
653 // lower than the threshold of 4 dB), and PHY state should stay IDLE since the total energy is
654 // below CCA-ED (-62 dBm).
655
658 this,
659 rxPowerDbm);
662 this,
663 rxPowerDbm + 3);
664 // At 4us, STA PHY STATE should stay IDLE
667 this,
668 WifiPhyState::IDLE);
669 // No more packet should have been successfully received, and since preamble detection did not
670 // pass the packet should not have been counted as a failure
673 this,
674 2,
675 2);
676
677 // CASE 11: send one packet with a power slightly above the minimum RSSI needed for the preamble
678 // detection (-82 dBm) and check PHY state: preamble detection should succeed and PHY state
679 // should move to RX.
680
681 rxPowerDbm = -81;
682
685 this,
686 rxPowerDbm);
687 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
688 // CCA_BUSY
691 this,
692 WifiPhyState::IDLE);
695 this,
696 WifiPhyState::CCA_BUSY);
697 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
698 // CCA_BUSY to RX
701 this,
702 WifiPhyState::CCA_BUSY);
705 this,
706 WifiPhyState::RX);
707 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
710 this,
711 WifiPhyState::RX);
714 this,
715 WifiPhyState::IDLE);
716
717 // RX power < CCA-PD < CCA-ED
718 rxPowerDbm = -83;
719
720 // CASE 12: send one packet with a power slightly below the minimum RSSI needed for the preamble
721 // detection (-82 dBm) and check PHY state: preamble detection should fail and PHY should be
722 // kept in IDLE state.
723
726 this,
727 rxPowerDbm);
728 // At 4us, STA PHY state should be IDLE
731 this,
732 WifiPhyState::IDLE);
733
736}
737
745{
746 public:
749
750 protected:
751 void DoSetup() override;
752 void DoTeardown() override;
758 void SendPacket(double rxPowerDbm);
767 RxSignalInfo rxSignalInfo,
768 WifiTxVector txVector,
769 std::vector<bool> statusPerMpdu);
777
778 private:
779 void DoRun() override;
780
785 void CheckPhyState(WifiPhyState expectedState);
790 void DoCheckPhyState(WifiPhyState expectedState);
796 void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount);
797
798 uint64_t m_uid;
799};
800
802 : TestCase(
803 "Threshold preamble detection model test when simple frame capture model is applied"),
804 m_countRxSuccess(0),
805 m_countRxFailure(0),
806 m_uid(0)
807{
808}
809
810void
812{
813 WifiTxVector txVector =
814 WifiTxVector(HePhy::GetHeMcs7(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
815
816 Ptr<Packet> pkt = Create<Packet>(1000);
817 WifiMacHeader hdr;
818
820 hdr.SetQosTid(0);
821
822 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
823 Time txDuration = m_phy->CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
824
825 Ptr<WifiPpdu> ppdu =
826 Create<HePpdu>(psdu, txVector, FREQUENCY, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
827
828 Ptr<SpectrumValue> txPowerSpectrum =
831 DbmToW(rxPowerDbm),
833
834 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters>();
835 txParams->psd = txPowerSpectrum;
836 txParams->txPhy = nullptr;
837 txParams->duration = txDuration;
838 txParams->ppdu = ppdu;
839
840 m_phy->StartRx(txParams);
841}
842
843void
845{
846 // This is needed to make sure PHY state will be checked as the last event if a state change
847 // occurred at the exact same time as the check
849 this,
850 expectedState);
851}
852
853void
855{
856 WifiPhyState currentState;
857 PointerValue ptr;
858 m_phy->GetAttribute("State", ptr);
859 Ptr<WifiPhyStateHelper> state = DynamicCast<WifiPhyStateHelper>(ptr.Get<WifiPhyStateHelper>());
860 currentState = state->GetState();
861 NS_LOG_FUNCTION(this << currentState);
862 NS_TEST_ASSERT_MSG_EQ(currentState,
863 expectedState,
864 "PHY State " << currentState << " does not match expected state "
865 << expectedState << " at " << Simulator::Now());
866}
867
868void
870 uint32_t expectedFailureCount)
871{
873 expectedSuccessCount,
874 "Didn't receive right number of successful packets");
876 expectedFailureCount,
877 "Didn't receive right number of unsuccessful packets");
878}
879
880void
882 RxSignalInfo rxSignalInfo,
883 WifiTxVector txVector,
884 std::vector<bool> statusPerMpdu)
885{
886 NS_LOG_FUNCTION(this << *psdu << txVector);
888}
889
890void
892{
893 NS_LOG_FUNCTION(this << *psdu);
895}
896
898{
899 m_phy = nullptr;
900}
901
902void
904{
905 m_phy = CreateObject<SpectrumWifiPhy>();
907 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
908 m_phy->SetInterferenceHelper(interferenceHelper);
909 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel>();
910 m_phy->SetErrorRateModel(error);
916
917 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
918 CreateObject<ThresholdPreambleDetectionModel>();
919 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(4));
920 preambleDetectionModel->SetAttribute("MinimumRssi", DoubleValue(-82));
921 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
922
923 Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel>();
924 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
925 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
926 m_phy->SetFrameCaptureModel(frameCaptureModel);
927}
928
929void
931{
932 m_phy->Dispose();
933 m_phy = nullptr;
934}
935
936void
938{
941 int64_t streamNumber = 1;
942 m_phy->AssignStreams(streamNumber);
943
944 // RX power > CCA-ED > CCA-PD
945 double rxPowerDbm = -50;
946
947 // CASE 1: send one packet and check PHY state:
948 // All reception stages should succeed and PHY state should be RX for the duration of the packet
949 // minus the time to detect the preamble, otherwise it should be IDLE.
950
953 this,
954 rxPowerDbm);
955 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
956 // CCA_BUSY
959 this,
960 WifiPhyState::IDLE);
963 this,
964 WifiPhyState::CCA_BUSY);
965 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
966 // CCA_BUSY to RX
969 this,
970 WifiPhyState::CCA_BUSY);
973 this,
974 WifiPhyState::RX);
975 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
978 this,
979 WifiPhyState::RX);
982 this,
983 WifiPhyState::IDLE);
984 // Packet should have been successfully received
987 this,
988 1,
989 0);
990
991 // CASE 2: send two packets with same power within the 4us window and check PHY state:
992 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
993 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
994 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
995 // time to detect the preamble.
996
999 this,
1000 rxPowerDbm);
1003 this,
1004 rxPowerDbm);
1005 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1006 // CCA_BUSY
1009 this,
1010 WifiPhyState::IDLE);
1013 this,
1014 WifiPhyState::CCA_BUSY);
1015 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1016 // = 154.8us
1019 this,
1020 WifiPhyState::CCA_BUSY);
1023 this,
1024 WifiPhyState::IDLE);
1025 // No more packet should have been successfully received, and since preamble detection did not
1026 // pass the packet should not have been counted as a failure
1029 this,
1030 1,
1031 0);
1032
1033 // CASE 3: send two packets with second one 3 dB weaker within the 4us window and check PHY
1034 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
1035 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1036 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1037 // time to detect the preamble.
1038
1041 this,
1042 rxPowerDbm);
1045 this,
1046 rxPowerDbm - 3);
1047 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1048 // CCA_BUSY
1051 this,
1052 WifiPhyState::IDLE);
1055 this,
1056 WifiPhyState::CCA_BUSY);
1057 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1058 // = 154.8us
1061 this,
1062 WifiPhyState::CCA_BUSY);
1065 this,
1066 WifiPhyState::IDLE);
1067 // No more packet should have been successfully received, and since preamble detection did not
1068 // pass the packet should not have been counted as a failure
1071 this,
1072 1,
1073 0);
1074
1075 // CASE 4: send two packets with second one 6 dB weaker within the 4us window and check PHY
1076 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1077 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1078 // decode the modulation).
1079
1082 this,
1083 rxPowerDbm);
1086 this,
1087 rxPowerDbm - 6);
1088 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1089 // CCA_BUSY
1092 this,
1093 WifiPhyState::IDLE);
1096 this,
1097 WifiPhyState::CCA_BUSY);
1098 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1099 // CCA_BUSY to RX
1102 this,
1103 WifiPhyState::CCA_BUSY);
1106 this,
1107 WifiPhyState::RX);
1108 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
1109 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
1110 // should first be seen as CCA_BUSY for 2us.
1113 this,
1114 WifiPhyState::RX);
1117 this,
1118 WifiPhyState::CCA_BUSY);
1121 this,
1122 WifiPhyState::CCA_BUSY);
1125 this,
1126 WifiPhyState::IDLE);
1127 // In this case, the first packet should be marked as a failure
1130 this,
1131 1,
1132 1);
1133
1134 // CASE 5: send two packets with second one 3 dB higher within the 4us window and check PHY
1135 // state: PHY preamble detection should switch because a higher packet is received within the
1136 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1137 // lower than the threshold of 4 dB), PHY state should be CCA_BUSY since the total energy is
1138 // above CCA-ED (-62 dBm).
1139
1142 this,
1143 rxPowerDbm);
1146 this,
1147 rxPowerDbm + 3);
1148 // At 4us, STA PHY STATE should stay IDLE
1151 this,
1152 WifiPhyState::IDLE);
1153 // At 6us, STA PHY STATE should move from IDLE to CCA_BUSY
1156 this,
1157 WifiPhyState::IDLE);
1160 this,
1161 WifiPhyState::CCA_BUSY);
1162 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1163 // = 154.8us
1166 this,
1167 WifiPhyState::CCA_BUSY);
1170 this,
1171 WifiPhyState::IDLE);
1172 // No more packet should have been successfully received, and since preamble detection did not
1173 // pass the packet should not have been counted as a failure
1176 this,
1177 1,
1178 1);
1179
1180 // CASE 6: send two packets with second one 6 dB higher within the 4us window and check PHY
1181 // state: PHY preamble detection should switch because a higher packet is received within the
1182 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1183 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1184 // decode the modulation).
1185
1188 this,
1189 rxPowerDbm);
1192 this,
1193 rxPowerDbm + 6);
1194 // At 4us, STA PHY STATE should stay IDLE
1197 this,
1198 WifiPhyState::IDLE);
1199 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1200 // CCA_BUSY
1203 this,
1204 WifiPhyState::IDLE);
1207 this,
1208 WifiPhyState::CCA_BUSY);
1209 // At 46us, PHY header should be successfully received and STA PHY STATE should move from
1210 // CCA_BUSY to RX
1213 this,
1214 WifiPhyState::CCA_BUSY);
1217 this,
1218 WifiPhyState::RX);
1219 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1220 // = 154.8us
1223 this,
1224 WifiPhyState::RX);
1227 this,
1228 WifiPhyState::IDLE);
1229 // In this case, the second packet should be marked as a failure
1232 this,
1233 1,
1234 2);
1235
1236 // CASE 7: send two packets with same power at the exact same time and check PHY state:
1237 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
1238 // the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1239 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1240 // time to detect the preamble.
1241
1244 this,
1245 rxPowerDbm);
1248 this,
1249 rxPowerDbm);
1250 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1251 // CCA_BUSY
1254 this,
1255 WifiPhyState::IDLE);
1258 this,
1259 WifiPhyState::CCA_BUSY);
1260 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1261 // = 154.8us
1264 this,
1265 WifiPhyState::CCA_BUSY);
1268 this,
1269 WifiPhyState::IDLE);
1270 // No more packet should have been successfully received, and since preamble detection did not
1271 // pass the packet should not have been counted as a failure
1274 this,
1275 1,
1276 2);
1277
1278 // CASE 8: send two packets with second one 3 dB weaker at the exact same time and check PHY
1279 // state: PHY preamble detection should fail because SNR is too low (around 3 dB, which is lower
1280 // than the threshold of 4 dB), and PHY state should be CCA_BUSY since the total energy is above
1281 // CCA-ED (-62 dBm). CCA_BUSY state should last for the duration of the two packets minus the
1282 // time to detect the preamble.
1283
1286 this,
1287 rxPowerDbm);
1290 this,
1291 rxPowerDbm - 3);
1292 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1293 // CCA_BUSY
1296 this,
1297 WifiPhyState::IDLE);
1300 this,
1301 WifiPhyState::CCA_BUSY);
1302 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1305 this,
1306 WifiPhyState::CCA_BUSY);
1309 this,
1310 WifiPhyState::IDLE);
1311 // No more packet should have been successfully received, and since preamble detection did not
1312 // pass the packet should not have been counted as a failure
1315 this,
1316 1,
1317 2);
1318
1319 // CASE 9: send two packets with second one 6 dB weaker at the exact same time and check PHY
1320 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1321 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1322 // decode the modulation).
1323
1326 this,
1327 rxPowerDbm);
1330 this,
1331 rxPowerDbm - 6);
1332 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1333 // CCA_BUSY
1336 this,
1337 WifiPhyState::IDLE);
1340 this,
1341 WifiPhyState::CCA_BUSY);
1342 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1343 // CCA_BUSY to RX
1346 this,
1347 WifiPhyState::CCA_BUSY);
1350 this,
1351 WifiPhyState::RX);
1352 // Since it takes 152.8us to transmit the packets, PHY should be back to IDLE at time 152.8us.
1355 this,
1356 WifiPhyState::RX);
1359 this,
1360 WifiPhyState::IDLE);
1361 // In this case, the first packet should be marked as a failure
1364 this,
1365 1,
1366 3);
1367
1368 // CASE 10: send two packets with second one 3 dB higher at the exact same time and check PHY
1369 // state: PHY preamble detection should switch because a higher packet is received within the
1370 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1371 // lower than the threshold of 4 dB), PHY state should be CCA_BUSY since the total energy is
1372 // above CCA-ED (-62 dBm).
1373
1376 this,
1377 rxPowerDbm);
1380 this,
1381 rxPowerDbm + 3);
1382 // At 4us, no preamble is successfully detected, hence STA PHY STATE should move from IDLE to
1383 // CCA_BUSY
1386 this,
1387 WifiPhyState::IDLE);
1390 this,
1391 WifiPhyState::CCA_BUSY);
1392 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1393 Simulator::Schedule(Seconds(10.0) + NanoSeconds(152799),
1395 this,
1396 WifiPhyState::CCA_BUSY);
1397 Simulator::Schedule(Seconds(10.0) + NanoSeconds(152800),
1399 this,
1400 WifiPhyState::IDLE);
1401 // No more packet should have been successfully received, and since preamble detection did not
1402 // pass the packet should not have been counted as a failure
1405 this,
1406 1,
1407 3);
1408
1409 // CASE 11: send two packets with second one 6 dB higher at the exact same time and check PHY
1410 // state: PHY preamble detection should switch because a higher packet is received within the
1411 // 4us window, and preamble detection should succeed because SNR is high enough (around 6 dB,
1412 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1413 // decode the modulation).
1414
1417 this,
1418 rxPowerDbm);
1421 this,
1422 rxPowerDbm + 6);
1423 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1424 // CCA_BUSY
1427 this,
1428 WifiPhyState::IDLE);
1431 this,
1432 WifiPhyState::CCA_BUSY);
1433 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1434 // CCA_BUSY to RX
1437 this,
1438 WifiPhyState::CCA_BUSY);
1441 this,
1442 WifiPhyState::RX);
1443 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 us
1444 Simulator::Schedule(Seconds(11.0) + NanoSeconds(152799),
1446 this,
1447 WifiPhyState::RX);
1448 Simulator::Schedule(Seconds(11.0) + NanoSeconds(152800),
1450 this,
1451 WifiPhyState::IDLE);
1452 // In this case, the second packet should be marked as a failure
1455 this,
1456 1,
1457 4);
1458
1459 // CCA-PD < RX power < CCA-ED
1460 rxPowerDbm = -70;
1461
1462 // CASE 12: send one packet and check PHY state:
1463 // All reception stages should succeed and PHY state should be RX for the duration of the packet
1464 // minus the time to detect the preamble, otherwise it should be IDLE.
1465
1468 this,
1469 rxPowerDbm);
1470 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1471 // CCA_BUSY
1474 this,
1475 WifiPhyState::IDLE);
1478 this,
1479 WifiPhyState::CCA_BUSY);
1480 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1481 // CCA_BUSY to RX
1484 this,
1485 WifiPhyState::CCA_BUSY);
1488 this,
1489 WifiPhyState::RX);
1490 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us
1491 Simulator::Schedule(Seconds(12.0) + NanoSeconds(152799),
1493 this,
1494 WifiPhyState::RX);
1495 Simulator::Schedule(Seconds(12.0) + NanoSeconds(152800),
1497 this,
1498 WifiPhyState::IDLE);
1499 // Packet should have been successfully received
1502 this,
1503 2,
1504 4);
1505
1506 // CASE 13: send two packets with same power within the 4us window and check PHY state:
1507 // PHY preamble detection should fail because SNR is too low (around 0 dB, which is lower than
1508 // the threshold of 4 dB), and PHY state should be CCA_BUSY since it should detect the start of
1509 // a valid OFDM transmission at a receive level greater than or equal to the minimum modulation
1510 // and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
1511
1514 this,
1515 rxPowerDbm);
1518 this,
1519 rxPowerDbm);
1520 // At 4us, STA PHY STATE should stay IDLE
1523 this,
1524 WifiPhyState::CCA_BUSY);
1525 // No more packet should have been successfully received, and since preamble detection did not
1526 // pass the packet should not have been counted as a failure
1529 this,
1530 2,
1531 4);
1532
1533 // CASE 14: send two packets with second one 3 dB weaker within the 4us window and check PHY
1534 // state: PHY preamble detection should fail PHY preamble detection should fail because SNR is
1535 // too low (around 3 dB, which is lower than the threshold of 4 dB), and PHY state should be
1536 // CCA_BUSY since it should detect the start of a valid OFDM transmission at a receive level
1537 // greater than or equal to the minimum modulation and coding rate sensitivity (–82 dBm for 20
1538 // MHz channel spacing).
1539
1542 this,
1543 rxPowerDbm);
1546 this,
1547 rxPowerDbm - 3);
1548 // At 4us, STA PHY STATE should stay IDLE
1551 this,
1552 WifiPhyState::CCA_BUSY);
1553 // No more packet should have been successfully received, and since preamble detection did not
1554 // pass the packet should not have been counted as a failure
1557 this,
1558 2,
1559 4);
1560
1561 // CASE 15: send two packets with second one 6 dB weaker within the 4us window and check PHY
1562 // state: PHY preamble detection should succeed because SNR is high enough (around 6 dB, which
1563 // is higher than the threshold of 4 dB), but payload reception should fail (SNR too low to
1564 // decode the modulation).
1565
1568 this,
1569 rxPowerDbm);
1572 this,
1573 rxPowerDbm - 6);
1574 // At 4us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1575 // CCA_BUSY
1578 this,
1579 WifiPhyState::IDLE);
1582 this,
1583 WifiPhyState::CCA_BUSY);
1584 // At 44us, PHY header should be successfully received and STA PHY STATE should move from
1585 // CCA_BUSY to RX
1588 this,
1589 WifiPhyState::CCA_BUSY);
1592 this,
1593 WifiPhyState::RX);
1594 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
1595 // 152.8us.
1596 Simulator::Schedule(Seconds(15.0) + NanoSeconds(152799),
1598 this,
1599 WifiPhyState::RX);
1600 Simulator::Schedule(Seconds(15.0) + NanoSeconds(152800),
1602 this,
1603 WifiPhyState::CCA_BUSY);
1604 // In this case, the first packet should be marked as a failure
1607 this,
1608 2,
1609 5);
1610
1611 // CASE 16: send two packets with second one 3 dB higher within the 4us window and check PHY
1612 // state: PHY preamble detection should switch because a higher packet is received within the
1613 // 4us window, but preamble detection should fail because SNR is too low (around 3 dB, which is
1614 // lower than the threshold of 4 dB). and PHY state should be CCA_BUSY since it should detect
1615 // the start of a valid OFDM transmission at a receive level greater than or equal to the
1616 // minimum modulation and coding rate sensitivity (–82 dBm for 20 MHz channel spacing).
1617
1620 this,
1621 rxPowerDbm);
1624 this,
1625 rxPowerDbm + 3);
1626 // At 4us, STA PHY STATE should stay IDLE
1629 this,
1630 WifiPhyState::IDLE);
1631 // At 6us, STA PHY STATE should be CCA_BUSY
1634 this,
1635 WifiPhyState::CCA_BUSY);
1636 // No more packet should have been successfully received, and since preamble detection did not
1637 // pass the packet should not have been counted as a failure
1640 this,
1641 2,
1642 5);
1643
1644 // CASE 17: send two packets with second one 6 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, and preamble detection should succeed because SNR is high enough (around 6 dB,
1647 // which is higher than the threshold of 4 dB), Payload reception should fail (SNR too low to
1648 // decode the modulation).
1649
1652 this,
1653 rxPowerDbm);
1656 this,
1657 rxPowerDbm + 6);
1658 // At 4us, STA PHY STATE should stay IDLE
1661 this,
1662 WifiPhyState::IDLE);
1663 // At 6us, preamble should be successfully detected and STA PHY STATE should move from IDLE to
1664 // CCA_BUSY
1667 this,
1668 WifiPhyState::IDLE);
1671 this,
1672 WifiPhyState::CCA_BUSY);
1673 // At 46us, PHY header should be successfully received and STA PHY STATE should move from
1674 // CCA_BUSY to RX
1677 this,
1678 WifiPhyState::CCA_BUSY);
1681 this,
1682 WifiPhyState::RX);
1683 // Since it takes 152.8us to transmit each packet, PHY should be back to IDLE at time 152.8 + 2
1684 // = 154.8us
1685 Simulator::Schedule(Seconds(17.0) + NanoSeconds(154799),
1687 this,
1688 WifiPhyState::RX);
1689 Simulator::Schedule(Seconds(17.0) + NanoSeconds(154800),
1691 this,
1692 WifiPhyState::IDLE);
1693 // In this case, the second packet should be marked as a failure
1696 this,
1697 2,
1698 6);
1699
1700 rxPowerDbm = -50;
1701 // CASE 18: send two packets with second one 50 dB higher within the 4us window
1702
1705 this,
1706 rxPowerDbm);
1709 this,
1710 rxPowerDbm + 50);
1711 // The second packet should be received successfully
1714 this,
1715 3,
1716 6);
1717
1718 // CASE 19: send two packets with second one 10 dB higher within the 4us window
1719
1722 this,
1723 rxPowerDbm);
1726 this,
1727 rxPowerDbm + 10);
1728 // The second packet should be captured, but not decoded since SNR to low for used MCS
1731 this,
1732 3,
1733 7);
1734
1735 // CASE 20: send two packets with second one 50 dB higher in the same time
1736
1739 this,
1740 rxPowerDbm);
1743 this,
1744 rxPowerDbm + 50);
1745 // The second packet should be received successfully, same as in CASE 13
1748 this,
1749 4,
1750 7);
1751
1752 // CASE 21: send two packets with second one 10 dB higher in the same time
1753
1756 this,
1757 rxPowerDbm);
1760 this,
1761 rxPowerDbm + 10);
1762 // The second packet should be captured, but not decoded since SNR to low for used MCS, same as
1763 // in CASE 19
1766 this,
1767 4,
1768 8);
1769
1772}
1773
1781{
1782 public:
1785
1786 protected:
1787 void DoSetup() override;
1788 void DoTeardown() override;
1789
1790 private:
1791 void DoRun() override;
1792
1796 void Reset();
1802 void SendPacket(double rxPowerDbm, uint32_t packetSize);
1811 RxSignalInfo rxSignalInfo,
1812 WifiTxVector txVector,
1813 std::vector<bool> statusPerMpdu);
1820
1837
1839
1844
1845 uint64_t m_uid;
1846};
1847
1849 : TestCase("Simple frame capture model test"),
1850 m_rxSuccess1000B(false),
1851 m_rxSuccess1500B(false),
1852 m_rxDropped1000B(false),
1853 m_rxDropped1500B(false),
1854 m_uid(0)
1855{
1856}
1857
1858void
1860{
1861 WifiTxVector txVector =
1862 WifiTxVector(HePhy::GetHeMcs0(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
1863
1864 Ptr<Packet> pkt = Create<Packet>(packetSize);
1865 WifiMacHeader hdr;
1866
1868 hdr.SetQosTid(0);
1869
1870 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
1871 Time txDuration = m_phy->CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
1872
1873 Ptr<WifiPpdu> ppdu =
1874 Create<HePpdu>(psdu, txVector, FREQUENCY, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
1875
1876 Ptr<SpectrumValue> txPowerSpectrum =
1879 DbmToW(rxPowerDbm),
1880 GUARD_WIDTH);
1881
1882 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters>();
1883 txParams->psd = txPowerSpectrum;
1884 txParams->txPhy = nullptr;
1885 txParams->duration = txDuration;
1886 txParams->ppdu = ppdu;
1887
1888 m_phy->StartRx(txParams);
1889}
1890
1891void
1893 RxSignalInfo rxSignalInfo,
1894 WifiTxVector txVector,
1895 std::vector<bool> statusPerMpdu)
1896{
1897 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
1898 NS_ASSERT(!psdu->IsAggregate() || psdu->IsSingle());
1899 if (psdu->GetSize() == 1030)
1900 {
1901 m_rxSuccess1000B = true;
1902 }
1903 else if (psdu->GetSize() == 1530)
1904 {
1905 m_rxSuccess1500B = true;
1906 }
1907}
1908
1909void
1911{
1912 NS_LOG_FUNCTION(this << p << reason);
1913 if (p->GetSize() == 1030)
1914 {
1915 m_rxDropped1000B = true;
1916 }
1917 else if (p->GetSize() == 1530)
1918 {
1919 m_rxDropped1500B = true;
1920 }
1921}
1922
1923void
1925{
1926 m_rxSuccess1000B = false;
1927 m_rxSuccess1500B = false;
1928 m_rxDropped1000B = false;
1929 m_rxDropped1500B = false;
1930}
1931
1932void
1934{
1935 NS_TEST_ASSERT_MSG_EQ(m_rxSuccess1000B, true, "Didn't receive 1000B packet");
1936}
1937
1938void
1940{
1941 NS_TEST_ASSERT_MSG_EQ(m_rxSuccess1500B, true, "Didn't receive 1500B packet");
1942}
1943
1944void
1946{
1947 NS_TEST_ASSERT_MSG_EQ(m_rxDropped1000B, true, "Didn't drop 1000B packet");
1948}
1949
1950void
1952{
1953 NS_TEST_ASSERT_MSG_EQ(m_rxDropped1500B, true, "Didn't drop 1500B packet");
1954}
1955
1957{
1958 m_phy = nullptr;
1959}
1960
1961void
1963{
1964 m_phy = CreateObject<SpectrumWifiPhy>();
1966 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
1967 m_phy->SetInterferenceHelper(interferenceHelper);
1968 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel>();
1969 m_phy->SetErrorRateModel(error);
1971
1973 m_phy->TraceConnectWithoutContext("PhyRxDrop",
1975
1976 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
1977 CreateObject<ThresholdPreambleDetectionModel>();
1978 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(2));
1979 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
1980
1981 Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel>();
1982 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
1983 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
1984 m_phy->SetFrameCaptureModel(frameCaptureModel);
1985}
1986
1987void
1989{
1990 m_phy->Dispose();
1991 m_phy = nullptr;
1992}
1993
1994void
1996{
1999 int64_t streamNumber = 2;
2000 double rxPowerDbm = -30;
2001 m_phy->AssignStreams(streamNumber);
2002
2003 // CASE 1: send two packets with same power within the capture window:
2004 // PHY should not switch reception because they have same power.
2005
2008 this,
2009 rxPowerDbm,
2010 1000);
2013 this,
2014 rxPowerDbm,
2015 1500);
2018
2019 // CASE 2: send two packets with second one 6 dB weaker within the capture window:
2020 // PHY should not switch reception because first one has higher power.
2021
2024 this,
2025 rxPowerDbm,
2026 1000);
2029 this,
2030 rxPowerDbm - 6,
2031 1500);
2034 this);
2037
2038 // CASE 3: send two packets with second one 6 dB higher within the capture window:
2039 // PHY should switch reception because the second one has a higher power.
2040
2043 this,
2044 rxPowerDbm,
2045 1000);
2048 this,
2049 rxPowerDbm + 6,
2050 1500);
2054 this);
2056
2057 // CASE 4: send two packets with second one 6 dB higher after the capture window:
2058 // PHY should not switch reception because capture window duration has elapsed when the second
2059 // packet arrives.
2060
2063 this,
2064 rxPowerDbm,
2065 1000);
2068 this,
2069 rxPowerDbm + 6,
2070 1500);
2073
2076}
2077
2085{
2086 public:
2088 ~TestPhyHeadersReception() override;
2089
2090 protected:
2091 void DoSetup() override;
2092 void DoTeardown() override;
2098 void SendPacket(double rxPowerDbm);
2099
2100 private:
2101 void DoRun() override;
2102
2107 void CheckPhyState(WifiPhyState expectedState);
2112 void DoCheckPhyState(WifiPhyState expectedState);
2113
2114 uint64_t m_uid;
2115};
2116
2118 : TestCase("PHY headers reception test"),
2119 m_uid(0)
2120{
2121}
2122
2123void
2125{
2126 WifiTxVector txVector =
2127 WifiTxVector(HePhy::GetHeMcs7(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false);
2128
2129 Ptr<Packet> pkt = Create<Packet>(1000);
2130 WifiMacHeader hdr;
2131
2133 hdr.SetQosTid(0);
2134
2135 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
2136 Time txDuration = m_phy->CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
2137
2138 Ptr<WifiPpdu> ppdu =
2139 Create<HePpdu>(psdu, txVector, FREQUENCY, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
2140
2141 Ptr<SpectrumValue> txPowerSpectrum =
2144 DbmToW(rxPowerDbm),
2145 GUARD_WIDTH);
2146
2147 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters>();
2148 txParams->psd = txPowerSpectrum;
2149 txParams->txPhy = nullptr;
2150 txParams->duration = txDuration;
2151 txParams->ppdu = ppdu;
2152
2153 m_phy->StartRx(txParams);
2154}
2155
2156void
2158{
2159 // This is needed to make sure PHY state will be checked as the last event if a state change
2160 // occurred at the exact same time as the check
2162}
2163
2164void
2166{
2167 WifiPhyState currentState;
2168 PointerValue ptr;
2169 m_phy->GetAttribute("State", ptr);
2170 Ptr<WifiPhyStateHelper> state = DynamicCast<WifiPhyStateHelper>(ptr.Get<WifiPhyStateHelper>());
2171 currentState = state->GetState();
2172 NS_LOG_FUNCTION(this << currentState);
2173 NS_TEST_ASSERT_MSG_EQ(currentState,
2174 expectedState,
2175 "PHY State " << currentState << " does not match expected state "
2176 << expectedState << " at " << Simulator::Now());
2177}
2178
2180{
2181 m_phy = nullptr;
2182}
2183
2184void
2186{
2187 m_phy = CreateObject<SpectrumWifiPhy>();
2189 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
2190 m_phy->SetInterferenceHelper(interferenceHelper);
2191 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel>();
2192 m_phy->SetErrorRateModel(error);
2194}
2195
2196void
2198{
2199 m_phy->Dispose();
2200 m_phy = nullptr;
2201}
2202
2203void
2205{
2208 int64_t streamNumber = 0;
2209 m_phy->AssignStreams(streamNumber);
2210
2211 // RX power > CCA-ED
2212 double rxPowerDbm = -50;
2213
2214 // CASE 1: send one packet followed by a second one with same power between the end of the 4us
2215 // preamble detection window and the start of L-SIG of the first packet: reception should be
2216 // aborted since L-SIG cannot be decoded (SNR too low).
2217
2221 this,
2222 rxPowerDbm);
2223 // At 10 us, STA PHY STATE should be CCA_BUSY.
2226 this,
2227 WifiPhyState::CCA_BUSY);
2228 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX and be kept to
2229 // CCA_BUSY.
2232 this,
2233 WifiPhyState::CCA_BUSY);
2234 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8 + 10
2235 // = 162.8us.
2238 this,
2239 WifiPhyState::CCA_BUSY);
2242 this,
2243 WifiPhyState::IDLE);
2244
2245 // CASE 2: send one packet followed by a second one 3 dB weaker between the end of the 4us
2246 // preamble detection window and the start of L-SIG of the first packet: reception should not be
2247 // aborted since L-SIG can be decoded (SNR high enough).
2248
2252 this,
2253 rxPowerDbm - 3);
2254 // At 10 us, STA PHY STATE should be CCA_BUSY.
2257 this,
2258 WifiPhyState::CCA_BUSY);
2259 // At 44us (end of PHY header), STA PHY STATE should have moved to RX since PHY header reception
2260 // should have succeeded.
2263 this,
2264 WifiPhyState::CCA_BUSY);
2267 this,
2268 WifiPhyState::RX);
2269 // Since it takes 152.8us to transmit the packet, PHY should be back to IDLE at time 152.8us.
2270 // However, since there is a second packet transmitted with a power above CCA-ED (-62 dBm), PHY
2271 // should first be seen as CCA_BUSY for 10us.
2274 this,
2275 WifiPhyState::RX);
2278 this,
2279 WifiPhyState::CCA_BUSY);
2282 this,
2283 WifiPhyState::CCA_BUSY);
2286 this,
2287 WifiPhyState::IDLE);
2288
2289 // CASE 3: send one packet followed by a second one with same power between the end of L-SIG and
2290 // the start of HE-SIG of the first packet: PHY header reception should not succeed but PHY
2291 // should stay in RX state for the duration estimated from L-SIG.
2292
2296 this,
2297 rxPowerDbm);
2298 // At 44us (end of PHY header), STA PHY STATE should not have moved to RX (HE-SIG failed) and be
2299 // kept to CCA_BUSY.
2302 this,
2303 WifiPhyState::CCA_BUSY);
2304 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed,
2305 // i.e. at 152.8us. However, since there is a second packet transmitted with a power above
2306 // CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
2309 this,
2310 WifiPhyState::CCA_BUSY);
2313 this,
2314 WifiPhyState::CCA_BUSY);
2317 this,
2318 WifiPhyState::CCA_BUSY);
2321 this,
2322 WifiPhyState::IDLE);
2323
2324 // CASE 4: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the
2325 // start of HE-SIG of the first packet: PHY header reception should succeed.
2326
2330 this,
2331 rxPowerDbm - 3);
2332 // At 10 us, STA PHY STATE should be CCA_BUSY.
2335 this,
2336 WifiPhyState::CCA_BUSY);
2337 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2338 // should have succeeded.
2341 this,
2342 WifiPhyState::CCA_BUSY);
2345 this,
2346 WifiPhyState::RX);
2347 // STA PHY STATE should move back to IDLE once the duration estimated from L-SIG has elapsed,
2348 // i.e. at 152.8us. However, since there is a second packet transmitted with a power above
2349 // CCA-ED (-62 dBm), PHY should first be seen as CCA_BUSY for 25us.
2352 this,
2353 WifiPhyState::RX);
2356 this,
2357 WifiPhyState::CCA_BUSY);
2360 this,
2361 WifiPhyState::CCA_BUSY);
2364 this,
2365 WifiPhyState::IDLE);
2366
2367 // RX power < CCA-ED
2368 rxPowerDbm = -70;
2369
2370 // CASE 5: send one packet followed by a second one with same power between the end of the 4us
2371 // preamble detection window and the start of L-SIG of the first packet: reception should be
2372 // aborted since L-SIG cannot be decoded (SNR too low).
2373
2377 this,
2378 rxPowerDbm);
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 stay CCA_BUSY because L-SIG reception failed and the
2385 // start of a valid OFDM transmission has been detected
2388 this,
2389 WifiPhyState::CCA_BUSY);
2390
2391 // CASE 6: send one packet followed by a second one 3 dB weaker between the end of the 4us
2392 // preamble detection window and the start of L-SIG of the first packet: reception should not be
2393 // aborted since L-SIG can be decoded (SNR high enough).
2394
2398 this,
2399 rxPowerDbm - 3);
2400 // At 10 us, STA PHY STATE should be CCA_BUSY.
2403 this,
2404 WifiPhyState::CCA_BUSY);
2405 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2406 // succeeded.
2409 this,
2410 WifiPhyState::CCA_BUSY);
2411 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2412 // should have succeeded.
2415 this,
2416 WifiPhyState::CCA_BUSY);
2419 this,
2420 WifiPhyState::RX);
2421 // Since it takes 152.8us to transmit the packet, PHY should be back to CCA_BUSY at time
2422 // 152.8us.
2425 this,
2426 WifiPhyState::RX);
2429 this,
2430 WifiPhyState::CCA_BUSY);
2431
2432 // CASE 7: send one packet followed by a second one with same power between the end of L-SIG and
2433 // the start of HE-SIG of the first packet: PHY header reception should not succeed but PHY
2434 // should stay in RX state for the duration estimated from L-SIG.
2435
2439 this,
2440 rxPowerDbm);
2441 // At 10 us, STA PHY STATE should be CCA_BUSY.
2444 this,
2445 WifiPhyState::CCA_BUSY);
2446 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2447 // succeeded.
2450 this,
2451 WifiPhyState::CCA_BUSY);
2452 // At 44 us (end of HE-SIG), STA PHY STATE should be not have moved to RX since reception of
2453 // HE-SIG should have failed.
2456 this,
2457 WifiPhyState::CCA_BUSY);
2458 // STA PHY STATE should keep CCA_BUSY once the duration estimated from L-SIG has elapsed, i.e.
2459 // at 152.8us.
2462 this,
2463 WifiPhyState::CCA_BUSY);
2464
2465 // CASE 8: send one packet followed by a second one 3 dB weaker between the end of L-SIG and the
2466 // start of HE-SIG of the first packet: PHY header reception should succeed.
2467
2471 this,
2472 rxPowerDbm - 3);
2473 // At 10 us, STA PHY STATE should be CCA_BUSY.
2476 this,
2477 WifiPhyState::CCA_BUSY);
2478 // At 24us (end of L-SIG), STA PHY STATE should be unchanged because L-SIG reception should have
2479 // succeeded.
2482 this,
2483 WifiPhyState::CCA_BUSY);
2484 // At 44 us (end of HE-SIG), STA PHY STATE should move to RX since the PHY header reception
2485 // should have succeeded.
2488 this,
2489 WifiPhyState::CCA_BUSY);
2492 this,
2493 WifiPhyState::RX);
2494 // STA PHY STATE should move back to CCA_BUSY once the duration estimated from L-SIG has
2495 // elapsed, i.e. at 152.8us.
2498 this,
2499 WifiPhyState::RX);
2502 this,
2503 WifiPhyState::CCA_BUSY);
2504
2507}
2508
2516{
2517 public:
2519 ~TestAmpduReception() override;
2520
2521 protected:
2522 void DoSetup() override;
2523 void DoTeardown() override;
2524
2525 private:
2526 void DoRun() override;
2527
2536 RxSignalInfo rxSignalInfo,
2537 WifiTxVector txVector,
2538 std::vector<bool> statusPerMpdu);
2543 void RxFailure(Ptr<const WifiPsdu> psdu);
2560
2564 void ResetBitmaps();
2565
2573 void SendAmpduWithThreeMpdus(double rxPowerDbm, uint32_t referencePacketSize);
2574
2579 void CheckRxSuccessBitmapAmpdu1(uint8_t expected);
2584 void CheckRxSuccessBitmapAmpdu2(uint8_t expected);
2589 void CheckRxFailureBitmapAmpdu1(uint8_t expected);
2594 void CheckRxFailureBitmapAmpdu2(uint8_t expected);
2599 void CheckRxDroppedBitmapAmpdu1(uint8_t expected);
2604 void CheckRxDroppedBitmapAmpdu2(uint8_t expected);
2605
2610 void CheckPhyState(WifiPhyState expectedState);
2611
2613
2616
2619
2622
2623 uint64_t m_uid;
2624};
2625
2627 : TestCase("A-MPDU reception test"),
2628 m_rxSuccessBitmapAmpdu1(0),
2629 m_rxSuccessBitmapAmpdu2(0),
2630 m_rxFailureBitmapAmpdu1(0),
2631 m_rxFailureBitmapAmpdu2(0),
2632 m_rxDroppedBitmapAmpdu1(0),
2633 m_rxDroppedBitmapAmpdu2(0),
2634 m_uid(0)
2635{
2636}
2637
2639{
2640 m_phy = nullptr;
2641}
2642
2643void
2645{
2652}
2653
2654void
2656 RxSignalInfo rxSignalInfo,
2657 WifiTxVector txVector,
2658 std::vector<bool> statusPerMpdu)
2659{
2660 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
2661 if (statusPerMpdu.empty()) // wait for the whole A-MPDU
2662 {
2663 return;
2664 }
2665 NS_ABORT_MSG_IF(psdu->GetNMpdus() != statusPerMpdu.size(),
2666 "Should have one receive status per MPDU");
2667 auto rxOkForMpdu = statusPerMpdu.begin();
2668 for (auto mpdu = psdu->begin(); mpdu != psdu->end(); ++mpdu)
2669 {
2670 if (*rxOkForMpdu)
2671 {
2672 IncrementSuccessBitmap((*mpdu)->GetSize());
2673 }
2674 else
2675 {
2676 IncrementFailureBitmap((*mpdu)->GetSize());
2677 }
2678 ++rxOkForMpdu;
2679 }
2680}
2681
2682void
2684{
2685 if (size == 1030) // A-MPDU 1 - MPDU #1
2686 {
2688 }
2689 else if (size == 1130) // A-MPDU 1 - MPDU #2
2690 {
2691 m_rxSuccessBitmapAmpdu1 |= (1 << 1);
2692 }
2693 else if (size == 1230) // A-MPDU 1 - MPDU #3
2694 {
2695 m_rxSuccessBitmapAmpdu1 |= (1 << 2);
2696 }
2697 else if (size == 1330) // A-MPDU 2 - MPDU #1
2698 {
2700 }
2701 else if (size == 1430) // A-MPDU 2 - MPDU #2
2702 {
2703 m_rxSuccessBitmapAmpdu2 |= (1 << 1);
2704 }
2705 else if (size == 1530) // A-MPDU 2 - MPDU #3
2706 {
2707 m_rxSuccessBitmapAmpdu2 |= (1 << 2);
2708 }
2709}
2710
2711void
2713{
2714 NS_LOG_FUNCTION(this << *psdu);
2715 for (auto mpdu = psdu->begin(); mpdu != psdu->end(); ++mpdu)
2716 {
2717 IncrementFailureBitmap((*mpdu)->GetSize());
2718 }
2719}
2720
2721void
2723{
2724 if (size == 1030) // A-MPDU 1 - MPDU #1
2725 {
2727 }
2728 else if (size == 1130) // A-MPDU 1 - MPDU #2
2729 {
2730 m_rxFailureBitmapAmpdu1 |= (1 << 1);
2731 }
2732 else if (size == 1230) // A-MPDU 1 - MPDU #3
2733 {
2734 m_rxFailureBitmapAmpdu1 |= (1 << 2);
2735 }
2736 else if (size == 1330) // A-MPDU 2 - MPDU #1
2737 {
2739 }
2740 else if (size == 1430) // A-MPDU 2 - MPDU #2
2741 {
2742 m_rxFailureBitmapAmpdu2 |= (1 << 1);
2743 }
2744 else if (size == 1530) // A-MPDU 2 - MPDU #3
2745 {
2746 m_rxFailureBitmapAmpdu2 |= (1 << 2);
2747 }
2748}
2749
2750void
2752{
2753 NS_LOG_FUNCTION(this << p << reason);
2754 if (p->GetSize() == 1030) // A-MPDU 1 - MPDU #1
2755 {
2757 }
2758 else if (p->GetSize() == 1130) // A-MPDU 1 - MPDU #2
2759 {
2760 m_rxDroppedBitmapAmpdu1 |= (1 << 1);
2761 }
2762 else if (p->GetSize() == 1230) // A-MPDU 1 - MPDU #3
2763 {
2764 m_rxDroppedBitmapAmpdu1 |= (1 << 2);
2765 }
2766 else if (p->GetSize() == 1330) // A-MPDU 2 - MPDU #1
2767 {
2769 }
2770 else if (p->GetSize() == 1430) // A-MPDU 2 - MPDU #2
2771 {
2772 m_rxDroppedBitmapAmpdu2 |= (1 << 1);
2773 }
2774 else if (p->GetSize() == 1530) // A-MPDU 2 - MPDU #3
2775 {
2776 m_rxDroppedBitmapAmpdu2 |= (1 << 2);
2777 }
2778}
2779
2780void
2782{
2784 expected,
2785 "RX success bitmap for A-MPDU 1 is not as expected");
2786}
2787
2788void
2790{
2792 expected,
2793 "RX success bitmap for A-MPDU 2 is not as expected");
2794}
2795
2796void
2798{
2800 expected,
2801 "RX failure bitmap for A-MPDU 1 is not as expected");
2802}
2803
2804void
2806{
2808 expected,
2809 "RX failure bitmap for A-MPDU 2 is not as expected");
2810}
2811
2812void
2814{
2816 expected,
2817 "RX dropped bitmap for A-MPDU 1 is not as expected");
2818}
2819
2820void
2822{
2824 expected,
2825 "RX dropped bitmap for A-MPDU 2 is not as expected");
2826}
2827
2828void
2830{
2831 WifiPhyState currentState;
2832 PointerValue ptr;
2833 m_phy->GetAttribute("State", ptr);
2834 Ptr<WifiPhyStateHelper> state = DynamicCast<WifiPhyStateHelper>(ptr.Get<WifiPhyStateHelper>());
2835 currentState = state->GetState();
2836 NS_TEST_ASSERT_MSG_EQ(currentState,
2837 expectedState,
2838 "PHY State " << currentState << " does not match expected state "
2839 << expectedState << " at " << Simulator::Now());
2840}
2841
2842void
2843TestAmpduReception::SendAmpduWithThreeMpdus(double rxPowerDbm, uint32_t referencePacketSize)
2844{
2845 WifiTxVector txVector =
2846 WifiTxVector(HePhy::GetHeMcs0(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, true);
2847
2848 WifiMacHeader hdr;
2850 hdr.SetQosTid(0);
2851
2852 std::vector<Ptr<WifiMpdu>> mpduList;
2853 for (size_t i = 0; i < 3; ++i)
2854 {
2855 Ptr<Packet> p = Create<Packet>(referencePacketSize + i * 100);
2856 mpduList.push_back(Create<WifiMpdu>(p, hdr));
2857 }
2858 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(mpduList);
2859
2860 Time txDuration = m_phy->CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
2861
2862 Ptr<WifiPpdu> ppdu =
2863 Create<HePpdu>(psdu, txVector, FREQUENCY, txDuration, WIFI_PHY_BAND_5GHZ, m_uid++);
2864
2865 Ptr<SpectrumValue> txPowerSpectrum =
2868 DbmToW(rxPowerDbm),
2869 GUARD_WIDTH);
2870
2871 Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters>();
2872 txParams->psd = txPowerSpectrum;
2873 txParams->txPhy = nullptr;
2874 txParams->duration = txDuration;
2875 txParams->ppdu = ppdu;
2876 txParams->txWidth = CHANNEL_WIDTH;
2877
2878 m_phy->StartRx(txParams);
2879}
2880
2881void
2883{
2884 m_phy = CreateObject<SpectrumWifiPhy>();
2886 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
2887 m_phy->SetInterferenceHelper(interferenceHelper);
2888 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel>();
2889 m_phy->SetErrorRateModel(error);
2891
2894 m_phy->TraceConnectWithoutContext("PhyRxDrop",
2896
2897 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
2898 CreateObject<ThresholdPreambleDetectionModel>();
2899 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(2));
2900 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
2901
2902 Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel>();
2903 frameCaptureModel->SetAttribute("Margin", DoubleValue(5));
2904 frameCaptureModel->SetAttribute("CaptureWindow", TimeValue(MicroSeconds(16)));
2905 m_phy->SetFrameCaptureModel(frameCaptureModel);
2906}
2907
2908void
2910{
2911 m_phy->Dispose();
2912 m_phy = nullptr;
2913}
2914
2915void
2917{
2920 int64_t streamNumber = 1;
2921 double rxPowerDbm = -30;
2922 m_phy->AssignStreams(streamNumber);
2923
2925 // CASE 1: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
2926 // power under RX sensitivity. The second A-MPDU is received 2 microseconds after the first
2927 // A-MPDU (i.e. during preamble detection).
2929
2930 // A-MPDU 1
2933 this,
2934 rxPowerDbm - 100,
2935 1000);
2936
2937 // A-MPDU 2
2940 this,
2941 rxPowerDbm,
2942 1300);
2943
2944 // All MPDUs of A-MPDU 1 should have been ignored.
2947 this,
2948 0b00000000);
2951 this,
2952 0b00000000);
2955 this,
2956 0b00000000);
2957
2958 // All MPDUs of A-MPDU 2 should have been successfully received.
2961 this,
2962 0b00000111);
2965 this,
2966 0b00000000);
2969 this,
2970 0b00000000);
2971
2973
2975 // CASE 2: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
2976 // with power under RX sensitivity. The second A-MPDU is received 2 microseconds after the first
2977 // A-MPDU (i.e. during preamble detection).
2979
2980 // A-MPDU 1
2983 this,
2984 rxPowerDbm,
2985 1000);
2986
2987 // A-MPDU 2
2990 this,
2991 rxPowerDbm - 100,
2992 1300);
2993
2994 // All MPDUs of A-MPDU 1 should have been received.
2997 this,
2998 0b00000111);
3001 this,
3002 0b00000000);
3005 this,
3006 0b00000000);
3007
3008 // All MPDUs of A-MPDU 2 should have been ignored.
3011 this,
3012 0b00000000);
3015 this,
3016 0b00000000);
3019 this,
3020 0b00000000);
3021
3023
3025 // CASE 3: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
3026 // power under RX sensitivity. The second A-MPDU is received 10 microseconds after the first
3027 // A-MPDU (i.e. during the frame capture window).
3029
3030 // A-MPDU 1
3033 this,
3034 rxPowerDbm - 100,
3035 1000);
3036
3037 // A-MPDU 2
3040 this,
3041 rxPowerDbm,
3042 1300);
3043
3044 // All MPDUs of A-MPDU 1 should have been ignored.
3047 this,
3048 0b00000000);
3051 this,
3052 0b00000000);
3055 this,
3056 0b00000000);
3057
3058 // All MPDUs of A-MPDU 2 should have been successfully received.
3061 this,
3062 0b00000111);
3065 this,
3066 0b00000000);
3069 this,
3070 0b00000000);
3071
3073
3075 // CASE 4: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
3076 // with power under RX sensitivity. The second A-MPDU is received 10 microseconds after the
3077 // first A-MPDU (i.e. during the frame capture window).
3079
3080 // A-MPDU 1
3083 this,
3084 rxPowerDbm,
3085 1000);
3086
3087 // A-MPDU 2
3090 this,
3091 rxPowerDbm - 100,
3092 1300);
3093
3094 // All MPDUs of A-MPDU 1 should have been received.
3097 this,
3098 0b00000111);
3101 this,
3102 0b00000000);
3105 this,
3106 0b00000000);
3107
3108 // All MPDUs of A-MPDU 2 should have been ignored.
3111 this,
3112 0b00000000);
3115 this,
3116 0b00000000);
3119 this,
3120 0b00000000);
3121
3123
3125 // CASE 5: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
3126 // power under RX sensitivity. The second A-MPDU is received 100 microseconds after the first
3127 // A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
3129
3130 // A-MPDU 1
3133 this,
3134 rxPowerDbm - 100,
3135 1000);
3136
3137 // A-MPDU 2
3140 this,
3141 rxPowerDbm,
3142 1300);
3143
3144 // All MPDUs of A-MPDU 1 should have been ignored.
3147 this,
3148 0b00000000);
3151 this,
3152 0b00000000);
3155 this,
3156 0b00000000);
3157
3158 // All MPDUs of A-MPDU 2 should have been successfully received.
3161 this,
3162 0b00000111);
3165 this,
3166 0b00000000);
3169 this,
3170 0b00000000);
3171
3173
3175 // CASE 6: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
3176 // with power under RX sensitivity. The second A-MPDU is received 100 microseconds after the
3177 // first A-MPDU (i.e. after the frame capture window, during the payload of MPDU #1).
3179
3180 // A-MPDU 1
3183 this,
3184 rxPowerDbm,
3185 1000);
3186
3187 // A-MPDU 2
3190 this,
3191 rxPowerDbm - 100,
3192 1300);
3193
3194 // All MPDUs of A-MPDU 1 should have been received.
3197 this,
3198 0b00000111);
3201 this,
3202 0b00000000);
3205 this,
3206 0b00000000);
3207
3208 // All MPDUs of A-MPDU 2 should have been ignored.
3211 this,
3212 0b00000000);
3215 this,
3216 0b00000000);
3219 this,
3220 0b00000000);
3221
3223
3225 // CASE 7: receive two A-MPDUs (containing each 3 MPDUs) where the first A-MPDU is received with
3226 // power under RX sensitivity. The second A-MPDU is received during the payload of MPDU #2.
3228
3229 // A-MPDU 1
3232 this,
3233 rxPowerDbm - 100,
3234 1000);
3235
3236 // A-MPDU 2
3237 Simulator::Schedule(Seconds(7.0) + NanoSeconds(1100000),
3239 this,
3240 rxPowerDbm,
3241 1300);
3242
3243 // All MPDUs of A-MPDU 1 should have been ignored.
3246 this,
3247 0b00000000);
3250 this,
3251 0b00000000);
3254 this,
3255 0b00000000);
3256
3257 // All MPDUs of A-MPDU 2 should have been successfully received.
3260 this,
3261 0b00000111);
3264 this,
3265 0b00000000);
3268 this,
3269 0b00000000);
3270
3272
3274 // CASE 8: receive two A-MPDUs (containing each 3 MPDUs) where the second A-MPDU is received
3275 // with power under RX sensitivity. The second A-MPDU is received during the payload of MPDU #2.
3277
3278 // A-MPDU 1
3281 this,
3282 rxPowerDbm,
3283 1000);
3284
3285 // A-MPDU 2
3286 Simulator::Schedule(Seconds(8.0) + NanoSeconds(1100000),
3288 this,
3289 rxPowerDbm - 100,
3290 1300);
3291
3292 // All MPDUs of A-MPDU 1 should have been received.
3295 this,
3296 0b00000111);
3299 this,
3300 0b00000000);
3303 this,
3304 0b00000000);
3305
3306 // All MPDUs of A-MPDU 2 should have been ignored.
3309 this,
3310 0b00000000);
3313 this,
3314 0b00000000);
3317 this,
3318 0b00000000);
3319
3321
3323 // CASE 9: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power 3
3324 // dB higher. The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during
3325 // preamble detection).
3327
3328 // A-MPDU 1
3331 this,
3332 rxPowerDbm,
3333 1000);
3334
3335 // A-MPDU 2
3338 this,
3339 rxPowerDbm + 3,
3340 1300);
3341
3342 // All MPDUs of A-MPDU 1 should have been dropped.
3345 this,
3346 0b00000000);
3349 this,
3350 0b00000000);
3353 this,
3354 0b00000111);
3355
3356 // All MPDUs of A-MPDU 2 should have been received with errors.
3359 this,
3360 0b00000000);
3363 this,
3364 0b00000111);
3367 this,
3368 0b00000000);
3369
3371
3373 // CASE 10: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3374 // The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during preamble
3375 // detection).
3377
3378 // A-MPDU 1
3381 this,
3382 rxPowerDbm,
3383 1000);
3384
3385 // A-MPDU 2
3388 this,
3389 rxPowerDbm,
3390 1300);
3391
3392 // All MPDUs of A-MPDU 1 should have been dropped (preamble detection failed).
3395 this,
3396 0b00000000);
3399 this,
3400 0b00000000);
3403 this,
3404 0b00000111);
3405
3406 // All MPDUs of A-MPDU 2 should have been dropped as well.
3409 this,
3410 0b00000000);
3413 this,
3414 0b00000000);
3417 this,
3418 0b00000111);
3419
3421
3423 // CASE 11: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3
3424 // dB higher. The second A-MPDU is received 2 microseconds after the first A-MPDU (i.e. during
3425 // preamble detection).
3427
3428 // A-MPDU 1
3431 this,
3432 rxPowerDbm + 3,
3433 1000);
3434
3435 // A-MPDU 2
3438 this,
3439 rxPowerDbm,
3440 1300);
3441
3442 // All MPDUs of A-MPDU 1 should have been received with errors.
3445 this,
3446 0b00000000);
3449 this,
3450 0b00000111);
3453 this,
3454 0b00000000);
3455
3456 // All MPDUs of A-MPDU 2 should have been dropped.
3459 this,
3460 0b00000000);
3463 this,
3464 0b00000000);
3467 this,
3468 0b00000111);
3469
3471
3473 // CASE 12: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3474 // 3 dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e.
3475 // during the frame capture window).
3477
3478 // A-MPDU 1
3481 this,
3482 rxPowerDbm,
3483 1000);
3484
3485 // A-MPDU 2
3488 this,
3489 rxPowerDbm + 3,
3490 1300);
3491
3492 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and
3493 // thus incorrect decoding of payload).
3496 this,
3497 0b00000000);
3500 this,
3501 0b00000000);
3504 this,
3505 0b00000111);
3506
3507 // All MPDUs of A-MPDU 2 should have been dropped (even though TX power is higher, it is not
3508 // high enough to get the PHY reception switched)
3511 this,
3512 0b00000000);
3515 this,
3516 0b00000000);
3519 this,
3520 0b00000111);
3521
3523
3525 // CASE 13: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3526 // The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during the frame
3527 // capture window).
3529
3530 // A-MPDU 1
3533 this,
3534 rxPowerDbm,
3535 1000);
3536
3537 // A-MPDU 2
3540 this,
3541 rxPowerDbm,
3542 1300);
3543
3544 // All MPDUs of A-MPDU 1 should have been received with errors (PHY header reception failed and
3545 // thus incorrect decoding of payload).
3548 this,
3549 0b00000000);
3552 this,
3553 0b00000000);
3556 this,
3557 0b00000111);
3558
3559 // All MPDUs of A-MPDU 2 should have been dropped as well.
3562 this,
3563 0b00000000);
3566 this,
3567 0b00000000);
3570 this,
3571 0b00000111);
3572
3574
3576 // CASE 14: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 3
3577 // dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during
3578 // the frame capture window).
3580
3581 // A-MPDU 1
3584 this,
3585 rxPowerDbm + 3,
3586 1000);
3587
3588 // A-MPDU 2
3591 this,
3592 rxPowerDbm,
3593 1300);
3594
3595 // All MPDUs of A-MPDU 1 should have been received with errors.
3598 this,
3599 0b00000000);
3602 this,
3603 0b00000111);
3606 this,
3607 0b00000000);
3608
3609 // All MPDUs of A-MPDU 2 should have been dropped.
3612 this,
3613 0b00000000);
3616 this,
3617 0b00000000);
3620 this,
3621 0b00000111);
3622
3624
3626 // CASE 15: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3627 // 6 dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e.
3628 // during the frame capture window).
3630
3631 // A-MPDU 1
3634 this,
3635 rxPowerDbm,
3636 1000);
3637
3638 // A-MPDU 2
3641 this,
3642 rxPowerDbm + 6,
3643 1300);
3644
3645 // All MPDUs of A-MPDU 1 should have been dropped because PHY reception switched to A-MPDU 2.
3648 this,
3649 0b00000000);
3652 this,
3653 0b00000000);
3656 this,
3657 0b00000111);
3658
3659 // All MPDUs of A-MPDU 2 should have been successfully received
3662 this,
3663 0b00000111);
3666 this,
3667 0b00000000);
3670 this,
3671 0b00000000);
3672
3674
3676 // CASE 16: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3677 // dB higher. The second A-MPDU is received 10 microseconds after the first A-MPDU (i.e. during
3678 // the frame capture window).
3680
3681 // A-MPDU 1
3684 this,
3685 rxPowerDbm + 6,
3686 1000);
3687
3688 // A-MPDU 2
3691 this,
3692 rxPowerDbm,
3693 1300);
3694
3695 // All MPDUs of A-MPDU 1 should have been successfully received.
3698 this,
3699 0b00000111);
3702 this,
3703 0b00000000);
3706 this,
3707 0b00000000);
3708
3709 // All MPDUs of A-MPDU 2 should have been dropped.
3712 this,
3713 0b00000000);
3716 this,
3717 0b00000000);
3720 this,
3721 0b00000111);
3722
3724
3726 // CASE 17: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3727 // 6 dB higher. The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after
3728 // the frame capture window, but still during PHY header).
3730
3731 // A-MPDU 1
3734 this,
3735 rxPowerDbm,
3736 1000);
3737
3738 // A-MPDU 2
3741 this,
3742 rxPowerDbm + 6,
3743 1300);
3744
3745 // All MPDUs of A-MPDU 1 should have been received with errors.
3748 this,
3749 0b00000000);
3752 this,
3753 0b00000000);
3756 this,
3757 0b00000111);
3758
3759 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because
3760 // PHY is already in RX state).
3763 this,
3764 0b00000000);
3767 this,
3768 0b00000000);
3771 this,
3772 0b00000111);
3773
3775
3777 // CASE 18: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3778 // dB higher. The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after
3779 // the frame capture window, but still during PHY header).
3781
3782 // A-MPDU 1
3785 this,
3786 rxPowerDbm + 6,
3787 1000);
3788
3789 // A-MPDU 2
3792 this,
3793 rxPowerDbm,
3794 1300);
3795
3796 // All MPDUs of A-MPDU 1 should have been successfully received.
3799 this,
3800 0b00000111);
3803 this,
3804 0b00000000);
3807 this,
3808 0b00000000);
3809
3810 // All MPDUs of A-MPDU 2 should have been dropped.
3813 this,
3814 0b00000000);
3817 this,
3818 0b00000000);
3821 this,
3822 0b00000111);
3823
3825
3827 // CASE 19: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3828 // The second A-MPDU is received 25 microseconds after the first A-MPDU (i.e. after the frame
3829 // capture window, but still during PHY header).
3831
3832 // A-MPDU 1
3835 this,
3836 rxPowerDbm,
3837 1000);
3838
3839 // A-MPDU 2
3842 this,
3843 rxPowerDbm,
3844 1300);
3845
3846 // All MPDUs of A-MPDU 1 should have been received with errors.
3849 this,
3850 0b00000000);
3853 this,
3854 0b00000000);
3857 this,
3858 0b00000111);
3859
3860 // All MPDUs of A-MPDU 2 should have been dropped.
3863 this,
3864 0b00000000);
3867 this,
3868 0b00000000);
3871 this,
3872 0b00000111);
3873
3875
3877 // CASE 20: receive two A-MPDUs (containing each 3 MPDUs) with the second A-MPDU having a power
3878 // 6 dB higher. The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e.
3879 // during the payload of MPDU #1).
3881
3882 // A-MPDU 1
3885 this,
3886 rxPowerDbm,
3887 1000);
3888
3889 // A-MPDU 2
3892 this,
3893 rxPowerDbm + 6,
3894 1300);
3895
3896 // All MPDUs of A-MPDU 1 should have been received with errors.
3899 this,
3900 0b00000000);
3903 this,
3904 0b00000111);
3907 this,
3908 0b00000000);
3909
3910 // All MPDUs of A-MPDU 2 should have been dropped (no reception switch, MPDUs dropped because
3911 // PHY is already in RX state).
3914 this,
3915 0b00000000);
3918 this,
3919 0b00000000);
3922 this,
3923 0b00000111);
3924
3926
3928 // CASE 21: receive two A-MPDUs (containing each 3 MPDUs) with the first A-MPDU having a power 6
3929 // dB higher. The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during
3930 // the payload of MPDU #1).
3932
3933 // A-MPDU 1
3936 this,
3937 rxPowerDbm + 6,
3938 1000);
3939
3940 // A-MPDU 2
3943 this,
3944 rxPowerDbm,
3945 1300);
3946
3947 // All MPDUs of A-MPDU 1 should have been successfully received.
3950 this,
3951 0b00000111);
3954 this,
3955 0b00000000);
3958 this,
3959 0b00000000);
3960
3961 // All MPDUs of A-MPDU 2 should have been dropped.
3964 this,
3965 0b00000000);
3968 this,
3969 0b00000000);
3972 this,
3973 0b00000111);
3974
3976
3978 // CASE 22: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
3979 // The second A-MPDU is received 100 microseconds after the first A-MPDU (i.e. during the
3980 // payload of MPDU #1).
3982
3983 // A-MPDU 1
3986 this,
3987 rxPowerDbm,
3988 1000);
3989
3990 // A-MPDU 2
3993 this,
3994 rxPowerDbm,
3995 1300);
3996
3997 // All MPDUs of A-MPDU 1 should have been received with errors.
4000 this,
4001 0b00000000);
4004 this,
4005 0b00000111);
4008 this,
4009 0b00000000);
4010
4011 // All MPDUs of A-MPDU 2 should have been dropped.
4014 this,
4015 0b00000000);
4018 this,
4019 0b00000000);
4022 this,
4023 0b00000111);
4024
4026
4028 // CASE 23: receive two A-MPDUs (containing each 3 MPDUs) with the same power.
4029 // The second A-MPDU is received during the payload of MPDU #2.
4031
4032 // A-MPDU 1
4035 this,
4036 rxPowerDbm,
4037 1000);
4038
4039 // A-MPDU 2
4040 Simulator::Schedule(Seconds(23.0) + NanoSeconds(1100000),
4042 this,
4043 rxPowerDbm,
4044 1300);
4045
4046 // The first MPDU of A-MPDU 1 should have been successfully received (no interference).
4047 // The two other MPDUs failed due to interference and are marked as failure (and dropped).
4050 this,
4051 0b00000001);
4054 this,
4055 0b00000110);
4058 this,
4059 0b00000000);
4060
4061 // The two first MPDUs of A-MPDU 2 are dropped because PHY is already in RX state (receiving
4062 // A-MPDU 1). The last MPDU of A-MPDU 2 is interference free (A-MPDU 1 transmission is finished)
4063 // but is dropped because its PHY preamble and header were not received.
4066 this,
4067 0b00000000);
4070 this,
4071 0b00000000);
4074 this,
4075 0b00000111);
4076
4078
4081}
4082
4104{
4105 public:
4111
4118 void Dropped(std::string context, Ptr<const Packet> packet, WifiPhyRxfailureReason reason);
4122 void CheckResults();
4123
4124 private:
4125 void DoRun() override;
4126 uint16_t m_dropped;
4127};
4128
4130 : TestCase("Check correct behavior when a STA is receiving a transmission using an unsupported "
4131 "modulation"),
4132 m_dropped(0)
4133{
4134}
4135
4137{
4138}
4139
4140void
4142 Ptr<const Packet> packet,
4144{
4145 // Print if the test is executed through test-runner
4146 if (reason == RXING)
4147 {
4148 std::cout << "Dropped a packet because already receiving" << std::endl;
4149 m_dropped++;
4150 }
4151}
4152
4153void
4155{
4156 uint16_t m_nStations = 2;
4157 NetDeviceContainer m_staDevices;
4158 NetDeviceContainer m_apDevices;
4159
4160 // RngSeedManager::SetSeed (1);
4161 // RngSeedManager::SetRun (40);
4162 int64_t streamNumber = 100;
4163
4164 NodeContainer wifiApNode;
4165 wifiApNode.Create(1);
4166
4167 NodeContainer wifiStaNodes;
4168 wifiStaNodes.Create(m_nStations);
4169
4170 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
4171 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
4172 spectrumChannel->AddPropagationLossModel(lossModel);
4174 CreateObject<ConstantSpeedPropagationDelayModel>();
4175 spectrumChannel->SetPropagationDelayModel(delayModel);
4176
4178 phy.SetChannel(spectrumChannel);
4179
4180 Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue(65535));
4181
4182 WifiHelper wifi;
4183 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
4184
4185 WifiMacHelper mac;
4186 mac.SetType("ns3::StaWifiMac",
4187 "QosSupported",
4188 BooleanValue(true),
4189 "Ssid",
4190 SsidValue(Ssid("non-existent-ssid")));
4191
4192 wifi.SetStandard(WIFI_STANDARD_80211ax);
4193 m_staDevices.Add(wifi.Install(phy, mac, wifiStaNodes.Get(0)));
4194 wifi.SetStandard(WIFI_STANDARD_80211ac);
4195 m_staDevices.Add(wifi.Install(phy, mac, wifiStaNodes.Get(1)));
4196
4197 wifi.SetStandard(WIFI_STANDARD_80211ax);
4198 mac.SetType("ns3::ApWifiMac",
4199 "QosSupported",
4200 BooleanValue(true),
4201 "Ssid",
4202 SsidValue(Ssid("wifi-backoff-ssid")),
4203 "BeaconInterval",
4204 TimeValue(MicroSeconds(102400)),
4205 "EnableBeaconJitter",
4206 BooleanValue(false));
4207
4208 m_apDevices = wifi.Install(phy, mac, wifiApNode);
4209
4210 // schedule association requests at different times
4211 Time init = MilliSeconds(100);
4213
4214 for (uint16_t i = 0; i < m_nStations; i++)
4215 {
4216 dev = DynamicCast<WifiNetDevice>(m_staDevices.Get(i));
4217 Simulator::Schedule(init + i * MicroSeconds(102400),
4219 dev->GetMac(),
4220 Ssid("wifi-backoff-ssid"));
4221 }
4222
4223 // Assign fixed streams to random variables in use
4224 wifi.AssignStreams(m_apDevices, streamNumber);
4225
4226 MobilityHelper mobility;
4227 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
4228
4229 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
4230 positionAlloc->Add(Vector(1.0, 0.0, 0.0));
4231 positionAlloc->Add(Vector(0.0, 1.0, 0.0));
4232 positionAlloc->Add(Vector(-1.0, 0.0, 0.0));
4233 mobility.SetPositionAllocator(positionAlloc);
4234
4235 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
4236 mobility.Install(wifiApNode);
4237 mobility.Install(wifiStaNodes);
4238
4239 // set the TXOP limit on BE AC
4240 dev = DynamicCast<WifiNetDevice>(m_apDevices.Get(0));
4241 PointerValue ptr;
4242 dev->GetMac()->GetAttribute("BE_Txop", ptr);
4243
4244 PacketSocketHelper packetSocket;
4245 packetSocket.Install(wifiApNode);
4246 packetSocket.Install(wifiStaNodes);
4247
4248 // UL Traffic
4249 for (uint16_t i = 0; i < m_nStations; i++)
4250 {
4251 PacketSocketAddress socket;
4252 socket.SetSingleDevice(m_staDevices.Get(0)->GetIfIndex());
4253 socket.SetPhysicalAddress(m_apDevices.Get(0)->GetAddress());
4254 socket.SetProtocol(1);
4255 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
4256 client->SetAttribute("PacketSize", UintegerValue(1500));
4257 client->SetAttribute("MaxPackets", UintegerValue(200));
4258 client->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
4259 client->SetRemote(socket);
4260 wifiStaNodes.Get(i)->AddApplication(client);
4261 client->SetStartTime(MicroSeconds(400000));
4262 client->SetStopTime(Seconds(1.0));
4263 Ptr<PacketSocketClient> legacyStaClient = CreateObject<PacketSocketClient>();
4264 legacyStaClient->SetAttribute("PacketSize", UintegerValue(1500));
4265 legacyStaClient->SetAttribute("MaxPackets", UintegerValue(200));
4266 legacyStaClient->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
4267 legacyStaClient->SetRemote(socket);
4268 wifiStaNodes.Get(i)->AddApplication(legacyStaClient);
4269 legacyStaClient->SetStartTime(MicroSeconds(400000));
4270 legacyStaClient->SetStopTime(Seconds(1.0));
4271 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
4272 server->SetLocal(socket);
4273 wifiApNode.Get(0)->AddApplication(server);
4274 server->SetStartTime(Seconds(0.0));
4275 server->SetStopTime(Seconds(1.0));
4276 }
4277
4278 // Trace dropped packets
4279 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
4281
4284
4285 CheckResults();
4286
4288}
4289
4290void
4292{
4293 NS_TEST_EXPECT_MSG_EQ(m_dropped, 0, "Dropped some packets unexpectedly");
4294}
4295
4308{
4309 public:
4311
4312 private:
4313 void DoSetup() override;
4314 void DoTeardown() override;
4315 void DoRun() override;
4316
4324 void SendPpdu(WifiPhyBand band, uint16_t centerFreqMhz, uint16_t bandwidthMhz);
4325
4334 RxSignalInfo rxSignalInfo,
4335 WifiTxVector txVector,
4336 std::vector<bool> statusPerMpdu);
4337
4342 void RxFailure(Ptr<const WifiPsdu> psdu);
4343
4350
4362 void CheckRx(uint32_t expectedCountRxSuccess,
4363 uint32_t expectedCountRxFailure,
4364 uint32_t expectedCountRxDropped,
4365 std::optional<Time> expectedLastRxSucceeded,
4366 std::optional<Time> expectedLastRxFailed,
4367 std::optional<Time> expectedLastRxDropped);
4368
4372
4373 std::optional<Time> m_lastRxSucceeded;
4374 std::optional<Time> m_lastRxFailed;
4375 std::optional<Time> m_lastRxDropped;
4376
4378};
4379
4381 : TestCase("Check correct behavior when a STA is receiving a transmission using an unsupported "
4382 "bandwidth"),
4383 m_countRxSuccess(0),
4384 m_countRxFailure(0),
4385 m_countRxDropped(0),
4386 m_lastRxSucceeded(std::nullopt),
4387 m_lastRxFailed(std::nullopt),
4388 m_lastRxDropped(std::nullopt)
4389{
4390}
4391
4392void
4394 uint16_t centerFreqMhz,
4395 uint16_t bandwidthMhz)
4396{
4397 auto txVector =
4398 WifiTxVector(HePhy::GetHeMcs0(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, bandwidthMhz, false);
4399
4400 auto pkt = Create<Packet>(1000);
4401 WifiMacHeader hdr;
4402
4404 hdr.SetQosTid(0);
4405
4406 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
4407 Time txDuration = m_phy->CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand());
4408
4409 auto ppdu = Create<HePpdu>(psdu, txVector, centerFreqMhz, txDuration, WIFI_PHY_BAND_5GHZ, 0);
4410
4411 auto txPowerSpectrum =
4413 bandwidthMhz,
4414 DbmToW(-50),
4415 bandwidthMhz);
4416
4417 auto txParams = Create<WifiSpectrumSignalParameters>();
4418 txParams->psd = txPowerSpectrum;
4419 txParams->txPhy = nullptr;
4420 txParams->duration = txDuration;
4421 txParams->ppdu = ppdu;
4422 txParams->txWidth = bandwidthMhz;
4423
4424 m_phy->StartRx(txParams);
4425}
4426
4427void
4429 RxSignalInfo rxSignalInfo,
4430 WifiTxVector txVector,
4431 std::vector<bool> statusPerMpdu)
4432{
4433 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
4436}
4437
4438void
4440{
4441 NS_LOG_FUNCTION(this << *psdu);
4444}
4445
4446void
4448{
4449 NS_LOG_FUNCTION(this << p << reason);
4453}
4454
4455void
4457 uint32_t expectedCountRxFailure,
4458 uint32_t expectedCountRxDropped,
4459 std::optional<Time> expectedLastRxSucceeded,
4460 std::optional<Time> expectedLastRxFailed,
4461 std::optional<Time> expectedLastRxDropped)
4462{
4464 expectedCountRxSuccess,
4465 "Didn't receive right number of successful packets");
4466
4468 expectedCountRxFailure,
4469 "Didn't receive right number of unsuccessful packets");
4470
4472 expectedCountRxDropped,
4473 "Didn't receive right number of dropped packets");
4474
4475 if (expectedCountRxSuccess > 0)
4476 {
4477 NS_ASSERT(m_lastRxSucceeded.has_value());
4478 NS_ASSERT(expectedLastRxSucceeded.has_value());
4480 expectedLastRxSucceeded.value(),
4481 "Didn't receive the last successful packet at the expected time");
4482 }
4483
4484 if (expectedCountRxFailure > 0)
4485 {
4486 NS_ASSERT(m_lastRxFailed.has_value());
4487 NS_ASSERT(expectedLastRxFailed.has_value());
4489 expectedLastRxFailed.value(),
4490 "Didn't receive the last unsuccessful packet at the expected time");
4491 }
4492
4493 if (expectedCountRxDropped > 0)
4494 {
4495 NS_ASSERT(m_lastRxDropped.has_value());
4496 NS_ASSERT(expectedLastRxDropped.has_value());
4498 expectedLastRxDropped.value(),
4499 "Didn't drop the last filtered packet at the expected time");
4500 }
4501}
4502
4503void
4505{
4506 m_phy = CreateObject<SpectrumWifiPhy>();
4508 auto interferenceHelper = CreateObject<InterferenceHelper>();
4509 m_phy->SetInterferenceHelper(interferenceHelper);
4510 auto error = CreateObject<NistErrorRateModel>();
4511 m_phy->SetErrorRateModel(error);
4512
4517 "PhyRxDrop",
4519}
4520
4521void
4523{
4524 m_phy->Dispose();
4525 m_phy = nullptr;
4526}
4527
4528void
4530{
4533
4534 int64_t streamNumber = 0;
4535 m_phy->AssignStreams(streamNumber);
4536
4537 // Case 1: the PHY is operating on channel 36 (20 MHz) and receives a 40 MHz PPDU (channel 38).
4538 // The PPDU should be dropped once HE-SIG-A is successfully received, since it contains
4539 // indication about the BW used for the transmission and the PHY shall detect it is larger than
4540 // its operating BW.
4542
4545 this,
4547 5190,
4548 40);
4549
4550 auto heSigAExpectedRxTime = Seconds(1.0) + MicroSeconds(32);
4553 this,
4554 0,
4555 0,
4556 1,
4557 std::nullopt,
4558 std::nullopt,
4559 heSigAExpectedRxTime);
4560
4561 // TODO: this test can be extended with other scenarios
4562
4565}
4566
4576{
4577 public:
4579
4580 private:
4581 void DoSetup() override;
4582 void DoRun() override;
4583 void DoTeardown() override;
4584
4592 Ptr<HePpdu> CreatePpdu(WifiPhyBand band, uint16_t ppduCenterFreqMhz);
4593
4606 void RunOne(WifiPhyBand band,
4607 uint16_t phyCenterFreqMhz,
4608 uint8_t p20Index,
4609 uint16_t ppduCenterFreqMhz,
4610 bool expectedP20Overlap,
4611 bool expectedP20Covered);
4612
4614};
4615
4617 : TestCase("Check correct detection of whether P20 is fully covered (hence it can be received) "
4618 "or overlaps with the bandwidth of an incoming PPDU")
4619{
4620}
4621
4624{
4625 [[maybe_unused]] auto [channelNumber, centerFreq, channelWidth, type, phyBand] =
4626 (*WifiPhyOperatingChannel::FindFirst(0, ppduCenterFreqMhz, 0, WIFI_STANDARD_80211ax, band));
4627
4628 auto txVector =
4629 WifiTxVector(HePhy::GetHeMcs7(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, channelWidth, false);
4630
4631 auto pkt = Create<Packet>(1000);
4633
4634 auto psdu = Create<WifiPsdu>(pkt, hdr);
4635 auto txDuration = m_phy->CalculateTxDuration(psdu->GetSize(), txVector, band);
4636
4637 return Create<HePpdu>(psdu, txVector, ppduCenterFreqMhz, txDuration, band, 0);
4638}
4639
4640void
4642{
4643 m_phy = CreateObject<SpectrumWifiPhy>();
4645 auto interferenceHelper = CreateObject<InterferenceHelper>();
4646 m_phy->SetInterferenceHelper(interferenceHelper);
4647 auto error = CreateObject<NistErrorRateModel>();
4648 m_phy->SetErrorRateModel(error);
4649}
4650
4651void
4653{
4654 m_phy->Dispose();
4655 m_phy = nullptr;
4656}
4657
4658void
4660 uint16_t phyCenterFreqMhz,
4661 uint8_t p20Index,
4662 uint16_t ppduCenterFreqMhz,
4663 bool expectedP20Overlap,
4664 bool expectedP20Covered)
4665{
4666 [[maybe_unused]] const auto [channelNumber, centerFreq, channelWidth, type, phyBand] =
4667 (*WifiPhyOperatingChannel::FindFirst(0, phyCenterFreqMhz, 0, WIFI_STANDARD_80211ax, band));
4668
4669 m_phy->SetOperatingChannel(WifiPhy::ChannelTuple{channelNumber, channelWidth, band, p20Index});
4671 auto p20MinFreq = p20CenterFreq - 10;
4672 auto p20MaxFreq = p20CenterFreq + 10;
4673
4674 auto ppdu = CreatePpdu(band, ppduCenterFreqMhz);
4675
4676 auto p20Overlap = ppdu->DoesOverlapChannel(p20MinFreq, p20MaxFreq);
4677 NS_TEST_ASSERT_MSG_EQ(p20Overlap,
4678 expectedP20Overlap,
4679 "PPDU is " << (expectedP20Overlap ? "expected" : "not expected")
4680 << " to overlap with the P20");
4681
4682 auto p20Covered =
4684 ->CanStartRx(
4685 ppdu,
4686 ppdu->GetTxVector()
4687 .GetChannelWidth()); // CanStartRx returns true is the P20 is fully covered
4688 NS_TEST_ASSERT_MSG_EQ(p20Covered,
4689 expectedP20Covered,
4690 "PPDU is " << (expectedP20Covered ? "expected" : "not expected")
4691 << " to cover the whole P20");
4692}
4693
4694void
4696{
4697 /*
4698 * Receiver PHY Operating Channel: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4699 * Transmitted 20 MHz PPDU: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4700 * Overlap with primary 20 MHz: yes
4701 * Primary 20 MHz fully covered: yes
4702 */
4703 RunOne(WIFI_PHY_BAND_2_4GHZ, 2427, 0, 2427, true, true);
4704
4705 /*
4706 * Receiver PHY Operating Channel: 2.4 GHz Channel 4 (2417 MHz – 2437 MHz)
4707 * Transmitted 40 MHz PPDU: 2.4 GHz Channel 6 (2427 MHz – 2447 MHz)
4708 * Overlap with primary 20 MHz: yes
4709 * Primary 20 MHz fully covered: no
4710 */
4711 RunOne(WIFI_PHY_BAND_2_4GHZ, 2427, 0, 2437, true, false);
4712
4713 /*
4714 * Receiver PHY Operating Channel: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4715 * Transmitted 40 MHz PPDU: 5 GHz Channel 38 (5170 MHz – 5210 MHz)
4716 * Overlap with primary 20 MHz: yes
4717 * Primary 20 MHz fully covered: yes
4718 */
4719 RunOne(WIFI_PHY_BAND_5GHZ, 5180, 0, 5190, true, true);
4720
4721 /*
4722 * Receiver PHY Operating Channel: 5 GHz Channel 36 (5170 MHz–5190 MHz)
4723 * Transmitted 20 MHz PPDU: 5 GHz Channel 40 (5190 MHz – 5210 MHz)
4724 * Overlap with primary 20 MHz: no
4725 * Primary 20 MHz fully covered: no
4726 */
4727 RunOne(WIFI_PHY_BAND_5GHZ, 5180, 0, 5200, false, false);
4728
4729 /*
4730 * Receiver PHY Operating Channel: 5 GHz Channel 38 (5170 MHz – 5210 MHz) with P20 index 0
4731 * Transmitted 20 MHz PPDU: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4732 * Overlap with primary 20 MHz: yes
4733 * Primary 20 MHz fully covered: yes
4734 */
4735 RunOne(WIFI_PHY_BAND_5GHZ, 5190, 0, 5180, true, true);
4736
4737 /*
4738 * Receiver PHY Operating Channel: 5 GHz Channel 38 (5170 MHz – 5210 MHz) with P20 index 1
4739 * Transmitted 20 MHz PPDU: 5 GHz Channel 36 (5170 MHz – 5190 MHz)
4740 * Overlap with primary 20 MHz: no
4741 * Primary 20 MHz fully covered: no
4742 */
4743 RunOne(WIFI_PHY_BAND_5GHZ, 5190, 1, 5180, false, false);
4744
4746}
4747
4755{
4756 public:
4758};
4759
4761 : TestSuite("wifi-phy-reception", UNIT)
4762{
4771}
4772
A-MPDU reception test.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
RX success function.
void IncrementSuccessBitmap(uint32_t size)
Increment reception success bitmap.
uint8_t m_rxDroppedBitmapAmpdu2
bitmap of dropped MPDUs in A-MPDU #2
void CheckRxSuccessBitmapAmpdu2(uint8_t expected)
Check the RX success bitmap for A-MPDU 2.
void DoRun() override
Implementation to actually run this TestCase.
void CheckRxDroppedBitmapAmpdu1(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 1.
uint8_t m_rxSuccessBitmapAmpdu1
bitmap of successfully received MPDUs in A-MPDU #1
uint8_t m_rxFailureBitmapAmpdu1
bitmap of unsuccessfuly received MPDUs in A-MPDU #1
uint8_t m_rxFailureBitmapAmpdu2
bitmap of unsuccessfuly received MPDUs in A-MPDU #2
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void SendAmpduWithThreeMpdus(double rxPowerDbm, uint32_t referencePacketSize)
Send A-MPDU with 3 MPDUs of different size (i-th MSDU will have 100 bytes more than (i-1)-th).
void RxFailure(Ptr< const WifiPsdu > psdu)
RX failure function.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void CheckRxFailureBitmapAmpdu2(uint8_t expected)
Check the RX failure bitmap for A-MPDU 2.
uint8_t m_rxDroppedBitmapAmpdu1
bitmap of dropped MPDUs in A-MPDU #1
void IncrementFailureBitmap(uint32_t size)
Increment reception failure bitmap.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void ResetBitmaps()
Reset bitmaps function.
void CheckPhyState(WifiPhyState expectedState)
Check the PHY state.
void CheckRxSuccessBitmapAmpdu1(uint8_t expected)
Check the RX success bitmap for A-MPDU 1.
void CheckRxFailureBitmapAmpdu1(uint8_t expected)
Check the RX failure bitmap for A-MPDU 1.
uint8_t m_rxSuccessBitmapAmpdu2
bitmap of successfully received MPDUs in A-MPDU #2
Ptr< SpectrumWifiPhy > m_phy
Phy.
void CheckRxDroppedBitmapAmpdu2(uint8_t expected)
Check the RX dropped bitmap for A-MPDU 2.
Test PHY state upon success or failure of L-SIG and SIG-A.
void DoRun() override
Implementation to actually run this TestCase.
void SendPacket(double rxPowerDbm)
Send packet function.
Ptr< SpectrumWifiPhy > m_phy
Phy.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
uint64_t m_uid
the UID to use for the PPDU
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Primary 20 MHz Covered By Ppdu Test This test checks whether the functions WifiPpdu::DoesOverlapChann...
void RunOne(WifiPhyBand band, uint16_t phyCenterFreqMhz, uint8_t p20Index, uint16_t ppduCenterFreqMhz, bool expectedP20Overlap, bool expectedP20Covered)
Run one function.
Ptr< SpectrumWifiPhy > m_phy
PHY.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
Ptr< HePpdu > CreatePpdu(WifiPhyBand band, uint16_t ppduCenterFreqMhz)
Function to create a PPDU.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Simple frame capture model test.
void Expect1000BPacketReceived()
Verify whether 1000 bytes packet has been received.
bool m_rxDropped1500B
count dropped packets with 1500B payload
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void Expect1500BPacketDropped()
Verify whether 1500 bytes packet has been dropped.
void Expect1000BPacketDropped()
Verify whether 1000 bytes packet has been dropped.
void SendPacket(double rxPowerDbm, uint32_t packetSize)
Send packet function.
Ptr< SpectrumWifiPhy > m_phy
Phy.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void RxDropped(Ptr< const Packet > p, WifiPhyRxfailureReason reason)
RX dropped function.
void DoRun() override
Implementation to actually run this TestCase.
bool m_rxSuccess1000B
count received packets with 1000B payload
bool m_rxSuccess1500B
count received packets with 1500B payload
void Expect1500BPacketReceived()
Verify whether 1500 bytes packet has been received.
uint64_t m_uid
the UID to use for the PPDU
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
bool m_rxDropped1000B
count dropped packets with 1000B payload
Preamble detection test w/o frame capture.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void SendPacket(double rxPowerDbm)
Send packet function.
void RxFailure(Ptr< const WifiPsdu > psdu)
Spectrum wifi receive failure function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void DoRun() override
Implementation to actually run this TestCase.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
Preamble detection test w/o frame capture.
void DoRun() override
Implementation to actually run this TestCase.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Spectrum wifi receive success function.
void CheckRxPacketCount(uint32_t expectedSuccessCount, uint32_t expectedFailureCount)
Check the number of received packets.
void DoCheckPhyState(WifiPhyState expectedState)
Check the PHY state now.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void SendPacket(double rxPowerDbm)
Send packet function.
void CheckPhyState(WifiPhyState expectedState)
Schedule now to check the PHY state.
void RxFailure(Ptr< const WifiPsdu > psdu)
Spectrum wifi receive failure function.
Unsupported Bandwidth Reception Test This test checks whether a PHY receiving a PPDU sent over a chan...
void DoSetup() override
Implementation to do any local setup required for this TestCase.
std::optional< Time > m_lastRxDropped
time of last RX drop, if any
std::optional< Time > m_lastRxSucceeded
time of last RX success, if any
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void CheckRx(uint32_t expectedCountRxSuccess, uint32_t expectedCountRxFailure, uint32_t expectedCountRxDropped, std::optional< Time > expectedLastRxSucceeded, std::optional< Time > expectedLastRxFailed, std::optional< Time > expectedLastRxDropped)
Check the reception results.
void RxFailure(Ptr< const WifiPsdu > psdu)
Function called upon a PSDU received unsuccessfuly.
void RxSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Function called upon a PSDU received successfully.
void DoRun() override
Implementation to actually run this TestCase.
std::optional< Time > m_lastRxFailed
time of last RX failure, if any
void SendPpdu(WifiPhyBand band, uint16_t centerFreqMhz, uint16_t bandwidthMhz)
Function to create a PPDU.
void RxDropped(Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Function called upon a PSDU dropped by the PHY.
Unsupported Modulation Reception Test This test creates a mixed network, in which an HE STA and a VHT...
void DoRun() override
Implementation to actually run this TestCase.
void CheckResults()
Check correctness of transmitted frames.
void Dropped(std::string context, Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Callback invoked when PHY drops an incoming packet.
uint16_t m_dropped
number of packets dropped by the AP because it was already receiving
wifi PHY reception Test Suite
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
static WifiMode GetHeMcs7()
Return MCS 7 from HE MCS values.
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:311
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:240
void Dispose()
Dispose of this Object.
Definition: object.cc:219
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get() const
Definition: pointer.h:206
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static void Run()
Run the simulation.
Definition: simulator.cc:176
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
Make it easy to create and manage PHY objects for the spectrum model.
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level PHY interface to this Sp...
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
encapsulates test code
Definition: test.h:1060
@ QUICK
Fast test.
Definition: test.h:1065
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:325
Implements the IEEE 802.11 MAC header.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
create MAC layers for a ns3::WifiNetDevice.
void SetSsid(Ssid ssid)
Definition: wifi-mac.cc:449
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition: wifi-phy.cc:624
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:632
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:448
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:941
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1480
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:1062
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:996
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:704
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:652
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:442
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:646
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:870
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1008
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: wifi-phy.cc:2184
static ConstIterator FindFirst(uint8_t number, uint16_t frequency, uint16_t width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first channel matching the specified parameters.
uint16_t GetPrimaryChannelCenterFrequency(uint16_t primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
This objects implements the PHY state machine of the Wifi device.
static Ptr< SpectrumValue > CreateHeOfdmTxPowerSpectralDensity(uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth, double minInnerBandDbr=-20, double minOuterbandDbr=-28, double lowestPointDbr=-40, const std::vector< bool > &puncturedSubchannels=std::vector< bool >{})
Create a transmit power spectral density corresponding to OFDM High Efficiency (HE) (802....
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:975
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1372
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ UNSUPPORTED_SETTINGS
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:40
@ WIFI_MAC_QOSDATA
STL namespace.
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:70
static const uint8_t CHANNEL_NUMBER
static const uint16_t GUARD_WIDTH
static const uint16_t CHANNEL_WIDTH
static WifiPhyReceptionTestSuite wifiPhyReceptionTestSuite
the test suite
static const uint32_t FREQUENCY
WifiPhyState
The state of the PHY layer.
static const uint32_t packetSize
Packet size generated at the AP.