A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-phy-ofdma-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 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/ap-wifi-mac.h"
21#include "ns3/boolean.h"
22#include "ns3/constant-position-mobility-model.h"
23#include "ns3/ctrl-headers.h"
24#include "ns3/double.h"
25#include "ns3/he-configuration.h"
26#include "ns3/he-phy.h"
27#include "ns3/he-ppdu.h"
28#include "ns3/interference-helper.h"
29#include "ns3/log.h"
30#include "ns3/mobility-helper.h"
31#include "ns3/multi-model-spectrum-channel.h"
32#include "ns3/nist-error-rate-model.h"
33#include "ns3/node.h"
34#include "ns3/non-communicating-net-device.h"
35#include "ns3/pointer.h"
36#include "ns3/rng-seed-manager.h"
37#include "ns3/simulator.h"
38#include "ns3/spectrum-wifi-helper.h"
39#include "ns3/spectrum-wifi-phy.h"
40#include "ns3/sta-wifi-mac.h"
41#include "ns3/string.h"
42#include "ns3/test.h"
43#include "ns3/threshold-preamble-detection-model.h"
44#include "ns3/waveform-generator.h"
45#include "ns3/wifi-mac-header.h"
46#include "ns3/wifi-net-device.h"
47#include "ns3/wifi-phy-listener.h"
48#include "ns3/wifi-psdu.h"
49#include "ns3/wifi-spectrum-phy-interface.h"
50#include "ns3/wifi-spectrum-signal-parameters.h"
51#include "ns3/wifi-spectrum-value-helper.h"
52#include "ns3/wifi-utils.h"
53
54#include <algorithm>
55#include <iterator>
56#include <memory>
57
58using namespace ns3;
59
60NS_LOG_COMPONENT_DEFINE("WifiPhyOfdmaTest");
61
62static const uint8_t DEFAULT_CHANNEL_NUMBER = 36;
63static const uint32_t DEFAULT_FREQUENCY = 5180; // MHz
65static const uint16_t DEFAULT_CHANNEL_WIDTH = 20; // MHz
66static const uint16_t DEFAULT_GUARD_WIDTH =
67 DEFAULT_CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
68
73class OfdmaTestHePhy : public HePhy
74{
75 public:
81 OfdmaTestHePhy(uint16_t staId);
82 ~OfdmaTestHePhy() override;
83
91 uint16_t GetStaId(const Ptr<const WifiPpdu> ppdu) const override;
92
98 void SetGlobalPpduUid(uint64_t uid);
99
100 private:
101 uint16_t m_staId;
102}; // class OfdmaTestHePhy
103
105 : HePhy(),
106 m_staId(staId)
107{
108}
109
111{
112}
113
114uint16_t
116{
117 if (ppdu->GetType() == WIFI_PPDU_TYPE_DL_MU)
118 {
119 return m_staId;
120 }
121 return HePhy::GetStaId(ppdu);
122}
123
124void
126{
127 m_globalPpduUid = uid;
128}
129
134{
135 public:
140 static TypeId GetTypeId();
146 OfdmaSpectrumWifiPhy(uint16_t staId);
147 ~OfdmaSpectrumWifiPhy() override;
148
149 void DoInitialize() override;
150 void DoDispose() override;
151
152 using WifiPhy::Reset;
153 void StartTx(Ptr<const WifiPpdu> ppdu) override;
154
160 typedef void (*TxPpduUidCallback)(uint64_t uid);
161
167 void SetPpduUid(uint64_t uid);
168
174 void SetTriggerFrameUid(uint64_t uid);
175
179 std::map<std::pair<uint64_t, WifiPreamble>, Ptr<Event>>& GetCurrentPreambleEvents();
184
195 Time GetEnergyDuration(double energyW, WifiSpectrumBandInfo band);
196
201
202 private:
206}; // class OfdmaSpectrumWifiPhy
207
208TypeId
210{
211 static TypeId tid =
212 TypeId("ns3::OfdmaSpectrumWifiPhy")
214 .SetGroupName("Wifi")
215 .AddTraceSource("TxPpduUid",
216 "UID of the PPDU to be transmitted",
218 "ns3::OfdmaSpectrumWifiPhy::TxPpduUidCallback");
219 return tid;
220}
221
224{
225 m_ofdmTestHePhy = Create<OfdmaTestHePhy>(staId);
227}
228
230{
231}
232
233void
235{
236 // Replace HE PHY instance with test instance
239}
240
241void
243{
244 m_ofdmTestHePhy = nullptr;
246}
247
248void
250{
253}
254
255void
257{
259}
260
261void
263{
264 m_phyTxPpduUidTrace(ppdu->GetUid());
266}
267
268std::map<std::pair<uint64_t, WifiPreamble>, Ptr<Event>>&
270{
272}
273
276{
277 return m_currentEvent;
278}
279
280Time
282{
283 return m_interference->GetEnergyDuration(energyW, band);
284}
285
288{
289 return DynamicCast<const HePhy>(GetLatestPhyEntity());
290}
291
299{
300 public:
303
304 private:
305 void DoSetup() override;
306 void DoTeardown() override;
307 void DoRun() override;
308
317 RxSignalInfo rxSignalInfo,
318 WifiTxVector txVector,
319 std::vector<bool> statusPerMpdu);
328 RxSignalInfo rxSignalInfo,
329 WifiTxVector txVector,
330 std::vector<bool> statusPerMpdu);
339 RxSignalInfo rxSignalInfo,
340 WifiTxVector txVector,
341 std::vector<bool> statusPerMpdu);
342
358
365 void CheckResultsSta1(uint32_t expectedRxSuccess,
366 uint32_t expectedRxFailure,
367 uint32_t expectedRxBytes);
374 void CheckResultsSta2(uint32_t expectedRxSuccess,
375 uint32_t expectedRxFailure,
376 uint32_t expectedRxBytes);
383 void CheckResultsSta3(uint32_t expectedRxSuccess,
384 uint32_t expectedRxFailure,
385 uint32_t expectedRxBytes);
386
390 void ResetResults();
391
397 void SendMuPpdu(uint16_t rxStaId1, uint16_t rxStaId2);
398
404 void GenerateInterference(Ptr<SpectrumValue> interferencePsd, Time duration);
408 void StopInterference();
409
413 void RunOne();
414
427
437
443
444 uint16_t m_frequency;
445 uint16_t m_channelWidth;
447};
448
450 : TestCase("DL-OFDMA PHY test"),
451 m_countRxSuccessSta1(0),
452 m_countRxSuccessSta2(0),
453 m_countRxSuccessSta3(0),
454 m_countRxFailureSta1(0),
455 m_countRxFailureSta2(0),
456 m_countRxFailureSta3(0),
457 m_countRxBytesSta1(0),
458 m_countRxBytesSta2(0),
459 m_countRxBytesSta3(0),
460 m_frequency(DEFAULT_FREQUENCY),
461 m_channelWidth(DEFAULT_CHANNEL_WIDTH),
462 m_expectedPpduDuration(NanoSeconds(306400))
463{
464}
465
466void
468{
478}
479
480void
481TestDlOfdmaPhyTransmission::SendMuPpdu(uint16_t rxStaId1, uint16_t rxStaId2)
482{
483 NS_LOG_FUNCTION(this << rxStaId1 << rxStaId2);
484 WifiConstPsduMap psdus;
486 0,
488 800,
489 1,
490 1,
491 0,
493 false,
494 false);
496 if (m_channelWidth == 20)
497 {
498 ruType = HeRu::RU_106_TONE;
499 txVector.SetRuAllocation({96}, 0);
500 }
501 else if (m_channelWidth == 40)
502 {
503 ruType = HeRu::RU_242_TONE;
504 txVector.SetRuAllocation({192, 192}, 0);
505 }
506 else if (m_channelWidth == 80)
507 {
508 ruType = HeRu::RU_484_TONE;
509 txVector.SetRuAllocation({200, 200, 200, 200}, 0);
510 }
511 else if (m_channelWidth == 160)
512 {
513 ruType = HeRu::RU_996_TONE;
514 txVector.SetRuAllocation({208, 208, 208, 208, 208, 208, 208, 208}, 0);
515 }
516 else
517 {
518 NS_ASSERT_MSG(false, "Unsupported channel width");
519 }
520
522
523 HeRu::RuSpec ru1(ruType, 1, true);
524 txVector.SetRu(ru1, rxStaId1);
525 txVector.SetMode(HePhy::GetHeMcs7(), rxStaId1);
526 txVector.SetNss(1, rxStaId1);
527
528 HeRu::RuSpec ru2(ruType, (m_channelWidth == 160 ? 1 : 2), m_channelWidth != 160);
529 txVector.SetRu(ru2, rxStaId2);
530 txVector.SetMode(HePhy::GetHeMcs9(), rxStaId2);
531 txVector.SetNss(1, rxStaId2);
532
533 Ptr<Packet> pkt1 = Create<Packet>(1000);
534 WifiMacHeader hdr1;
536 hdr1.SetQosTid(0);
537 hdr1.SetAddr1(Mac48Address("00:00:00:00:00:01"));
538 hdr1.SetSequenceNumber(1);
539 Ptr<WifiPsdu> psdu1 = Create<WifiPsdu>(pkt1, hdr1);
540 psdus.insert(std::make_pair(rxStaId1, psdu1));
541
542 Ptr<Packet> pkt2 = Create<Packet>(1500);
543 WifiMacHeader hdr2;
545 hdr2.SetQosTid(0);
546 hdr2.SetAddr1(Mac48Address("00:00:00:00:00:02"));
547 hdr2.SetSequenceNumber(2);
548 Ptr<WifiPsdu> psdu2 = Create<WifiPsdu>(pkt2, hdr2);
549 psdus.insert(std::make_pair(rxStaId2, psdu2));
550
551 m_phyAp->Send(psdus, txVector);
552}
553
554void
556{
558 m_phyInterferer->SetPeriod(duration);
561}
562
563void
565{
567}
568
570{
571}
572
573void
575 RxSignalInfo rxSignalInfo,
576 WifiTxVector txVector,
577 std::vector<bool> /*statusPerMpdu*/)
578{
579 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
581 m_countRxBytesSta1 += (psdu->GetSize() - 30);
582}
583
584void
586 RxSignalInfo rxSignalInfo,
587 WifiTxVector txVector,
588 std::vector<bool> /*statusPerMpdu*/)
589{
590 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
592 m_countRxBytesSta2 += (psdu->GetSize() - 30);
593}
594
595void
597 RxSignalInfo rxSignalInfo,
598 WifiTxVector txVector,
599 std::vector<bool> /*statusPerMpdu*/)
600{
601 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
603 m_countRxBytesSta3 += (psdu->GetSize() - 30);
604}
605
606void
608{
609 NS_LOG_FUNCTION(this << *psdu);
611}
612
613void
615{
616 NS_LOG_FUNCTION(this << *psdu);
618}
619
620void
622{
623 NS_LOG_FUNCTION(this << *psdu);
625}
626
627void
629 uint32_t expectedRxFailure,
630 uint32_t expectedRxBytes)
631{
633 expectedRxSuccess,
634 "The number of successfully received packets by STA 1 is not correct!");
636 expectedRxFailure,
637 "The number of unsuccessfuly received packets by STA 1 is not correct!");
639 expectedRxBytes,
640 "The number of bytes received by STA 1 is not correct!");
641}
642
643void
645 uint32_t expectedRxFailure,
646 uint32_t expectedRxBytes)
647{
649 expectedRxSuccess,
650 "The number of successfully received packets by STA 2 is not correct!");
652 expectedRxFailure,
653 "The number of unsuccessfuly received packets by STA 2 is not correct!");
655 expectedRxBytes,
656 "The number of bytes received by STA 2 is not correct!");
657}
658
659void
661 uint32_t expectedRxFailure,
662 uint32_t expectedRxBytes)
663{
665 expectedRxSuccess,
666 "The number of successfully received packets by STA 3 is not correct!");
668 expectedRxFailure,
669 "The number of unsuccessfuly received packets by STA 3 is not correct!");
671 expectedRxBytes,
672 "The number of bytes received by STA 3 is not correct!");
673}
674
675void
677{
678 // This is needed to make sure PHY state will be checked as the last event if a state change
679 // occurred at the exact same time as the check
681}
682
683void
685 WifiPhyState expectedState)
686{
687 WifiPhyState currentState;
688 PointerValue ptr;
689 phy->GetAttribute("State", ptr);
690 Ptr<WifiPhyStateHelper> state = DynamicCast<WifiPhyStateHelper>(ptr.Get<WifiPhyStateHelper>());
691 currentState = state->GetState();
692 NS_LOG_FUNCTION(this << currentState);
693 NS_TEST_ASSERT_MSG_EQ(currentState,
694 expectedState,
695 "PHY State " << currentState << " does not match expected state "
696 << expectedState << " at " << Simulator::Now());
697}
698
699void
701{
702 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
703 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
704 lossModel->SetFrequency(m_frequency * 1e6);
705 spectrumChannel->AddPropagationLossModel(lossModel);
707 CreateObject<ConstantSpeedPropagationDelayModel>();
708 spectrumChannel->SetPropagationDelayModel(delayModel);
709
710 Ptr<Node> apNode = CreateObject<Node>();
711 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice>();
712 m_phyAp = CreateObject<SpectrumWifiPhy>();
713 Ptr<InterferenceHelper> apInterferenceHelper = CreateObject<InterferenceHelper>();
714 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
715 Ptr<ErrorRateModel> apErrorModel = CreateObject<NistErrorRateModel>();
716 m_phyAp->SetErrorRateModel(apErrorModel);
717 m_phyAp->SetDevice(apDev);
718 m_phyAp->AddChannel(spectrumChannel);
720 Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel>();
721 m_phyAp->SetMobility(apMobility);
722 apDev->SetPhy(m_phyAp);
723 apNode->AggregateObject(apMobility);
724 apNode->AddDevice(apDev);
725
726 Ptr<Node> sta1Node = CreateObject<Node>();
727 Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice>();
728 m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy>(1);
729 Ptr<InterferenceHelper> sta1InterferenceHelper = CreateObject<InterferenceHelper>();
730 m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
731 Ptr<ErrorRateModel> sta1ErrorModel = CreateObject<NistErrorRateModel>();
732 m_phySta1->SetErrorRateModel(sta1ErrorModel);
733 m_phySta1->SetDevice(sta1Dev);
734 m_phySta1->AddChannel(spectrumChannel);
739 Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel>();
740 m_phySta1->SetMobility(sta1Mobility);
741 sta1Dev->SetPhy(m_phySta1);
742 sta1Node->AggregateObject(sta1Mobility);
743 sta1Node->AddDevice(sta1Dev);
744
745 Ptr<Node> sta2Node = CreateObject<Node>();
746 Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice>();
747 m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy>(2);
748 Ptr<InterferenceHelper> sta2InterferenceHelper = CreateObject<InterferenceHelper>();
749 m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
750 Ptr<ErrorRateModel> sta2ErrorModel = CreateObject<NistErrorRateModel>();
751 m_phySta2->SetErrorRateModel(sta2ErrorModel);
752 m_phySta2->SetDevice(sta2Dev);
753 m_phySta2->AddChannel(spectrumChannel);
758 Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel>();
759 m_phySta2->SetMobility(sta2Mobility);
760 sta2Dev->SetPhy(m_phySta2);
761 sta2Node->AggregateObject(sta2Mobility);
762 sta2Node->AddDevice(sta2Dev);
763
764 Ptr<Node> sta3Node = CreateObject<Node>();
765 Ptr<WifiNetDevice> sta3Dev = CreateObject<WifiNetDevice>();
766 m_phySta3 = CreateObject<OfdmaSpectrumWifiPhy>(3);
767 Ptr<InterferenceHelper> sta3InterferenceHelper = CreateObject<InterferenceHelper>();
768 m_phySta3->SetInterferenceHelper(sta3InterferenceHelper);
769 Ptr<ErrorRateModel> sta3ErrorModel = CreateObject<NistErrorRateModel>();
770 m_phySta3->SetErrorRateModel(sta3ErrorModel);
771 m_phySta3->SetDevice(sta3Dev);
772 m_phySta3->AddChannel(spectrumChannel);
777 Ptr<ConstantPositionMobilityModel> sta3Mobility = CreateObject<ConstantPositionMobilityModel>();
778 m_phySta3->SetMobility(sta3Mobility);
779 sta3Dev->SetPhy(m_phySta3);
780 sta3Node->AggregateObject(sta3Mobility);
781 sta3Node->AddDevice(sta3Dev);
782
783 Ptr<Node> interfererNode = CreateObject<Node>();
784 Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice>();
785 m_phyInterferer = CreateObject<WaveformGenerator>();
786 m_phyInterferer->SetDevice(interfererDev);
787 m_phyInterferer->SetChannel(spectrumChannel);
789 interfererNode->AddDevice(interfererDev);
790}
791
792void
794{
795 m_phyAp->Dispose();
796 m_phyAp = nullptr;
798 m_phySta1 = nullptr;
800 m_phySta2 = nullptr;
802 m_phySta3 = nullptr;
804 m_phyInterferer = nullptr;
805}
806
807void
809{
812 int64_t streamNumber = 0;
813 m_phyAp->AssignStreams(streamNumber);
814 m_phySta1->AssignStreams(streamNumber);
815 m_phySta2->AssignStreams(streamNumber);
816 m_phySta3->AssignStreams(streamNumber);
817
818 auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0,
823
832
834
835 // Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
836 // Each STA should receive its PSDU.
838
839 // Since it takes m_expectedPpduDuration to transmit the PPDU,
840 // all 3 PHYs should be back to IDLE at the same time,
841 // even the PHY that has no PSDU addressed to it.
844 this,
845 m_phySta1,
846 WifiPhyState::RX);
849 this,
850 m_phySta2,
851 WifiPhyState::RX);
854 this,
855 m_phySta3,
856 WifiPhyState::CCA_BUSY);
859 this,
860 m_phySta1,
861 WifiPhyState::IDLE);
864 this,
865 m_phySta2,
866 WifiPhyState::IDLE);
869 this,
870 m_phySta3,
871 WifiPhyState::IDLE);
872
873 // One PSDU of 1000 bytes should have been successfully received by STA 1
876 this,
877 1,
878 0,
879 1000);
880 // One PSDU of 1500 bytes should have been successfully received by STA 2
883 this,
884 1,
885 0,
886 1500);
887 // No PSDU should have been received by STA 3
889
891
892 // Send MU PPDU with two PSDUs addressed to STA 1 and STA 3:
893 // STA 1 should receive its PSDU, whereas STA 2 should not receive any PSDU
894 // but should keep its PHY busy during all PPDU duration.
896
897 // Since it takes m_expectedPpduDuration to transmit the PPDU,
898 // all 3 PHYs should be back to IDLE at the same time,
899 // even the PHY that has no PSDU addressed to it.
902 this,
903 m_phySta1,
904 WifiPhyState::RX);
907 this,
908 m_phySta2,
909 WifiPhyState::CCA_BUSY);
912 this,
913 m_phySta3,
914 WifiPhyState::RX);
917 this,
918 m_phySta1,
919 WifiPhyState::IDLE);
922 this,
923 m_phySta2,
924 WifiPhyState::IDLE);
927 this,
928 m_phySta3,
929 WifiPhyState::IDLE);
930
931 // One PSDU of 1000 bytes should have been successfully received by STA 1
934 this,
935 1,
936 0,
937 1000);
938 // No PSDU should have been received by STA 2
940 // One PSDU of 1500 bytes should have been successfully received by STA 3
943 this,
944 1,
945 0,
946 1500);
947
949
950 // Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
952
953 // A strong non-wifi interference is generated on RU 1 during PSDU reception
954 BandInfo bandInfo;
955 bandInfo.fc = (m_frequency - (m_channelWidth / 4)) * 1e6;
956 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
957 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
958 Bands bands;
959 bands.push_back(bandInfo);
960
961 Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel>(bands);
962 Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue>(SpectrumInterferenceRu1);
963 double interferencePower = 0.1; // watts
964 *interferencePsdRu1 = interferencePower / ((m_channelWidth / 2) * 20e6);
965
968 this,
969 interferencePsdRu1,
970 MilliSeconds(100));
971
972 // Since it takes m_expectedPpduDuration to transmit the PPDU,
973 // both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
974 // even the PHY that has no PSDU addressed to it.
977 this,
978 m_phySta1,
979 WifiPhyState::RX);
982 this,
983 m_phySta2,
984 WifiPhyState::RX);
987 this,
988 m_phySta3,
989 WifiPhyState::CCA_BUSY);
992 this,
993 m_phySta1,
994 WifiPhyState::CCA_BUSY);
997 this,
998 m_phySta2,
999 WifiPhyState::CCA_BUSY);
1002 this,
1003 m_phySta3,
1004 WifiPhyState::CCA_BUSY);
1005
1006 // One PSDU of 1000 bytes should have been unsuccessfuly received by STA 1 (since interference
1007 // occupies RU 1)
1009 // One PSDU of 1500 bytes should have been successfully received by STA 2
1012 this,
1013 1,
1014 0,
1015 1500);
1016 // No PSDU should have been received by STA3
1018
1020
1021 // Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
1023
1024 // A strong non-wifi interference is generated on RU 2 during PSDU reception
1025 bandInfo.fc = (m_frequency + (m_channelWidth / 4)) * 1e6;
1026 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
1027 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
1028 bands.clear();
1029 bands.push_back(bandInfo);
1030
1031 Ptr<SpectrumModel> SpectrumInterferenceRu2 = Create<SpectrumModel>(bands);
1032 Ptr<SpectrumValue> interferencePsdRu2 = Create<SpectrumValue>(SpectrumInterferenceRu2);
1033 *interferencePsdRu2 = interferencePower / ((m_channelWidth / 2) * 20e6);
1034
1037 this,
1038 interferencePsdRu2,
1039 MilliSeconds(100));
1040
1041 // Since it takes m_expectedPpduDuration to transmit the PPDU,
1042 // both PHYs should be back to IDLE (or CCA_BUSY if interference on the primary 20 MHz) at the
1043 // same time, even the PHY that has no PSDU addressed to it.
1046 this,
1047 m_phySta1,
1048 WifiPhyState::RX);
1051 this,
1052 m_phySta2,
1053 WifiPhyState::RX);
1056 this,
1057 m_phySta3,
1058 WifiPhyState::CCA_BUSY);
1061 this,
1062 m_phySta1,
1063 (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
1066 this,
1067 m_phySta2,
1068 (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
1071 this,
1072 m_phySta3,
1073 (m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
1074
1075 // One PSDU of 1000 bytes should have been successfully received by STA 1
1078 this,
1079 1,
1080 0,
1081 1000);
1082 // One PSDU of 1500 bytes should have been unsuccessfuly received by STA 2 (since interference
1083 // occupies RU 2)
1085 // No PSDU should have been received by STA3
1087
1089
1090 // Send MU PPDU with two PSDUs addressed to STA 1 and STA 2:
1092
1093 // A strong non-wifi interference is generated on the full band during PSDU reception
1094 bandInfo.fc = m_frequency * 1e6;
1095 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 2) * 1e6);
1096 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 2) * 1e6);
1097 bands.clear();
1098 bands.push_back(bandInfo);
1099
1100 Ptr<SpectrumModel> SpectrumInterferenceAll = Create<SpectrumModel>(bands);
1101 Ptr<SpectrumValue> interferencePsdAll = Create<SpectrumValue>(SpectrumInterferenceAll);
1102 *interferencePsdAll = interferencePower / (m_channelWidth * 20e6);
1103
1106 this,
1107 interferencePsdAll,
1108 MilliSeconds(100));
1109
1110 // Since it takes m_expectedPpduDuration to transmit the PPDU,
1111 // both PHYs should be back to CCA_BUSY (due to the interference) at the same time,
1112 // even the PHY that has no PSDU addressed to it.
1115 this,
1116 m_phySta1,
1117 WifiPhyState::RX);
1120 this,
1121 m_phySta2,
1122 WifiPhyState::RX);
1125 this,
1126 m_phySta3,
1127 WifiPhyState::CCA_BUSY);
1130 this,
1131 m_phySta1,
1132 WifiPhyState::CCA_BUSY);
1135 this,
1136 m_phySta2,
1137 WifiPhyState::CCA_BUSY);
1140 this,
1141 m_phySta3,
1142 WifiPhyState::CCA_BUSY);
1143
1144 // One PSDU of 1000 bytes should have been unsuccessfuly received by STA 1 (since interference
1145 // occupies RU 1)
1147 // One PSDU of 1500 bytes should have been unsuccessfuly received by STA 2 (since interference
1148 // occupies RU 2)
1150 // No PSDU should have been received by STA3
1152
1154
1156}
1157
1158void
1160{
1161 m_frequency = 5180;
1162 m_channelWidth = 20;
1164 RunOne();
1165
1166 m_frequency = 5190;
1167 m_channelWidth = 40;
1169 RunOne();
1170
1171 m_frequency = 5210;
1172 m_channelWidth = 80;
1174 RunOne();
1175
1176 m_frequency = 5250;
1177 m_channelWidth = 160;
1179 RunOne();
1180
1182}
1183
1191{
1192 public:
1194
1195 private:
1196 void DoSetup() override;
1197 void DoTeardown() override;
1198 void DoRun() override;
1199
1208 RxSignalInfo rxSignalInfo,
1209 WifiTxVector txVector,
1210 const std::vector<bool> statusPerMpdu);
1211
1220 RxSignalInfo rxSignalInfo,
1221 WifiTxVector txVector,
1222 std::vector<bool> statusPerMpdu);
1223
1229
1235
1242 void CheckResultsSta1(uint32_t expectedRxSuccess,
1243 uint32_t expectedRxFailure,
1244 uint32_t expectedRxBytes);
1245
1252 void CheckResultsSta2(uint32_t expectedRxSuccess,
1253 uint32_t expectedRxFailure,
1254 uint32_t expectedRxBytes);
1255
1259 void ResetResults();
1260
1268 void SendMuPpdu(uint16_t rxStaId1,
1269 uint16_t rxStaId2,
1270 const std::vector<bool>& puncturedSubchannels);
1271
1277 void GenerateInterference(Ptr<SpectrumValue> interferencePsd, Time duration);
1278
1282 void StopInterference();
1283
1287 void RunOne();
1288
1294 void CheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
1295
1302
1309
1314
1315 uint16_t m_frequency;
1317
1320
1323};
1324
1326 : TestCase("DL-OFDMA PHY puncturing test"),
1327 m_countRxSuccessSta1(0),
1328 m_countRxSuccessSta2(0),
1329 m_countRxFailureSta1(0),
1330 m_countRxFailureSta2(0),
1331 m_countRxBytesSta1(0),
1332 m_countRxBytesSta2(0),
1333 m_frequency(5210),
1334 m_channelWidth(80),
1335 m_indexSubchannel(0),
1336 m_expectedPpduDuration20Mhz(NanoSeconds(156800)),
1337 m_expectedPpduDuration40Mhz(NanoSeconds(102400))
1338{
1339}
1340
1341void
1343{
1350}
1351
1352void
1354 uint16_t rxStaId2,
1355 const std::vector<bool>& puncturedSubchannels)
1356{
1357 NS_LOG_FUNCTION(this << rxStaId1 << rxStaId2);
1358 WifiConstPsduMap psdus;
1360 0,
1362 800,
1363 1,
1364 1,
1365 0,
1367 false,
1368 false);
1369
1370 HeRu::RuType ruType =
1371 puncturedSubchannels.empty()
1373 : (puncturedSubchannels.at(1) ? HeRu::RU_242_TONE : HeRu::RU_484_TONE);
1374 HeRu::RuSpec ru1(ruType, 1, true);
1375 txVector.SetRu(ru1, rxStaId1);
1376 txVector.SetMode(HePhy::GetHeMcs7(), rxStaId1);
1377 txVector.SetNss(1, rxStaId1);
1378
1379 ruType = puncturedSubchannels.empty()
1381 : (puncturedSubchannels.at(1) ? HeRu::RU_484_TONE : HeRu::RU_242_TONE);
1382 HeRu::RuSpec ru2(ruType,
1383 ruType == HeRu::RU_484_TONE ? 2 : (puncturedSubchannels.at(3) ? 3 : 4),
1384 true);
1385 txVector.SetRu(ru2, rxStaId2);
1386 txVector.SetMode(HePhy::GetHeMcs9(), rxStaId2);
1387 txVector.SetNss(1, rxStaId2);
1388
1389 std::vector<uint8_t> ruAlloc;
1390 if (puncturedSubchannels.empty())
1391 {
1392 std::fill_n(std::back_inserter(ruAlloc), 4, 200);
1393 }
1394 else
1395 {
1396 ruAlloc.push_back(puncturedSubchannels.at(1) ? 192 : 200);
1397 ruAlloc.push_back(puncturedSubchannels.at(1) ? 113 : 200);
1398 ruAlloc.push_back(puncturedSubchannels.at(2) ? 113
1399 : (puncturedSubchannels.at(3) ? 192 : 200));
1400 ruAlloc.push_back(puncturedSubchannels.at(2) ? 192
1401 : (puncturedSubchannels.at(3) ? 113 : 200));
1402 }
1403
1404 txVector.SetRuAllocation(ruAlloc, 0);
1405 txVector.SetSigBMode(VhtPhy::GetVhtMcs5());
1406
1407 Ptr<Packet> pkt1 = Create<Packet>(1000);
1408 WifiMacHeader hdr1;
1410 hdr1.SetQosTid(0);
1411 hdr1.SetAddr1(Mac48Address("00:00:00:00:00:01"));
1412 hdr1.SetSequenceNumber(1);
1413 Ptr<WifiPsdu> psdu1 = Create<WifiPsdu>(pkt1, hdr1);
1414 psdus.insert(std::make_pair(rxStaId1, psdu1));
1415
1416 Ptr<Packet> pkt2 = Create<Packet>(1500);
1417 WifiMacHeader hdr2;
1419 hdr2.SetQosTid(0);
1420 hdr2.SetAddr1(Mac48Address("00:00:00:00:00:02"));
1421 hdr2.SetSequenceNumber(2);
1422 Ptr<WifiPsdu> psdu2 = Create<WifiPsdu>(pkt2, hdr2);
1423 psdus.insert(std::make_pair(rxStaId2, psdu2));
1424
1425 if (!puncturedSubchannels.empty())
1426 {
1427 txVector.SetInactiveSubchannels(puncturedSubchannels);
1428 }
1429
1430 m_phyAp->Send(psdus, txVector);
1431}
1432
1433void
1435{
1436 NS_LOG_FUNCTION(this << duration);
1438 m_phyInterferer->SetPeriod(duration);
1441}
1442
1443void
1445{
1446 NS_LOG_FUNCTION(this);
1448}
1449
1450void
1452 RxSignalInfo rxSignalInfo,
1453 WifiTxVector txVector,
1454 std::vector<bool> /*statusPerMpdu*/)
1455{
1456 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
1458 m_countRxBytesSta1 += (psdu->GetSize() - 30);
1459}
1460
1461void
1463 RxSignalInfo rxSignalInfo,
1464 WifiTxVector txVector,
1465 std::vector<bool> /*statusPerMpdu*/)
1466{
1467 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
1469 m_countRxBytesSta2 += (psdu->GetSize() - 30);
1470}
1471
1472void
1474{
1475 NS_LOG_FUNCTION(this << *psdu);
1477}
1478
1479void
1481{
1482 NS_LOG_FUNCTION(this << *psdu);
1484}
1485
1486void
1488 uint32_t expectedRxFailure,
1489 uint32_t expectedRxBytes)
1490{
1492 expectedRxSuccess,
1493 "The number of successfully received packets by STA 1 is not correct!");
1495 expectedRxFailure,
1496 "The number of unsuccessfuly received packets by STA 1 is not correct!");
1498 expectedRxBytes,
1499 "The number of bytes received by STA 1 is not correct!");
1500}
1501
1502void
1504 uint32_t expectedRxFailure,
1505 uint32_t expectedRxBytes)
1506{
1508 expectedRxSuccess,
1509 "The number of successfully received packets by STA 2 is not correct!");
1511 expectedRxFailure,
1512 "The number of unsuccessfuly received packets by STA 2 is not correct!");
1514 expectedRxBytes,
1515 "The number of bytes received by STA 2 is not correct!");
1516}
1517
1518void
1520{
1521 // This is needed to make sure PHY state will be checked as the last event if a state change
1522 // occurred at the exact same time as the check
1524}
1525
1526void
1528{
1529 WifiPhyState currentState;
1530 PointerValue ptr;
1531 phy->GetAttribute("State", ptr);
1532 Ptr<WifiPhyStateHelper> state = DynamicCast<WifiPhyStateHelper>(ptr.Get<WifiPhyStateHelper>());
1533 currentState = state->GetState();
1534 NS_LOG_FUNCTION(this << currentState);
1535 NS_TEST_ASSERT_MSG_EQ(currentState,
1536 expectedState,
1537 "PHY State " << currentState << " does not match expected state "
1538 << expectedState << " at " << Simulator::Now());
1539}
1540
1541void
1543{
1544 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
1545 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
1546 lossModel->SetFrequency(m_frequency * 1e6);
1547 spectrumChannel->AddPropagationLossModel(lossModel);
1549 CreateObject<ConstantSpeedPropagationDelayModel>();
1550 spectrumChannel->SetPropagationDelayModel(delayModel);
1551
1552 Ptr<Node> apNode = CreateObject<Node>();
1553 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice>();
1554 m_phyAp = CreateObject<SpectrumWifiPhy>();
1555 Ptr<InterferenceHelper> apInterferenceHelper = CreateObject<InterferenceHelper>();
1556 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
1557 Ptr<ErrorRateModel> apErrorModel = CreateObject<NistErrorRateModel>();
1558 m_phyAp->SetErrorRateModel(apErrorModel);
1559 m_phyAp->SetDevice(apDev);
1560 m_phyAp->AddChannel(spectrumChannel);
1562 Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel>();
1563 m_phyAp->SetMobility(apMobility);
1564 apDev->SetPhy(m_phyAp);
1565 apNode->AggregateObject(apMobility);
1566 apNode->AddDevice(apDev);
1567
1568 Ptr<Node> sta1Node = CreateObject<Node>();
1569 Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice>();
1570 m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy>(1);
1571 Ptr<InterferenceHelper> sta1InterferenceHelper = CreateObject<InterferenceHelper>();
1572 m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
1573 Ptr<ErrorRateModel> sta1ErrorModel = CreateObject<NistErrorRateModel>();
1574 m_phySta1->SetErrorRateModel(sta1ErrorModel);
1575 m_phySta1->SetDevice(sta1Dev);
1576 m_phySta1->AddChannel(spectrumChannel);
1581 Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel>();
1582 m_phySta1->SetMobility(sta1Mobility);
1583 sta1Dev->SetPhy(m_phySta1);
1584 sta1Node->AggregateObject(sta1Mobility);
1585 sta1Node->AddDevice(sta1Dev);
1586
1587 Ptr<Node> sta2Node = CreateObject<Node>();
1588 Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice>();
1589 m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy>(2);
1590 Ptr<InterferenceHelper> sta2InterferenceHelper = CreateObject<InterferenceHelper>();
1591 m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
1592 Ptr<ErrorRateModel> sta2ErrorModel = CreateObject<NistErrorRateModel>();
1593 m_phySta2->SetErrorRateModel(sta2ErrorModel);
1594 m_phySta2->SetDevice(sta2Dev);
1595 m_phySta2->AddChannel(spectrumChannel);
1600 Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel>();
1601 m_phySta2->SetMobility(sta2Mobility);
1602 sta2Dev->SetPhy(m_phySta2);
1603 sta2Node->AggregateObject(sta2Mobility);
1604 sta2Node->AddDevice(sta2Dev);
1605
1606 Ptr<Node> interfererNode = CreateObject<Node>();
1607 Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice>();
1608 m_phyInterferer = CreateObject<WaveformGenerator>();
1609 m_phyInterferer->SetDevice(interfererDev);
1610 m_phyInterferer->SetChannel(spectrumChannel);
1612 interfererNode->AddDevice(interfererDev);
1613}
1614
1615void
1617{
1618 m_phyAp->Dispose();
1619 m_phyAp = nullptr;
1620 m_phySta1->Dispose();
1621 m_phySta1 = nullptr;
1622 m_phySta2->Dispose();
1623 m_phySta2 = nullptr;
1625 m_phyInterferer = nullptr;
1626}
1627
1628void
1630{
1633 int64_t streamNumber = 0;
1634 m_phyAp->AssignStreams(streamNumber);
1635 m_phySta1->AssignStreams(streamNumber);
1636 m_phySta2->AssignStreams(streamNumber);
1637
1638 auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0,
1643
1650
1651 // A strong non-wifi interference is generated on selected 20 MHz subchannel for the whole
1652 // duration of the test run
1653 BandInfo bandInfo;
1654 bandInfo.fc = (m_frequency - (m_channelWidth / 2) + 10 + (m_indexSubchannel * 20)) * 1e6;
1655 // Occupy half of the RU to make sure we do not have some power allocated to the subcarriers on
1656 // the border of another RU
1657 bandInfo.fl = bandInfo.fc - (5 * 1e6);
1658 bandInfo.fh = bandInfo.fc + (5 * 1e6);
1659 Bands bands;
1660 bands.push_back(bandInfo);
1661
1662 Ptr<SpectrumModel> spectrumInterference = Create<SpectrumModel>(bands);
1663 Ptr<SpectrumValue> interferencePsd = Create<SpectrumValue>(spectrumInterference);
1664 double interferencePower = 0.1; // watts
1665 *interferencePsd = interferencePower / 10e6;
1666
1669 this,
1670 interferencePsd,
1671 Seconds(3));
1672
1673 //---------------------------------------------------------------------------
1674 // Send MU PPDU with two PSDUs addressed to STA 1 and STA 2 without preamble puncturing:
1677 this,
1678 1,
1679 2,
1680 std::vector<bool>{});
1681
1682 // Since it takes m_expectedPpduDuration to transmit the PPDU,
1683 // both PHYs should be back to IDLE at the same time.
1686 this,
1687 m_phySta1,
1688 WifiPhyState::RX);
1691 this,
1692 m_phySta2,
1693 WifiPhyState::RX);
1696 this,
1697 m_phySta1,
1698 WifiPhyState::IDLE);
1701 this,
1702 m_phySta2,
1703 WifiPhyState::IDLE);
1704
1705 if (m_indexSubchannel < 2) // interference in RU 1
1706 {
1707 // One PSDU of 1000 bytes should have been unsuccessfuly received by STA 1
1710 this,
1711 0,
1712 1,
1713 0);
1714 // One PSDU of 1500 bytes should have been successfully received by STA 2
1717 this,
1718 1,
1719 0,
1720 1500);
1721 }
1722 else // interference in RU 2
1723 {
1724 // One PSDU of 1000 bytes should have been successfully received by STA 1
1727 this,
1728 1,
1729 0,
1730 1000);
1731 // One PSDU of 1500 bytes should have been unsuccessfuly received by STA 2
1734 this,
1735 0,
1736 1,
1737 0);
1738 }
1739
1741
1742 //---------------------------------------------------------------------------
1743 // Send MU PPDU with two PSDUs addressed to STA 1 and STA 2 with preamble puncturing:
1744 // the punctured 20 MHz subchannel is the one that has interference
1745 std::vector<bool> puncturedSubchannels;
1746 for (std::size_t i = 0; i < (m_channelWidth / 20); ++i)
1747 {
1748 if (i == m_indexSubchannel)
1749 {
1750 puncturedSubchannels.push_back(true);
1751 }
1752 else
1753 {
1754 puncturedSubchannels.push_back(false);
1755 }
1756 }
1759 this,
1760 1,
1761 2,
1762 puncturedSubchannels);
1763
1764 // Since it takes m_expectedPpduDuration to transmit the PPDU,
1765 // both PHYs should be back to IDLE at the same time.
1768 this,
1769 m_phySta1,
1770 WifiPhyState::RX);
1773 this,
1774 m_phySta2,
1775 WifiPhyState::RX);
1778 this,
1779 m_phySta1,
1780 WifiPhyState::IDLE);
1783 this,
1784 m_phySta2,
1785 WifiPhyState::IDLE);
1786
1787 // One PSDU of 1000 bytes should have been successfully received by STA 1
1790 this,
1791 1,
1792 0,
1793 1000);
1794 // One PSDU of 1500 bytes should have been successfully received by STA 2
1797 this,
1798 1,
1799 0,
1800 1500);
1801
1803
1805}
1806
1807void
1809{
1810 // test all 20 MHz subchannels in the 80 MHz operation channel except the primary one which
1811 // cannot be punctured
1812 for (auto index : {1, 2, 3})
1813 {
1814 m_indexSubchannel = index;
1815 RunOne();
1816 }
1818}
1819
1827{
1828 public:
1830 ~TestUlOfdmaPpduUid() override;
1831
1832 private:
1833 void DoSetup() override;
1834 void DoTeardown() override;
1835 void DoRun() override;
1836
1841 void TxPpduAp(uint64_t uid);
1846 void TxPpduSta1(uint64_t uid);
1851 void TxPpduSta2(uint64_t uid);
1855 void ResetPpduUid();
1856
1860 void SendMuPpdu();
1864 void SendTbPpdu();
1869 void SendSuPpdu(uint16_t txStaId);
1870
1876 void CheckUid(uint16_t staId, uint64_t expectedUid);
1877
1881
1882 uint64_t m_ppduUidAp;
1883 uint64_t m_ppduUidSta1;
1884 uint64_t m_ppduUidSta2;
1885};
1886
1888 : TestCase("UL-OFDMA PPDU UID attribution test"),
1889 m_ppduUidAp(UINT64_MAX),
1890 m_ppduUidSta1(UINT64_MAX),
1891 m_ppduUidSta2(UINT64_MAX)
1892{
1893}
1894
1896{
1897}
1898
1899void
1901{
1902 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
1903 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
1904 lossModel->SetFrequency(DEFAULT_FREQUENCY);
1905 spectrumChannel->AddPropagationLossModel(lossModel);
1907 CreateObject<ConstantSpeedPropagationDelayModel>();
1908 spectrumChannel->SetPropagationDelayModel(delayModel);
1909
1910 Ptr<Node> apNode = CreateObject<Node>();
1911 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice>();
1912 m_phyAp = CreateObject<OfdmaSpectrumWifiPhy>(0);
1913 Ptr<InterferenceHelper> apInterferenceHelper = CreateObject<InterferenceHelper>();
1914 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
1915 Ptr<ErrorRateModel> apErrorModel = CreateObject<NistErrorRateModel>();
1916 m_phyAp->SetErrorRateModel(apErrorModel);
1917 m_phyAp->AddChannel(spectrumChannel);
1919 auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0,
1926 m_phyAp->SetDevice(apDev);
1929 Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel>();
1930 m_phyAp->SetMobility(apMobility);
1931 apDev->SetPhy(m_phyAp);
1932 apNode->AggregateObject(apMobility);
1933 apNode->AddDevice(apDev);
1934 apDev->SetStandard(WIFI_STANDARD_80211ax);
1935 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
1936
1937 Ptr<Node> sta1Node = CreateObject<Node>();
1938 Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice>();
1939 m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy>(1);
1940 Ptr<InterferenceHelper> sta1InterferenceHelper = CreateObject<InterferenceHelper>();
1941 m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
1942 Ptr<ErrorRateModel> sta1ErrorModel = CreateObject<NistErrorRateModel>();
1943 m_phySta1->SetErrorRateModel(sta1ErrorModel);
1944 m_phySta1->AddChannel(spectrumChannel);
1948 m_phySta1->SetDevice(sta1Dev);
1951 Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel>();
1952 m_phySta1->SetMobility(sta1Mobility);
1953 sta1Dev->SetPhy(m_phySta1);
1954 sta1Node->AggregateObject(sta1Mobility);
1955 sta1Node->AddDevice(sta1Dev);
1956
1957 Ptr<Node> sta2Node = CreateObject<Node>();
1958 Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice>();
1959 m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy>(2);
1960 Ptr<InterferenceHelper> sta2InterferenceHelper = CreateObject<InterferenceHelper>();
1961 m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
1962 Ptr<ErrorRateModel> sta2ErrorModel = CreateObject<NistErrorRateModel>();
1963 m_phySta2->SetErrorRateModel(sta2ErrorModel);
1964 m_phySta2->AddChannel(spectrumChannel);
1968 m_phySta2->SetDevice(sta2Dev);
1971 Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel>();
1972 m_phySta2->SetMobility(sta2Mobility);
1973 sta2Dev->SetPhy(m_phySta2);
1974 sta2Node->AggregateObject(sta2Mobility);
1975 sta2Node->AddDevice(sta2Dev);
1976}
1977
1978void
1980{
1981 m_phyAp->Dispose();
1982 m_phyAp = nullptr;
1983 m_phySta1->Dispose();
1984 m_phySta1 = nullptr;
1985 m_phySta2->Dispose();
1986 m_phySta2 = nullptr;
1987}
1988
1989void
1990TestUlOfdmaPpduUid::CheckUid(uint16_t staId, uint64_t expectedUid)
1991{
1992 uint64_t uid;
1993 std::string device;
1994 switch (staId)
1995 {
1996 case 0:
1997 uid = m_ppduUidAp;
1998 device = "AP";
1999 break;
2000 case 1:
2001 uid = m_ppduUidSta1;
2002 device = "STA1";
2003 break;
2004 case 2:
2005 uid = m_ppduUidSta2;
2006 device = "STA2";
2007 break;
2008 default:
2009 NS_ABORT_MSG("Unexpected STA-ID");
2010 }
2012 expectedUid,
2013 "UID " << uid << " does not match expected one " << expectedUid << " for "
2014 << device << " at " << Simulator::Now());
2015}
2016
2017void
2019{
2020 NS_LOG_FUNCTION(this << uid);
2021 m_ppduUidAp = uid;
2022}
2023
2024void
2026{
2027 NS_LOG_FUNCTION(this << uid);
2028 m_ppduUidSta1 = uid;
2029}
2030
2031void
2033{
2034 NS_LOG_FUNCTION(this << uid);
2035 m_ppduUidSta2 = uid;
2036}
2037
2038void
2040{
2041 NS_LOG_FUNCTION(this);
2042 m_phyAp->SetPpduUid(0); // one is enough since it's a global attribute
2043}
2044
2045void
2047{
2048 WifiConstPsduMap psdus;
2050 0,
2052 800,
2053 1,
2054 1,
2055 0,
2057 false,
2058 false);
2059
2060 uint16_t rxStaId1 = 1;
2061 HeRu::RuSpec ru1(HeRu::RU_106_TONE, 1, true);
2062 txVector.SetRu(ru1, rxStaId1);
2063 txVector.SetMode(HePhy::GetHeMcs7(), rxStaId1);
2064 txVector.SetNss(1, rxStaId1);
2065
2066 uint16_t rxStaId2 = 2;
2067 HeRu::RuSpec ru2(HeRu::RU_106_TONE, 2, true);
2068 txVector.SetRu(ru2, rxStaId2);
2069 txVector.SetMode(HePhy::GetHeMcs9(), rxStaId2);
2070 txVector.SetNss(1, rxStaId2);
2071 txVector.SetSigBMode(VhtPhy::GetVhtMcs5());
2072 txVector.SetRuAllocation({96}, 0);
2073
2074 Ptr<Packet> pkt1 = Create<Packet>(1000);
2075 WifiMacHeader hdr1;
2077 hdr1.SetQosTid(0);
2078 hdr1.SetAddr1(Mac48Address("00:00:00:00:00:01"));
2079 hdr1.SetSequenceNumber(1);
2080 Ptr<WifiPsdu> psdu1 = Create<WifiPsdu>(pkt1, hdr1);
2081 psdus.insert(std::make_pair(rxStaId1, psdu1));
2082
2083 Ptr<Packet> pkt2 = Create<Packet>(1500);
2084 WifiMacHeader hdr2;
2086 hdr2.SetQosTid(0);
2087 hdr2.SetAddr1(Mac48Address("00:00:00:00:00:02"));
2088 hdr2.SetSequenceNumber(2);
2089 Ptr<WifiPsdu> psdu2 = Create<WifiPsdu>(pkt2, hdr2);
2090 psdus.insert(std::make_pair(rxStaId2, psdu2));
2091
2092 m_phyAp->Send(psdus, txVector);
2093}
2094
2095void
2097{
2098 WifiConstPsduMap psdus1;
2099 WifiConstPsduMap psdus2;
2100
2102 0,
2104 1600,
2105 1,
2106 1,
2107 0,
2109 false,
2110 false);
2111 WifiTxVector txVector2 = txVector1;
2112 WifiTxVector trigVector = txVector2;
2113
2114 uint16_t rxStaId1 = 1;
2115 HeRu::RuSpec ru1(HeRu::RU_106_TONE, 1, false);
2116 txVector1.SetRu(ru1, rxStaId1);
2117 txVector1.SetMode(HePhy::GetHeMcs7(), rxStaId1);
2118 txVector1.SetNss(1, rxStaId1);
2119 trigVector.SetRu(ru1, rxStaId1);
2120 trigVector.SetMode(HePhy::GetHeMcs7(), rxStaId1);
2121 trigVector.SetNss(1, rxStaId1);
2122
2123 Ptr<Packet> pkt1 = Create<Packet>(1000);
2124 WifiMacHeader hdr1;
2126 hdr1.SetQosTid(0);
2127 hdr1.SetAddr1(Mac48Address("00:00:00:00:00:00"));
2128 hdr1.SetSequenceNumber(1);
2129 Ptr<WifiPsdu> psdu1 = Create<WifiPsdu>(pkt1, hdr1);
2130 psdus1.insert(std::make_pair(rxStaId1, psdu1));
2131
2132 uint16_t rxStaId2 = 2;
2133 HeRu::RuSpec ru2(HeRu::RU_106_TONE, 2, false);
2134 txVector2.SetRu(ru2, rxStaId2);
2135 txVector2.SetMode(HePhy::GetHeMcs9(), rxStaId2);
2136 txVector2.SetNss(1, rxStaId2);
2137 trigVector.SetRu(ru2, rxStaId2);
2138 trigVector.SetMode(HePhy::GetHeMcs9(), rxStaId2);
2139 trigVector.SetNss(1, rxStaId2);
2140
2141 Ptr<Packet> pkt2 = Create<Packet>(1500);
2142 WifiMacHeader hdr2;
2144 hdr2.SetQosTid(0);
2145 hdr2.SetAddr1(Mac48Address("00:00:00:00:00:00"));
2146 hdr2.SetSequenceNumber(2);
2147 Ptr<WifiPsdu> psdu2 = Create<WifiPsdu>(pkt2, hdr2);
2148 psdus2.insert(std::make_pair(rxStaId2, psdu2));
2149
2150 Time txDuration1 = m_phySta1->CalculateTxDuration(psdu1->GetSize(),
2151 txVector1,
2153 rxStaId1);
2154 Time txDuration2 = m_phySta2->CalculateTxDuration(psdu2->GetSize(),
2155 txVector2,
2157 rxStaId2);
2158 Time txDuration = std::max(txDuration1, txDuration2);
2159
2160 txVector1.SetLength(
2162 .first);
2163 txVector2.SetLength(
2165 .first);
2166
2167 auto hePhyAp = DynamicCast<HePhy>(m_phyAp->GetPhyEntity(WIFI_MOD_CLASS_HE));
2168 hePhyAp->SetTrigVector(trigVector, txDuration);
2169
2170 m_phySta1->Send(psdus1, txVector1);
2171 m_phySta2->Send(psdus2, txVector2);
2172}
2173
2174void
2176{
2177 WifiConstPsduMap psdus;
2179 0,
2181 800,
2182 1,
2183 1,
2184 0,
2186 false,
2187 false);
2188
2189 Ptr<Packet> pkt = Create<Packet>(1000);
2190 WifiMacHeader hdr;
2192 hdr.SetQosTid(0);
2194 hdr.SetSequenceNumber(1);
2195 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
2196 psdus.insert(std::make_pair(SU_STA_ID, psdu));
2197
2198 switch (txStaId)
2199 {
2200 case 0:
2201 m_phyAp->Send(psdus, txVector);
2202 break;
2203 case 1:
2204 m_phySta1->Send(psdus, txVector);
2205 break;
2206 case 2:
2207 m_phySta2->Send(psdus, txVector);
2208 break;
2209 default:
2210 NS_ABORT_MSG("Unexpected STA-ID");
2211 }
2212}
2213
2214void
2216{
2219 int64_t streamNumber = 0;
2220 m_phyAp->AssignStreams(streamNumber);
2221 m_phySta1->AssignStreams(streamNumber);
2222 m_phySta2->AssignStreams(streamNumber);
2223
2224 // Reset PPDU UID so as not to be dependent on previously executed test cases,
2225 // since global attribute will be changed).
2226 ResetPpduUid();
2227
2228 // Send HE MU PPDU with two PSDUs addressed to STA 1 and STA 2.
2229 // PPDU UID should be equal to 0 (the first counter value).
2232
2233 // Send HE SU PPDU from AP.
2234 // PPDU UID should be incremented since this is a new PPDU.
2237
2238 // Send HE TB PPDU from STAs to AP.
2239 // PPDU UID should NOT be incremented since HE TB PPDUs reuse the UID of the immediately
2240 // preceding correctly received PPDU (which normally contains the trigger frame).
2244
2245 // Send HE SU PPDU from STA1.
2246 // PPDU UID should be incremented since this is a new PPDU.
2249
2252}
2253
2261{
2262 public:
2264 ~TestMultipleHeTbPreambles() override;
2265
2266 private:
2267 void DoSetup() override;
2268 void DoTeardown() override;
2269 void DoRun() override;
2270
2280 void RxHeTbPpdu(uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize);
2281
2296
2303
2307 void Reset();
2308
2314 void CheckHeTbPreambles(size_t nEvents, std::vector<uint64_t> uids);
2315
2320 void CheckBytesDropped(size_t expectedBytesDropped);
2321
2323
2326};
2327
2329 : TestCase("UL-OFDMA multiple RX events test"),
2330 m_totalBytesDropped(0),
2331 m_trigVector(HePhy::GetHeMcs7(),
2332 0,
2334 1600,
2335 1,
2336 1,
2337 0,
2339 false,
2340 false)
2341{
2342}
2343
2345{
2346}
2347
2348void
2350{
2351 NS_LOG_FUNCTION(this);
2353 // We have to reset PHY here since we do not trigger OFDMA payload RX event in this test
2354 m_phy->Reset();
2356}
2357
2358void
2360{
2361 NS_LOG_FUNCTION(this << p << reason);
2362 m_totalBytesDropped += (p->GetSize() - 30);
2363}
2364
2365void
2366TestMultipleHeTbPreambles::CheckHeTbPreambles(size_t nEvents, std::vector<uint64_t> uids)
2367{
2368 auto events = m_phy->GetCurrentPreambleEvents();
2369 NS_TEST_ASSERT_MSG_EQ(events.size(), nEvents, "The number of UL MU events is not correct!");
2370 for (const auto& uid : uids)
2371 {
2372 auto pair = std::make_pair(uid, WIFI_PREAMBLE_HE_TB);
2373 auto it = events.find(pair);
2374 bool found = (it != events.end());
2376 true,
2377 "HE TB PPDU with UID " << uid << " has not been received!");
2378 }
2379}
2380
2381void
2383{
2385 expectedBytesDropped,
2386 "The number of dropped bytes is not correct!");
2387}
2388
2389void
2391 uint16_t staId,
2392 double txPowerWatts,
2393 size_t payloadSize)
2394{
2395 WifiConstPsduMap psdus;
2397 0,
2399 1600,
2400 1,
2401 1,
2402 0,
2404 false,
2405 false);
2406
2407 HeRu::RuSpec ru(HeRu::RU_106_TONE, staId, false);
2408 txVector.SetRu(ru, staId);
2409 txVector.SetMode(HePhy::GetHeMcs7(), staId);
2410 txVector.SetNss(1, staId);
2411
2412 m_trigVector.SetHeMuUserInfo(staId, {ru, 7, 1});
2413
2414 Ptr<Packet> pkt = Create<Packet>(payloadSize);
2415 WifiMacHeader hdr;
2417 hdr.SetQosTid(0);
2418 hdr.SetAddr1(Mac48Address("00:00:00:00:00:00"));
2419 hdr.SetSequenceNumber(1);
2420 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
2421 psdus.insert(std::make_pair(staId, psdu));
2422
2423 Time ppduDuration =
2424 m_phy->CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand(), staId);
2425 Ptr<HePpdu> ppdu = Create<HePpdu>(psdus,
2426 txVector,
2428 ppduDuration,
2429 uid,
2431
2432 // Send non-OFDMA part
2433 Time nonOfdmaDuration = m_phy->GetHePhy()->CalculateNonOfdmaDurationForHeTb(txVector);
2434 uint32_t centerFrequency =
2435 m_phy->GetHePhy()->GetCenterFrequencyForNonOfdmaPart(txVector, staId);
2436 uint16_t ruWidth = HeRu::GetBandwidth(txVector.GetRu(staId).GetRuType());
2437 uint16_t channelWidth = ruWidth < 20 ? 20 : ruWidth;
2439 centerFrequency,
2440 channelWidth,
2441 txPowerWatts,
2442 m_phy->GetGuardBandwidth(channelWidth));
2443 Ptr<WifiSpectrumSignalParameters> rxParams = Create<WifiSpectrumSignalParameters>();
2444 rxParams->psd = rxPsd;
2445 rxParams->txPhy = nullptr;
2446 rxParams->duration = nonOfdmaDuration;
2447 rxParams->ppdu = ppdu;
2448 rxParams->txWidth = channelWidth;
2449
2450 uint16_t length;
2451 std::tie(length, ppduDuration) =
2453 txVector.SetLength(length);
2454 m_trigVector.SetLength(length);
2455 auto hePhy = DynamicCast<HePhy>(m_phy->GetLatestPhyEntity());
2456 hePhy->SetTrigVector(m_trigVector, ppduDuration);
2457 ppdu->ResetTxVector();
2458 m_phy->StartRx(rxParams, nullptr);
2459
2460 // Schedule OFDMA part
2461 Ptr<HePpdu> ppduOfdma = DynamicCast<HePpdu>(ppdu->Copy()); // since flag will be modified
2462 ppduOfdma->SetTxPsdFlag(HePpdu::PSD_HE_PORTION);
2463 const auto band = m_phy->GetHePhy()->GetRuBandForRx(txVector, staId);
2464 Ptr<SpectrumValue> rxPsdOfdma =
2467 txPowerWatts,
2469 band.indices);
2470 Ptr<WifiSpectrumSignalParameters> rxParamsOfdma = Create<WifiSpectrumSignalParameters>();
2471 rxParamsOfdma->psd = rxPsd;
2472 rxParamsOfdma->txPhy = nullptr;
2473 rxParamsOfdma->duration = ppduDuration - nonOfdmaDuration;
2474 rxParamsOfdma->ppdu = ppduOfdma;
2475 rxParamsOfdma->txWidth = DEFAULT_CHANNEL_WIDTH;
2476 Simulator::Schedule(nonOfdmaDuration,
2478 this,
2479 rxParamsOfdma);
2480}
2481
2482void
2484{
2486}
2487
2488void
2490{
2491 // This is needed to make sure the OFDMA part is started as the last event since HE-SIG-A should
2492 // end at the exact same time as the start For normal WifiNetDevices, this the reception of the
2493 // OFDMA part is scheduled after end of HE-SIG-A decoding.
2494 m_phy->StartRx(rxParamsOfdma, nullptr);
2495}
2496
2497void
2499{
2500 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
2501 Ptr<Node> node = CreateObject<Node>();
2502 Ptr<WifiNetDevice> dev = CreateObject<WifiNetDevice>();
2503 dev->SetStandard(WIFI_STANDARD_80211ax);
2504 m_phy = CreateObject<OfdmaSpectrumWifiPhy>(0);
2505 Ptr<InterferenceHelper> interferenceHelper = CreateObject<InterferenceHelper>();
2506 Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel>();
2507 Ptr<ApWifiMac> mac = CreateObject<ApWifiMac>();
2508 mac->SetAttribute("BeaconGeneration", BooleanValue(false));
2509 dev->SetMac(mac);
2510 m_phy->SetInterferenceHelper(interferenceHelper);
2511 m_phy->SetErrorRateModel(error);
2512 m_phy->AddChannel(spectrumChannel);
2517 0});
2518 m_phy->TraceConnectWithoutContext("PhyRxDrop",
2520 m_phy->SetDevice(dev);
2521 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
2522 CreateObject<ThresholdPreambleDetectionModel>();
2523 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(4));
2524 preambleDetectionModel->SetAttribute("MinimumRssi", DoubleValue(-82));
2525 m_phy->SetPreambleDetectionModel(preambleDetectionModel);
2526 Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration>();
2527 heConfiguration->SetMaxTbPpduDelay(NanoSeconds(400));
2528 dev->SetHeConfiguration(heConfiguration);
2529 dev->SetPhy(m_phy);
2530 node->AddDevice(dev);
2531}
2532
2533void
2535{
2536 m_phy->Dispose();
2537 m_phy = nullptr;
2538}
2539
2540void
2542{
2545 int64_t streamNumber = 0;
2546 m_phy->AssignStreams(streamNumber);
2547
2548 double txPowerWatts = 0.01;
2549
2550 {
2551 // Verify a single UL MU transmission with two stations belonging to the same BSS
2552 std::vector<uint64_t> uids{0};
2555 this,
2556 uids[0],
2557 1,
2558 txPowerWatts,
2559 1001);
2562 this,
2563 uids[0],
2564 2,
2565 txPowerWatts,
2566 1002);
2567 // Check that we received a single UL MU transmission with the corresponding UID
2570 this,
2571 1,
2572 uids);
2574 }
2575
2576 {
2577 // Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where
2578 // the second transmission arrives during the preamble detection window and with half the
2579 // power of the first transmission.
2580 std::vector<uint64_t> uids{1, 2};
2583 this,
2584 uids[0],
2585 1,
2586 txPowerWatts,
2587 1001);
2590 this,
2591 uids[0],
2592 2,
2593 txPowerWatts,
2594 1002);
2597 this,
2598 uids[1],
2599 1,
2600 txPowerWatts / 2,
2601 1003);
2604 this,
2605 uids[1],
2606 2,
2607 txPowerWatts / 2,
2608 1004);
2609 // Check that we received the correct reception of 2 UL MU transmissions with the
2610 // corresponding UIDs
2613 this,
2614 2,
2615 uids);
2617 // TODO: verify PPDUs from second UL MU transmission are dropped
2618 }
2619
2620 {
2621 // Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where
2622 // the second transmission arrives during the preamble detection window and with twice the
2623 // power of the first transmission.
2624 std::vector<uint64_t> uids{3, 4};
2627 this,
2628 uids[0],
2629 1,
2630 txPowerWatts / 2,
2631 1001);
2634 this,
2635 uids[0],
2636 2,
2637 txPowerWatts / 2,
2638 1002);
2641 this,
2642 uids[1],
2643 1,
2644 txPowerWatts,
2645 1003);
2648 this,
2649 uids[1],
2650 2,
2651 txPowerWatts,
2652 1004);
2653 // Check that we received the correct reception of 2 UL MU transmissions with the
2654 // corresponding UIDs
2657 this,
2658 2,
2659 uids);
2661 // TODO: verify PPDUs from first UL MU transmission are dropped
2662 }
2663
2664 {
2665 // Verify the correct reception of 2 UL MU transmissions with two stations per BSS, where
2666 // the second transmission arrives during PHY header reception and with the same power as
2667 // the first transmission.
2668 std::vector<uint64_t> uids{5, 6};
2671 this,
2672 uids[0],
2673 1,
2674 txPowerWatts,
2675 1001);
2678 this,
2679 uids[0],
2680 2,
2681 txPowerWatts,
2682 1002);
2685 this,
2686 uids[1],
2687 1,
2688 txPowerWatts,
2689 1003);
2692 this,
2693 uids[1],
2694 2,
2695 txPowerWatts,
2696 1004);
2697 // Check that we received the correct reception of the first UL MU transmission with the
2698 // corresponding UID (second one dropped)
2701 this,
2702 1,
2703 std::vector<uint64_t>{uids[0]});
2704 // The packets of the second UL MU transmission should have been dropped
2707 this,
2708 1003 + 1004);
2710 }
2711
2712 {
2713 // Verify the correct reception of one UL MU transmission out of 2 with two stations per
2714 // BSS, where the second transmission arrives during payload reception and with the same
2715 // power as the first transmission.
2716 std::vector<uint64_t> uids{7, 8};
2719 this,
2720 uids[0],
2721 1,
2722 txPowerWatts,
2723 1001);
2726 this,
2727 uids[0],
2728 2,
2729 txPowerWatts,
2730 1002);
2733 this,
2734 uids[1],
2735 1,
2736 txPowerWatts,
2737 1003);
2740 this,
2741 uids[1],
2742 2,
2743 txPowerWatts,
2744 1004);
2745 // Check that we received the correct reception of the first UL MU transmission with the
2746 // corresponding UID (second one dropped)
2749 this,
2750 1,
2751 std::vector<uint64_t>{uids[0]});
2752 // The packets of the second UL MU transmission should have been dropped
2755 this,
2756 1003 + 1004);
2758 }
2759
2760 {
2761 // Verify the correct reception of a single UL MU transmission with two stations belonging
2762 // to the same BSS, and the second PPDU arrives 500ns after the first PPDU, i.e. it exceeds
2763 // the configured delay spread of 400ns
2764 std::vector<uint64_t> uids{9};
2767 this,
2768 uids[0],
2769 1,
2770 txPowerWatts,
2771 1001);
2774 this,
2775 uids[0],
2776 2,
2777 txPowerWatts,
2778 1002);
2779 // Check that we received a single UL MU transmission with the corresponding UID
2782 this,
2783 1,
2784 uids);
2785 // The first packet of 1001 bytes should be dropped because preamble is not detected after
2786 // 4us (because the PPDU that arrived at 500ns is interfering): the second HE TB PPDU is
2787 // acting as interference since it arrived after the maximum allowed 400ns. Obviously, that
2788 // second packet of 1002 bytes is dropped as well.
2791 this,
2792 1001 + 1002);
2794 }
2795
2798}
2799
2807{
2808 public:
2810
2811 void NotifyRxStart(Time duration) override
2812 {
2813 NS_LOG_FUNCTION(this << duration);
2816 m_lastRxSuccess = false;
2817 }
2818
2819 void NotifyRxEndOk() override
2820 {
2821 NS_LOG_FUNCTION(this);
2823 ++m_notifyRxEnd;
2824 m_lastRxSuccess = true;
2825 }
2826
2827 void NotifyRxEndError() override
2828 {
2829 NS_LOG_FUNCTION(this);
2831 ++m_notifyRxEnd;
2832 m_lastRxSuccess = false;
2833 }
2834
2835 void NotifyTxStart(Time duration, double txPowerDbm) override
2836 {
2837 NS_LOG_FUNCTION(this << duration << txPowerDbm);
2838 }
2839
2841 WifiChannelListType channelType,
2842 const std::vector<Time>& /*per20MhzDurations*/) override
2843 {
2844 NS_LOG_FUNCTION(this << duration << channelType);
2845 }
2846
2847 void NotifySwitchingStart(Time duration) override
2848 {
2849 }
2850
2851 void NotifySleep() override
2852 {
2853 }
2854
2855 void NotifyOff() override
2856 {
2857 }
2858
2859 void NotifyWakeup() override
2860 {
2861 }
2862
2863 void NotifyOn() override
2864 {
2865 }
2866
2870 void Reset()
2871 {
2872 m_notifyRxStart = 0;
2873 m_notifyRxEnd = 0;
2875 m_lastRxEnd = Seconds(0);
2876 m_lastRxSuccess = false;
2877 }
2878
2884 {
2885 return m_notifyRxStart;
2886 }
2887
2893 {
2894 return m_notifyRxEnd;
2895 }
2896
2902 {
2903 return m_lastRxStart;
2904 }
2905
2911 {
2912 return m_lastRxEnd;
2913 }
2914
2919 bool IsLastRxSuccess() const
2920 {
2921 return m_lastRxSuccess;
2922 }
2923
2924 private:
2929 bool m_lastRxSuccess{false};
2930};
2931
2939{
2940 public:
2945 {
2946 NONE = 0,
2950 };
2951
2953 ~TestUlOfdmaPhyTransmission() override;
2954
2955 private:
2956 void DoSetup() override;
2957 void DoTeardown() override;
2958 void DoRun() override;
2959
2967 WifiTxVector GetTxVectorForHeTbPpdu(uint16_t txStaId,
2968 std::size_t index,
2969 uint8_t bssColor) const;
2976 void SetTrigVector(uint8_t bssColor, TrigVectorInfo error);
2986 void SendHeTbPpdu(uint16_t txStaId,
2987 std::size_t index,
2988 std::size_t payloadSize,
2989 uint64_t uid,
2990 uint8_t bssColor,
2991 bool incrementUid);
2992
3000 void SendHeSuPpdu(uint16_t txStaId, std::size_t payloadSize, uint64_t uid, uint8_t bssColor);
3001
3007 void SetBssColor(Ptr<WifiPhy> phy, uint8_t bssColor);
3008
3014 void SetPsdLimit(Ptr<WifiPhy> phy, double psdLimit);
3015
3021 void GenerateInterference(Ptr<SpectrumValue> interferencePsd, Time duration);
3025 void StopInterference();
3026
3030 void RunOne();
3031
3038 void CheckRxFromSta1(uint32_t expectedSuccess,
3039 uint32_t expectedFailures,
3040 uint32_t expectedBytes);
3041
3048 void CheckRxFromSta2(uint32_t expectedSuccess,
3049 uint32_t expectedFailures,
3050 uint32_t expectedBytes);
3051
3060 double expectedRxPower);
3069 double expectedRxPower);
3070
3074 void VerifyEventsCleared();
3075
3081 void CheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
3084
3091 void CheckApRxStart(uint32_t expectedNotifications, Time expectedLastNotification);
3099 void CheckApRxEnd(uint32_t expectedNotifications,
3100 Time expectedLastNotification,
3101 bool expectedSuccess);
3102
3106 void Reset();
3107
3116 RxSignalInfo rxSignalInfo,
3117 WifiTxVector txVector,
3118 std::vector<bool> statusPerMpdu);
3119
3124 void RxFailure(Ptr<const WifiPsdu> psdu);
3125
3146 void ScheduleTest(Time delay,
3147 bool solicited,
3148 WifiPhyState expectedStateAtEnd,
3149 uint32_t expectedSuccessFromSta1,
3150 uint32_t expectedFailuresFromSta1,
3151 uint32_t expectedBytesFromSta1,
3152 uint32_t expectedSuccessFromSta2,
3153 uint32_t expectedFailuresFromSta2,
3154 uint32_t expectedBytesFromSta2,
3155 bool scheduleTxSta1 = true,
3156 Time ulTimeDifference = Seconds(0),
3157 WifiPhyState expectedStateBeforeEnd = WifiPhyState::RX,
3158 TrigVectorInfo error = NONE);
3159
3170 double rxPowerNonOfdmaRu1,
3171 double rxPowerNonOfdmaRu2,
3172 double rxPowerOfdmaRu1,
3173 double rxPowerOfdmaRu2);
3179 void LogScenario(std::string log) const;
3180
3185
3186 std::unique_ptr<OfdmaTestPhyListener>
3188
3190
3197
3198 uint16_t m_frequency;
3201};
3202
3204 : TestCase("UL-OFDMA PHY test"),
3205 m_countRxSuccessFromSta1(0),
3206 m_countRxSuccessFromSta2(0),
3207 m_countRxFailureFromSta1(0),
3208 m_countRxFailureFromSta2(0),
3209 m_countRxBytesFromSta1(0),
3210 m_countRxBytesFromSta2(0),
3211 m_frequency(DEFAULT_FREQUENCY),
3212 m_channelWidth(DEFAULT_CHANNEL_WIDTH),
3213 m_expectedPpduDuration(NanoSeconds(271200))
3214{
3215}
3216
3217void
3219 std::size_t payloadSize,
3220 uint64_t uid,
3221 uint8_t bssColor)
3222{
3223 NS_LOG_FUNCTION(this << txStaId << payloadSize << uid << +bssColor);
3224 WifiConstPsduMap psdus;
3225
3227 0,
3229 800,
3230 1,
3231 1,
3232 0,
3234 false,
3235 false,
3236 false,
3237 bssColor);
3238
3239 Ptr<Packet> pkt = Create<Packet>(payloadSize);
3240 WifiMacHeader hdr;
3242 hdr.SetQosTid(0);
3243 hdr.SetAddr1(Mac48Address("00:00:00:00:00:00"));
3244 std::ostringstream addr;
3245 addr << "00:00:00:00:00:0" << txStaId;
3246 hdr.SetAddr2(Mac48Address(addr.str().c_str()));
3247 hdr.SetSequenceNumber(1);
3248 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
3249 psdus.insert(std::make_pair(SU_STA_ID, psdu));
3250
3252 if (txStaId == 1)
3253 {
3254 phy = m_phySta1;
3255 }
3256 else if (txStaId == 2)
3257 {
3258 phy = m_phySta2;
3259 }
3260 else if (txStaId == 3)
3261 {
3262 phy = m_phySta3;
3263 }
3264 else if (txStaId == 0)
3265 {
3266 phy = m_phyAp;
3267 }
3268 phy->SetPpduUid(uid);
3269 phy->Send(psdus, txVector);
3270}
3271
3274 std::size_t index,
3275 uint8_t bssColor) const
3276{
3278 0,
3280 1600,
3281 1,
3282 1,
3283 0,
3285 false,
3286 false,
3287 false,
3288 bssColor);
3289
3291 if (m_channelWidth == 20)
3292 {
3293 ruType = HeRu::RU_106_TONE;
3294 }
3295 else if (m_channelWidth == 40)
3296 {
3297 ruType = HeRu::RU_242_TONE;
3298 }
3299 else if (m_channelWidth == 80)
3300 {
3301 ruType = HeRu::RU_484_TONE;
3302 }
3303 else if (m_channelWidth == 160)
3304 {
3305 ruType = HeRu::RU_996_TONE;
3306 }
3307 else
3308 {
3309 NS_ASSERT_MSG(false, "Unsupported channel width");
3310 }
3311
3312 bool primary80MHz = true;
3313 if (m_channelWidth == 160 && index == 2)
3314 {
3315 primary80MHz = false;
3316 index = 1;
3317 }
3318 HeRu::RuSpec ru(ruType, index, primary80MHz);
3319 txVector.SetRu(ru, txStaId);
3320 txVector.SetMode(HePhy::GetHeMcs7(), txStaId);
3321 txVector.SetNss(1, txStaId);
3322 return txVector;
3323}
3324
3325void
3327{
3328 uint16_t channelWidth = m_channelWidth;
3329 if (error == CHANNEL_WIDTH)
3330 {
3331 channelWidth = (channelWidth == 160 ? 20 : channelWidth * 2);
3332 }
3333
3334 WifiTxVector txVector(HePhy::GetHeMcs7(),
3335 0,
3337 1600,
3338 1,
3339 1,
3340 0,
3341 channelWidth,
3342 false,
3343 false,
3344 false,
3345 bssColor);
3346
3348 if (channelWidth == 20)
3349 {
3350 ruType = HeRu::RU_106_TONE;
3351 }
3352 else if (channelWidth == 40)
3353 {
3354 ruType = HeRu::RU_242_TONE;
3355 }
3356 else if (channelWidth == 80)
3357 {
3358 ruType = HeRu::RU_484_TONE;
3359 }
3360 else if (channelWidth == 160)
3361 {
3362 ruType = HeRu::RU_996_TONE;
3363 }
3364 else
3365 {
3366 NS_ASSERT_MSG(false, "Unsupported channel width");
3367 }
3368
3369 uint16_t aid1 = (error == AID ? 3 : 1);
3370 uint16_t aid2 = (error == AID ? 4 : 2);
3371
3372 HeRu::RuSpec ru1(ruType, 1, true);
3373 txVector.SetRu(ru1, aid1);
3374 txVector.SetMode(HePhy::GetHeMcs7(), aid1);
3375 txVector.SetNss(1, aid1);
3376
3377 HeRu::RuSpec ru2(ruType, (channelWidth == 160 ? 1 : 2), (channelWidth != 160));
3378 txVector.SetRu(ru2, aid2);
3379 txVector.SetMode(HePhy::GetHeMcs7(), aid2);
3380 txVector.SetNss(1, aid2);
3381
3382 uint16_t length;
3383 std::tie(length, m_expectedPpduDuration) =
3385 txVector,
3386 m_phyAp->GetPhyBand());
3387 if (error == UL_LENGTH)
3388 {
3389 ++length;
3390 }
3391 txVector.SetLength(length);
3392 auto hePhyAp = DynamicCast<HePhy>(m_phyAp->GetLatestPhyEntity());
3393 hePhyAp->SetTrigVector(txVector, m_expectedPpduDuration);
3394}
3395
3396void
3398 std::size_t index,
3399 std::size_t payloadSize,
3400 uint64_t uid,
3401 uint8_t bssColor,
3402 bool incrementUid)
3403{
3404 NS_LOG_FUNCTION(this << txStaId << index << payloadSize << uid << +bssColor << (incrementUid));
3405 WifiConstPsduMap psdus;
3406
3407 if (incrementUid)
3408 {
3409 ++uid;
3410 }
3411
3412 WifiTxVector txVector = GetTxVectorForHeTbPpdu(txStaId, index, bssColor);
3413 Ptr<Packet> pkt = Create<Packet>(payloadSize);
3414 WifiMacHeader hdr;
3416 hdr.SetQosTid(0);
3417 hdr.SetAddr1(Mac48Address("00:00:00:00:00:00"));
3418 std::ostringstream addr;
3419 addr << "00:00:00:00:00:0" << txStaId;
3420 hdr.SetAddr2(Mac48Address(addr.str().c_str()));
3421 hdr.SetSequenceNumber(1);
3422 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
3423 psdus.insert(std::make_pair(txStaId, psdu));
3424
3426 if (txStaId == 1)
3427 {
3428 phy = m_phySta1;
3429 }
3430 else if (txStaId == 2)
3431 {
3432 phy = m_phySta2;
3433 }
3434 else if (txStaId == 3)
3435 {
3436 phy = m_phySta3;
3437 }
3438
3439 Time txDuration =
3440 phy->CalculateTxDuration(psdu->GetSize(), txVector, phy->GetPhyBand(), txStaId);
3441 txVector.SetLength(
3442 HePhy::ConvertHeTbPpduDurationToLSigLength(txDuration, txVector, phy->GetPhyBand()).first);
3443
3444 phy->SetPpduUid(uid);
3445 phy->Send(psdus, txVector);
3446}
3447
3448void
3450{
3451 NS_LOG_FUNCTION(this << duration);
3453 m_phyInterferer->SetPeriod(duration);
3456}
3457
3458void
3460{
3462}
3463
3465{
3466}
3467
3468void
3470 RxSignalInfo rxSignalInfo,
3471 WifiTxVector txVector,
3472 std::vector<bool> /*statusPerMpdu*/)
3473{
3474 NS_LOG_FUNCTION(this << *psdu << psdu->GetAddr2() << rxSignalInfo << txVector);
3475 if (psdu->GetAddr2() == Mac48Address("00:00:00:00:00:01"))
3476 {
3478 m_countRxBytesFromSta1 += (psdu->GetSize() - 30);
3479 }
3480 else if (psdu->GetAddr2() == Mac48Address("00:00:00:00:00:02"))
3481 {
3483 m_countRxBytesFromSta2 += (psdu->GetSize() - 30);
3484 }
3485}
3486
3487void
3489{
3490 NS_LOG_FUNCTION(this << *psdu << psdu->GetAddr2());
3491 if (psdu->GetAddr2() == Mac48Address("00:00:00:00:00:01"))
3492 {
3494 }
3495 else if (psdu->GetAddr2() == Mac48Address("00:00:00:00:00:02"))
3496 {
3498 }
3499}
3500
3501void
3503 uint32_t expectedFailures,
3504 uint32_t expectedBytes)
3505{
3507 expectedSuccess,
3508 "The number of successfully received packets from STA 1 is not correct!");
3511 expectedFailures,
3512 "The number of unsuccessfuly received packets from STA 1 is not correct!");
3514 expectedBytes,
3515 "The number of bytes received from STA 1 is not correct!");
3516}
3517
3518void
3520 uint32_t expectedFailures,
3521 uint32_t expectedBytes)
3522{
3524 expectedSuccess,
3525 "The number of successfully received packets from STA 2 is not correct!");
3528 expectedFailures,
3529 "The number of unsuccessfuly received packets from STA 2 is not correct!");
3531 expectedBytes,
3532 "The number of bytes received from STA 2 is not correct!");
3533}
3534
3535void
3538 double expectedRxPower)
3539{
3540 Ptr<Event> event = phy->GetCurrentEvent();
3541 NS_ASSERT(event);
3542 auto rxPower = event->GetRxPowerW(band);
3543 NS_LOG_FUNCTION(this << band << expectedRxPower << rxPower);
3544 // Since there is out of band emission due to spectrum mask, the tolerance cannot be very low
3546 expectedRxPower,
3547 5e-3,
3548 "RX power " << rxPower << " over (" << band
3549 << ") does not match expected power " << expectedRxPower
3550 << " at " << Simulator::Now());
3551}
3552
3553void
3556 double expectedRxPower)
3557{
3563 NS_LOG_FUNCTION(this << band << expectedRxPower);
3564 double step = 5e-3;
3565 if (expectedRxPower > 0.0)
3566 {
3568 phy->GetEnergyDuration(expectedRxPower - step, band).IsStrictlyPositive(),
3569 true,
3570 "At least " << expectedRxPower << " W expected for OFDMA part over (" << band << ") at "
3571 << Simulator::Now());
3573 phy->GetEnergyDuration(expectedRxPower + step, band).IsStrictlyPositive(),
3574 false,
3575 "At most " << expectedRxPower << " W expected for OFDMA part over (" << band << ") at "
3576 << Simulator::Now());
3577 }
3578 else
3579 {
3581 phy->GetEnergyDuration(expectedRxPower + step, band).IsStrictlyPositive(),
3582 false,
3583 "At most " << expectedRxPower << " W expected for OFDMA part over (" << band << ") at "
3584 << Simulator::Now());
3585 }
3586}
3587
3588void
3590{
3592 nullptr,
3593 "m_currentEvent for AP was not cleared");
3595 nullptr,
3596 "m_currentEvent for STA 1 was not cleared");
3598 nullptr,
3599 "m_currentEvent for STA 2 was not cleared");
3600}
3601
3602void
3604{
3605 // This is needed to make sure PHY state will be checked as the last event if a state change
3606 // occurred at the exact same time as the check
3608}
3609
3610void
3612 WifiPhyState expectedState)
3613{
3614 WifiPhyState currentState;
3615 PointerValue ptr;
3616 phy->GetAttribute("State", ptr);
3617 Ptr<WifiPhyStateHelper> state = DynamicCast<WifiPhyStateHelper>(ptr.Get<WifiPhyStateHelper>());
3618 currentState = state->GetState();
3619 NS_LOG_FUNCTION(this << currentState);
3620 NS_TEST_ASSERT_MSG_EQ(currentState,
3621 expectedState,
3622 "PHY State " << currentState << " does not match expected state "
3623 << expectedState << " at " << Simulator::Now());
3624}
3625
3626void
3628 Time expectedLastNotification)
3629{
3630 NS_TEST_ASSERT_MSG_EQ(m_apPhyStateListener->GetNumRxStartNotifications(),
3631 expectedNotifications,
3632 "Number of RX start notifications "
3633 << m_apPhyStateListener->GetNumRxStartNotifications()
3634 << " does not match expected count " << expectedNotifications
3635 << " for AP at " << Simulator::Now());
3636 NS_TEST_ASSERT_MSG_EQ(m_apPhyStateListener->GetLastRxStartNotification(),
3637 expectedLastNotification,
3638 "Last time RX start notification has been received "
3639 << m_apPhyStateListener->GetLastRxStartNotification()
3640 << " does not match expected time " << expectedLastNotification
3641 << " for AP at " << Simulator::Now());
3642}
3643
3644void
3646 Time expectedLastNotification,
3647 bool expectedSuccess)
3648{
3649 NS_TEST_ASSERT_MSG_EQ(m_apPhyStateListener->GetNumRxEndNotifications(),
3650 expectedNotifications,
3651 "Number of RX end notifications "
3652 << m_apPhyStateListener->GetNumRxEndNotifications()
3653 << " does not match expected count " << expectedNotifications
3654 << " for AP at " << Simulator::Now());
3655 NS_TEST_ASSERT_MSG_EQ(m_apPhyStateListener->GetLastRxEndNotification(),
3656 expectedLastNotification,
3657 "Last time RX end notification has been received "
3658 << m_apPhyStateListener->GetLastRxEndNotification()
3659 << " does not match expected time " << expectedLastNotification
3660 << " for AP at " << Simulator::Now());
3662 expectedSuccess,
3663 "Last time RX end notification indicated a "
3664 << (m_apPhyStateListener->IsLastRxSuccess() ? "success" : "failure")
3665 << " but expected a " << (expectedSuccess ? "success" : "failure")
3666 << " for AP at " << Simulator::Now());
3667}
3668
3669void
3671{
3681 SetBssColor(m_phyAp, 0);
3682 m_apPhyStateListener->Reset();
3683}
3684
3685void
3687{
3688 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice>(phy->GetDevice());
3689 Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration();
3690 heConfiguration->SetAttribute("BssColor", UintegerValue(bssColor));
3691}
3692
3693void
3695{
3696 NS_LOG_FUNCTION(this << phy << psdLimit);
3697 phy->SetAttribute("PowerDensityLimit", DoubleValue(psdLimit));
3698}
3699
3700void
3702{
3703 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
3704 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
3705 lossModel->SetFrequency(m_frequency);
3706 spectrumChannel->AddPropagationLossModel(lossModel);
3708 CreateObject<ConstantSpeedPropagationDelayModel>();
3709 spectrumChannel->SetPropagationDelayModel(delayModel);
3710
3711 Ptr<ThresholdPreambleDetectionModel> preambleDetectionModel =
3712 CreateObject<ThresholdPreambleDetectionModel>();
3713 preambleDetectionModel->SetAttribute(
3714 "MinimumRssi",
3716 -8)); // to ensure that transmission in neighboring channel is ignored (16 dBm baseline)
3717 preambleDetectionModel->SetAttribute("Threshold", DoubleValue(-100)); // no limit on SNR
3718
3719 Ptr<Node> apNode = CreateObject<Node>();
3720 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice>();
3721 apDev->SetStandard(WIFI_STANDARD_80211ax);
3722 Ptr<ApWifiMac> apMac = CreateObject<ApWifiMac>();
3723 apMac->SetAttribute("BeaconGeneration", BooleanValue(false));
3724 apDev->SetMac(apMac);
3725 m_phyAp = CreateObject<OfdmaSpectrumWifiPhy>(0);
3726 Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration>();
3727 apDev->SetHeConfiguration(heConfiguration);
3728 Ptr<InterferenceHelper> apInterferenceHelper = CreateObject<InterferenceHelper>();
3729 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
3730 Ptr<ErrorRateModel> apErrorModel = CreateObject<NistErrorRateModel>();
3731 m_phyAp->SetErrorRateModel(apErrorModel);
3732 m_phyAp->SetDevice(apDev);
3733 m_phyAp->AddChannel(spectrumChannel);
3737 m_phyAp->SetPreambleDetectionModel(preambleDetectionModel);
3738 Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel>();
3739 m_phyAp->SetMobility(apMobility);
3740 m_apPhyStateListener = std::make_unique<OfdmaTestPhyListener>();
3742 apDev->SetPhy(m_phyAp);
3743 apMac->SetWifiPhys({m_phyAp});
3744 apNode->AggregateObject(apMobility);
3745 apNode->AddDevice(apDev);
3746
3747 Ptr<Node> sta1Node = CreateObject<Node>();
3748 Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice>();
3749 sta1Dev->SetStandard(WIFI_STANDARD_80211ax);
3750 sta1Dev->SetHeConfiguration(CreateObject<HeConfiguration>());
3751 m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy>(1);
3752 Ptr<InterferenceHelper> sta1InterferenceHelper = CreateObject<InterferenceHelper>();
3753 m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
3754 Ptr<ErrorRateModel> sta1ErrorModel = CreateObject<NistErrorRateModel>();
3755 m_phySta1->SetErrorRateModel(sta1ErrorModel);
3756 m_phySta1->SetDevice(sta1Dev);
3757 m_phySta1->AddChannel(spectrumChannel);
3759 m_phySta1->SetPreambleDetectionModel(preambleDetectionModel);
3760 Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel>();
3761 m_phySta1->SetMobility(sta1Mobility);
3762 sta1Dev->SetPhy(m_phySta1);
3763 sta1Node->AggregateObject(sta1Mobility);
3764 sta1Node->AddDevice(sta1Dev);
3765
3766 Ptr<Node> sta2Node = CreateObject<Node>();
3767 Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice>();
3768 sta2Dev->SetStandard(WIFI_STANDARD_80211ax);
3769 sta2Dev->SetHeConfiguration(CreateObject<HeConfiguration>());
3770 m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy>(2);
3771 Ptr<InterferenceHelper> sta2InterferenceHelper = CreateObject<InterferenceHelper>();
3772 m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
3773 Ptr<ErrorRateModel> sta2ErrorModel = CreateObject<NistErrorRateModel>();
3774 m_phySta2->SetErrorRateModel(sta2ErrorModel);
3775 m_phySta2->SetDevice(sta2Dev);
3776 m_phySta2->AddChannel(spectrumChannel);
3778 m_phySta2->SetPreambleDetectionModel(preambleDetectionModel);
3779 Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel>();
3780 m_phySta2->SetMobility(sta2Mobility);
3781 sta2Dev->SetPhy(m_phySta2);
3782 sta2Node->AggregateObject(sta2Mobility);
3783 sta2Node->AddDevice(sta2Dev);
3784
3785 Ptr<Node> sta3Node = CreateObject<Node>();
3786 Ptr<WifiNetDevice> sta3Dev = CreateObject<WifiNetDevice>();
3787 sta3Dev->SetStandard(WIFI_STANDARD_80211ax);
3788 sta3Dev->SetHeConfiguration(CreateObject<HeConfiguration>());
3789 m_phySta3 = CreateObject<OfdmaSpectrumWifiPhy>(3);
3790 Ptr<InterferenceHelper> sta3InterferenceHelper = CreateObject<InterferenceHelper>();
3791 m_phySta3->SetInterferenceHelper(sta3InterferenceHelper);
3792 Ptr<ErrorRateModel> sta3ErrorModel = CreateObject<NistErrorRateModel>();
3793 m_phySta3->SetErrorRateModel(sta3ErrorModel);
3794 m_phySta3->SetDevice(sta3Dev);
3795 m_phySta3->AddChannel(spectrumChannel);
3797 m_phySta3->SetPreambleDetectionModel(preambleDetectionModel);
3798 Ptr<ConstantPositionMobilityModel> sta3Mobility = CreateObject<ConstantPositionMobilityModel>();
3799 m_phySta3->SetMobility(sta3Mobility);
3800 sta3Dev->SetPhy(m_phySta3);
3801 sta3Node->AggregateObject(sta3Mobility);
3802 sta3Node->AddDevice(sta3Dev);
3803
3804 Ptr<Node> interfererNode = CreateObject<Node>();
3805 Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice>();
3806 m_phyInterferer = CreateObject<WaveformGenerator>();
3807 m_phyInterferer->SetDevice(interfererDev);
3808 m_phyInterferer->SetChannel(spectrumChannel);
3810 interfererNode->AddDevice(interfererDev);
3811
3812 // Configure power attributes of all wifi devices
3813 std::list<Ptr<WifiPhy>> phys{m_phyAp, m_phySta1, m_phySta2, m_phySta3};
3814 for (auto& phy : phys)
3815 {
3816 phy->SetAttribute("TxGain", DoubleValue(1.0));
3817 phy->SetAttribute("TxPowerStart", DoubleValue(16.0));
3818 phy->SetAttribute("TxPowerEnd", DoubleValue(16.0));
3819 phy->SetAttribute("PowerDensityLimit", DoubleValue(100.0)); // no impact by default
3820 phy->SetAttribute("RxGain", DoubleValue(2.0));
3821 // test assumes no rejection power for simplicity
3822 phy->SetAttribute("TxMaskInnerBandMinimumRejection", DoubleValue(-100.0));
3823 phy->SetAttribute("TxMaskOuterBandMinimumRejection", DoubleValue(-100.0));
3824 phy->SetAttribute("TxMaskOuterBandMaximumRejection", DoubleValue(-100.0));
3825 }
3826}
3827
3828void
3830{
3831 m_phyAp->Dispose();
3832 m_phyAp = nullptr;
3833 m_phySta1->Dispose();
3834 m_phySta1 = nullptr;
3835 m_phySta2->Dispose();
3836 m_phySta2 = nullptr;
3837 m_phySta3->Dispose();
3838 m_phySta3 = nullptr;
3840 m_phyInterferer = nullptr;
3841}
3842
3843void
3845{
3846 NS_LOG_INFO(log);
3847}
3848
3849void
3851 bool solicited,
3852 WifiPhyState expectedStateAtEnd,
3853 uint32_t expectedSuccessFromSta1,
3854 uint32_t expectedFailuresFromSta1,
3855 uint32_t expectedBytesFromSta1,
3856 uint32_t expectedSuccessFromSta2,
3857 uint32_t expectedFailuresFromSta2,
3858 uint32_t expectedBytesFromSta2,
3859 bool scheduleTxSta1,
3860 Time ulTimeDifference,
3861 WifiPhyState expectedStateBeforeEnd,
3862 TrigVectorInfo error)
3863{
3864 static uint64_t uid = 0;
3865
3866 // AP sends an SU packet preceding HE TB PPDUs
3869 this,
3870 0,
3871 50,
3872 ++uid,
3873 0);
3874 if (!solicited)
3875 {
3876 // UID of TB PPDUs will be different than the one of the preceding frame
3877 ++uid;
3878 }
3879 else
3880 {
3882 }
3883 // STA1 and STA2 send MU UL PPDUs addressed to AP
3886 m_apPhyStateListener.get());
3887 if (scheduleTxSta1)
3888 {
3889 Simulator::Schedule(delay,
3891 this,
3892 1,
3893 1,
3894 1000,
3895 uid,
3896 0,
3897 false);
3898 }
3899 Simulator::Schedule(delay + ulTimeDifference,
3901 this,
3902 2,
3903 2,
3904 1001,
3905 uid,
3906 0,
3907 false);
3908
3909 // Verify it takes m_expectedPpduDuration to transmit the PPDUs
3912 this,
3913 m_phyAp,
3914 expectedStateBeforeEnd);
3915 Simulator::Schedule(delay + m_expectedPpduDuration + ulTimeDifference,
3917 this,
3918 m_phyAp,
3919 expectedStateAtEnd);
3920 // TODO: add checks on TX stop for STAs
3921
3922 if (expectedSuccessFromSta1 + expectedFailuresFromSta1 + expectedSuccessFromSta2 +
3923 expectedFailuresFromSta2 >
3924 0)
3925 {
3926 // RxEndOk if at least one HE TB PPDU has been successfully received, RxEndError otherwise
3927 const bool isSuccess = (expectedSuccessFromSta1 > 0) || (expectedSuccessFromSta2 > 0);
3928 // The expected time at which the reception is started corresponds to the time at which the
3929 // test is started, plus the time to transmit the PHY preamble and the PHY headers.
3930 const Time expectedPayloadStart = delay + MicroSeconds(48);
3931 // The expected time at which the reception is terminated corresponds to the time at which
3932 // the test is started, plus the time to transmit the PPDU, plus the delay between the first
3933 // received HE TB PPDU and the last received HE TB PPDU.
3934 const Time expectedPayloadEnd = delay + m_expectedPpduDuration + ulTimeDifference;
3935 // At the end of the transmission, verify that a single RX start notification shall have
3936 // been notified when the reception of the first HE RB PPDU starts.
3937 Simulator::Schedule(expectedPayloadEnd,
3939 this,
3940 1,
3941 Simulator::Now() + expectedPayloadStart);
3942 // After the reception (hence we add 1ns to expectedPayloadEnd), a single RX end
3943 // notification shall have been notified when the reception of the last HE RB PPDU ends
3944 Simulator::Schedule(expectedPayloadEnd + NanoSeconds(1),
3946 this,
3947 1,
3948 Simulator::Now() + expectedPayloadEnd,
3949 isSuccess);
3950 }
3951
3952 delay += MilliSeconds(100);
3953 // Check reception state from STA 1
3954 Simulator::Schedule(delay,
3956 this,
3957 expectedSuccessFromSta1,
3958 expectedFailuresFromSta1,
3959 expectedBytesFromSta1);
3960 // Check reception state from STA 2
3961 Simulator::Schedule(delay,
3963 this,
3964 expectedSuccessFromSta2,
3965 expectedFailuresFromSta2,
3966 expectedBytesFromSta2);
3967 // Verify events data have been cleared
3969
3970 delay += MilliSeconds(100);
3972}
3973
3974void
3976 double rxPowerNonOfdmaRu1,
3977 double rxPowerNonOfdmaRu2,
3978 double rxPowerOfdmaRu1,
3979 double rxPowerOfdmaRu2)
3980{
3981 Time detectionDuration = WifiPhy::GetPreambleDetectionDuration();
3982 WifiTxVector txVectorSta1 = GetTxVectorForHeTbPpdu(1, 1, 0);
3983 WifiTxVector txVectorSta2 = GetTxVectorForHeTbPpdu(2, 2, 0);
3985 Time nonOfdmaDuration = hePhy->CalculateNonOfdmaDurationForHeTb(txVectorSta2);
3986 NS_ASSERT(nonOfdmaDuration == hePhy->CalculateNonOfdmaDurationForHeTb(txVectorSta1));
3987
3988 std::vector<double> rxPowerNonOfdma{rxPowerNonOfdmaRu1, rxPowerNonOfdmaRu2};
3989 std::vector<WifiSpectrumBandInfo> nonOfdmaBand{hePhy->GetNonOfdmaBand(txVectorSta1, 1),
3990 hePhy->GetNonOfdmaBand(txVectorSta2, 2)};
3991 std::vector<double> rxPowerOfdma{rxPowerOfdmaRu1, rxPowerOfdmaRu2};
3992 std::vector<WifiSpectrumBandInfo> ofdmaBand{hePhy->GetRuBandForRx(txVectorSta1, 1),
3993 hePhy->GetRuBandForRx(txVectorSta2, 2)};
3994
3995 for (uint8_t i = 0; i < 2; ++i)
3996 {
4000 // Check received power on non-OFDMA portion
4002 delay + detectionDuration +
4003 NanoSeconds(1), // just after beginning of portion (once event is stored)
4005 this,
4006 m_phyAp,
4007 nonOfdmaBand[i],
4008 rxPowerNonOfdma[i]);
4009 Simulator::Schedule(delay + nonOfdmaDuration - NanoSeconds(1), // just before end of portion
4011 this,
4012 m_phyAp,
4013 nonOfdmaBand[i],
4014 rxPowerNonOfdma[i]);
4015 // Check received power on OFDMA portion
4016 Simulator::Schedule(delay + nonOfdmaDuration +
4017 NanoSeconds(1), // just after beginning of portion
4019 this,
4020 m_phyAp,
4021 ofdmaBand[i],
4022 rxPowerOfdma[i]);
4024 NanoSeconds(1), // just before end of portion
4026 this,
4027 m_phyAp,
4028 ofdmaBand[i],
4029 rxPowerOfdma[i]);
4030
4036 // Check received power on non-OFDMA portion
4038 delay + detectionDuration +
4039 NanoSeconds(1), // just after beginning of portion (once event is stored)
4041 this,
4042 m_phySta3,
4043 nonOfdmaBand[i],
4044 rxPowerNonOfdma[i]);
4045 Simulator::Schedule(delay + nonOfdmaDuration - NanoSeconds(1), // just before end of portion
4047 this,
4048 m_phySta3,
4049 nonOfdmaBand[i],
4050 rxPowerNonOfdma[i]);
4051 // Check received power on OFDMA portion
4052 Simulator::Schedule(delay + nonOfdmaDuration +
4053 NanoSeconds(1), // just after beginning of portion
4055 this,
4056 m_phySta3,
4057 ofdmaBand[i],
4058 rxPowerOfdma[i]);
4060 NanoSeconds(1), // just before end of portion
4062 this,
4063 m_phySta3,
4064 ofdmaBand[i],
4065 rxPowerOfdma[i]);
4066 }
4067
4068 if (rxPowerOfdmaRu1 != 0.0)
4069 {
4075 double rxPowerNonOfdmaSta1Only =
4076 (m_channelWidth >= 40)
4077 ? rxPowerNonOfdma[0]
4078 : rxPowerNonOfdma[0] / 2; // both STAs transmit over the same 20 MHz channel
4079 // Check received power on non-OFDMA portion
4081 delay + detectionDuration +
4082 NanoSeconds(1), // just after beginning of portion (once event is stored)
4084 this,
4085 m_phySta2,
4086 nonOfdmaBand[0],
4087 rxPowerNonOfdmaSta1Only);
4088 Simulator::Schedule(delay + nonOfdmaDuration - NanoSeconds(1), // just before end of portion
4090 this,
4091 m_phySta2,
4092 nonOfdmaBand[0],
4093 rxPowerNonOfdmaSta1Only);
4094 // Check received power on OFDMA portion
4095 Simulator::Schedule(delay + nonOfdmaDuration +
4096 NanoSeconds(1), // just after beginning of portion
4098 this,
4099 m_phySta2,
4100 ofdmaBand[0],
4101 rxPowerOfdma[0]);
4103 NanoSeconds(1), // just before end of portion
4105 this,
4106 m_phySta2,
4107 ofdmaBand[0],
4108 rxPowerOfdma[0]);
4109 }
4110}
4111
4112void
4114{
4117 int64_t streamNumber = 0;
4118 m_phyAp->AssignStreams(streamNumber);
4119 m_phySta1->AssignStreams(streamNumber);
4120 m_phySta2->AssignStreams(streamNumber);
4121 m_phySta3->AssignStreams(streamNumber);
4122
4123 auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0,
4128
4137
4138 Time delay = Seconds(0.0);
4140 delay += Seconds(1.0);
4141
4150 //---------------------------------------------------------------------------
4151 // Verify that both solicited HE TB PPDUs have been corrected received
4152 Simulator::Schedule(delay,
4154 this,
4155 "Reception of solicited HE TB PPDUs");
4156 ScheduleTest(delay,
4157 true,
4158 WifiPhyState::IDLE,
4159 1,
4160 0,
4161 1000, // One PSDU of 1000 bytes should have been successfully received from STA 1
4162 1,
4163 0,
4164 1001); // One PSDU of 1001 bytes should have been successfully received from STA 2
4165 delay += Seconds(1.0);
4166
4167 //---------------------------------------------------------------------------
4168 // Verify that two solicited HE TB PPDUs with delay (< 400ns) between the two signals have been
4169 // corrected received
4171 delay,
4173 this,
4174 "Reception of solicited HE TB PPDUs with delay (< 400ns) between the two signals");
4175 ScheduleTest(delay,
4176 true,
4177 WifiPhyState::IDLE,
4178 1,
4179 0,
4180 1000, // One PSDU of 1000 bytes should have been successfully received from STA 1
4181 1,
4182 0,
4183 1001, // One PSDU of 1001 bytes should have been successfully received from STA 2
4184 true,
4185 NanoSeconds(100));
4186 delay += Seconds(1.0);
4187
4188 //---------------------------------------------------------------------------
4189 // Verify that no unsolicited HE TB PPDU is received
4190 Simulator::Schedule(delay,
4192 this,
4193 "Dropping of unsolicited HE TB PPDUs");
4194 ScheduleTest(delay,
4195 false,
4196 WifiPhyState::IDLE,
4197 0,
4198 0,
4199 0, // PSDU from STA 1 is not received (no TRIGVECTOR)
4200 0,
4201 0,
4202 0, // PSDU from STA 2 is not received (no TRIGVECTOR)
4203 true,
4204 Seconds(0),
4205 WifiPhyState::CCA_BUSY);
4206 delay += Seconds(1.0);
4207
4208 //---------------------------------------------------------------------------
4209 // Verify that HE TB PPDUs with channel width differing from TRIGVECTOR are discarded
4210 Simulator::Schedule(delay,
4212 this,
4213 "Dropping of HE TB PPDUs with channel width differing from TRIGVECTOR");
4214 ScheduleTest(delay,
4215 true,
4216 WifiPhyState::IDLE,
4217 0,
4218 0,
4219 0, // PSDU from STA 1 is not received (no TRIGVECTOR)
4220 0,
4221 0,
4222 0, // PSDU from STA 2 is not received (no TRIGVECTOR)
4223 true,
4224 Seconds(0),
4225 WifiPhyState::CCA_BUSY,
4227 delay += Seconds(1.0);
4228
4229 //---------------------------------------------------------------------------
4230 // Verify that HE TB PPDUs with UL Length differing from TRIGVECTOR are discarded
4231 Simulator::Schedule(delay,
4233 this,
4234 "Dropping of HE TB PPDUs with UL Length differing from TRIGVECTOR");
4235 ScheduleTest(delay,
4236 true,
4237 WifiPhyState::IDLE,
4238 0,
4239 0,
4240 0, // PSDU from STA 1 is not received (no TRIGVECTOR)
4241 0,
4242 0,
4243 0, // PSDU from STA 2 is not received (no TRIGVECTOR)
4244 true,
4245 Seconds(0),
4246 WifiPhyState::CCA_BUSY,
4247 UL_LENGTH);
4248 delay += Seconds(1.0);
4249
4250 //---------------------------------------------------------------------------
4251 // Verify that HE TB PPDUs with AIDs differing from TRIGVECTOR are discarded
4252 Simulator::Schedule(delay,
4254 this,
4255 "Dropping of HE TB PPDUs with AIDs differing from TRIGVECTOR");
4256 ScheduleTest(delay,
4257 true,
4258 WifiPhyState::IDLE,
4259 0,
4260 0,
4261 0, // PSDU from STA 1 is not received (no TRIGVECTOR)
4262 0,
4263 0,
4264 0, // PSDU from STA 2 is not received (no TRIGVECTOR)
4265 true,
4266 Seconds(0),
4267 WifiPhyState::CCA_BUSY,
4268 AID);
4269 delay += Seconds(1.0);
4270
4271 //---------------------------------------------------------------------------
4272 // Generate an interference on RU 1 and verify that only STA 1's solicited HE TB PPDU has been
4273 // impacted
4275 delay,
4277 this,
4278 "Reception of solicited HE TB PPDUs with interference on RU 1 during PSDU reception");
4279 // A strong non-wifi interference is generated on RU 1 during PSDU reception
4280 BandInfo bandInfo;
4281 bandInfo.fc = (m_frequency - (m_channelWidth / 4)) * 1e6;
4282 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
4283 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
4284 Bands bands;
4285 bands.push_back(bandInfo);
4286
4287 Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel>(bands);
4288 Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue>(SpectrumInterferenceRu1);
4289 double interferencePower = 0.1; // watts
4290 *interferencePsdRu1 = interferencePower / ((m_channelWidth / 2) * 20e6);
4291
4294 this,
4295 interferencePsdRu1,
4296 MilliSeconds(100));
4298 delay,
4299 true,
4300 WifiPhyState::CCA_BUSY, // PHY should move to CCA_BUSY instead of IDLE due to the
4301 // interference
4302 0,
4303 1,
4304 0, // Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
4305 1,
4306 0,
4307 1001); // One PSDU of 1001 bytes should have been successfully received from STA 2
4308 delay += Seconds(1.0);
4309
4310 //---------------------------------------------------------------------------
4311 // Generate an interference on RU 2 and verify that only STA 2's solicited HE TB PPDU has been
4312 // impacted
4314 delay,
4316 this,
4317 "Reception of solicited HE TB PPDUs with interference on RU 2 during PSDU reception");
4318 // A strong non-wifi interference is generated on RU 2 during PSDU reception
4319 bandInfo.fc = (m_frequency + (m_channelWidth / 4)) * 1e6;
4320 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 4) * 1e6);
4321 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 4) * 1e6);
4322 bands.clear();
4323 bands.push_back(bandInfo);
4324
4325 Ptr<SpectrumModel> SpectrumInterferenceRu2 = Create<SpectrumModel>(bands);
4326 Ptr<SpectrumValue> interferencePsdRu2 = Create<SpectrumValue>(SpectrumInterferenceRu2);
4327 *interferencePsdRu2 = interferencePower / ((m_channelWidth / 2) * 20e6);
4328
4331 this,
4332 interferencePsdRu2,
4333 MilliSeconds(100));
4334 ScheduleTest(delay,
4335 true,
4336 (m_channelWidth >= 40)
4337 ? WifiPhyState::IDLE
4338 : WifiPhyState::CCA_BUSY, // PHY should move to CCA_BUSY if interference is
4339 // generated in its primary channel
4340 1,
4341 0,
4342 1000, // One PSDU of 1000 bytes should have been successfully received from STA 1
4343 0,
4344 1,
4345 0); // Reception of the PSDU from STA 2 should have failed (since interference
4346 // occupies RU 2)
4347 delay += Seconds(1.0);
4348
4349 //---------------------------------------------------------------------------
4350 // Generate an interference on the full band and verify that both solicited HE TB PPDUs have
4351 // been impacted
4352 Simulator::Schedule(delay,
4354 this,
4355 "Reception of solicited HE TB PPDUs with interference on the full band "
4356 "during PSDU reception");
4357 // A strong non-wifi interference is generated on the full band during PSDU reception
4358 bandInfo.fc = m_frequency * 1e6;
4359 bandInfo.fl = bandInfo.fc - ((m_channelWidth / 2) * 1e6);
4360 bandInfo.fh = bandInfo.fc + ((m_channelWidth / 2) * 1e6);
4361 bands.clear();
4362 bands.push_back(bandInfo);
4363
4364 Ptr<SpectrumModel> SpectrumInterferenceAll = Create<SpectrumModel>(bands);
4365 Ptr<SpectrumValue> interferencePsdAll = Create<SpectrumValue>(SpectrumInterferenceAll);
4366 *interferencePsdAll = interferencePower / (m_channelWidth * 20e6);
4367
4370 this,
4371 interferencePsdAll,
4372 MilliSeconds(100));
4374 delay,
4375 true,
4376 WifiPhyState::CCA_BUSY, // PHY should move to CCA_BUSY instead of IDLE due to the
4377 // interference
4378 0,
4379 1,
4380 0, // Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
4381 0,
4382 1,
4383 0); // Reception of the PSDU from STA 2 should have failed (since interference occupies RU
4384 // 2)
4385 delay += Seconds(1.0);
4386
4387 //---------------------------------------------------------------------------
4388 // Send another HE TB PPDU (of another UL MU transmission) on RU 1 and verify that both
4389 // solicited HE TB PPDUs have been impacted if they are on the same
4390 // 20 MHz channel. Only STA 1's solicited HE TB PPDU is impacted otherwise.
4391 Simulator::Schedule(delay,
4393 this,
4394 "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU "
4395 "1 during PSDU reception");
4396 // Another HE TB PPDU arrives at AP on the same RU as STA 1 during PSDU reception
4399 this,
4400 3,
4401 1,
4402 1002,
4403 1,
4404 0,
4405 false);
4406 // Expected figures from STA 2
4407 uint32_t succ;
4408 uint32_t fail;
4409 uint32_t bytes;
4410 if (m_channelWidth > 20)
4411 {
4412 // One PSDU of 1001 bytes should have been successfully received from STA 2 (since
4413 // interference from STA 3 on distinct 20 MHz channel)
4414 succ = 1;
4415 fail = 0;
4416 bytes = 1001;
4417 }
4418 else
4419 {
4420 // Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on
4421 // same 20 MHz channel)
4422 succ = 0;
4423 fail = 1;
4424 bytes = 0;
4425 }
4426 ScheduleTest(delay,
4427 true,
4428 WifiPhyState::CCA_BUSY, // PHY should move to CCA_BUSY instead of IDLE due to the
4429 // interference on measurement channel width
4430 0,
4431 1,
4432 0, // Reception of the PSDU from STA 1 should have failed (since interference from
4433 // STA 3 on same 20 MHz channel)
4434 succ,
4435 fail,
4436 bytes);
4437 delay += Seconds(1.0);
4438
4439 //---------------------------------------------------------------------------
4440 // Send another HE TB PPDU (of another UL MU transmission) on RU 2 and verify that both
4441 // solicited HE TB PPDUs have been impacted if they are on the same
4442 // 20 MHz channel. Only STA 2's solicited HE TB PPDU is impacted otherwise.
4443 Simulator::Schedule(delay,
4445 this,
4446 "Reception of solicited HE TB PPDUs with another HE TB PPDU arriving on RU "
4447 "2 during PSDU reception");
4448 // Another HE TB PPDU arrives at AP on the same RU as STA 2 during PSDU reception
4451 this,
4452 3,
4453 2,
4454 1002,
4455 1,
4456 0,
4457 false);
4458 // Expected figures from STA 1
4459 if (m_channelWidth > 20)
4460 {
4461 // One PSDU of 1000 bytes should have been successfully received from STA 1 (since
4462 // interference from STA 3 on distinct 20 MHz channel)
4463 succ = 1;
4464 fail = 0;
4465 bytes = 1000;
4466 }
4467 else
4468 {
4469 // Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on
4470 // same 20 MHz channel)
4471 succ = 0;
4472 fail = 1;
4473 bytes = 0;
4474 }
4475 ScheduleTest(delay,
4476 true,
4477 (m_channelWidth >= 40)
4478 ? WifiPhyState::IDLE
4479 : WifiPhyState::CCA_BUSY, // PHY should move to CCA_BUSY instead of IDLE if HE
4480 // TB PPDU on primary channel
4481 succ,
4482 fail,
4483 bytes,
4484 0,
4485 1,
4486 0); // Reception of the PSDU from STA 2 should have failed (since interference from
4487 // STA 3 on same 20 MHz channel)
4488 delay += Seconds(1.0);
4489
4490 //---------------------------------------------------------------------------
4491 // Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been
4492 // impacted
4494 delay,
4496 this,
4497 "Reception of solicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window");
4498 // One HE SU arrives at AP during the 400ns window
4499 Simulator::Schedule(delay + NanoSeconds(300),
4501 this,
4502 3,
4503 1002,
4504 1,
4505 0);
4507 delay,
4508 true,
4509 WifiPhyState::IDLE,
4510 0,
4511 1,
4512 0, // Reception of the PSDU from STA 1 should have failed (since interference from STA 3)
4513 0,
4514 1,
4515 0); // Reception of the PSDU from STA 2 should have failed (since interference from STA 3)
4516 delay += Seconds(1.0);
4517
4518 //---------------------------------------------------------------------------
4519 // Only send a solicited HE TB PPDU from STA 2 on RU 2 and verify that it has been correctly
4520 // received
4521 Simulator::Schedule(delay,
4523 this,
4524 "Reception of solicited HE TB PPDU only on RU 2");
4525 // Check that STA3 will correctly set its state to CCA_BUSY if in measurement channel or IDLE
4526 // otherwise
4529 this,
4530 m_phySta3,
4531 (m_channelWidth >= 40)
4532 ? WifiPhyState::IDLE
4533 : WifiPhyState::CCA_BUSY); // PHY should move to CCA_BUSY instead of
4534 // IDLE if HE TB PPDU on primary channel
4535 ScheduleTest(delay,
4536 true,
4537 WifiPhyState::IDLE,
4538 0,
4539 0,
4540 0, // No transmission scheduled for STA 1
4541 1,
4542 0,
4543 1001, // One PSDU of 1001 bytes should have been successfully received from STA 2
4544 false,
4545 Seconds(0),
4546 WifiPhyState::RX); // Measurement channel is total channel width
4547 delay += Seconds(1.0);
4548
4549 //---------------------------------------------------------------------------
4550 // Measure the power of a solicited HE TB PPDU from STA 2 on RU 2
4551 Simulator::Schedule(delay,
4553 this,
4554 "Measure power for reception of HE TB PPDU only on RU 2");
4555 double rxPower =
4556 DbmToW(19); // 16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
4558 (m_channelWidth >= 40) ? 0.0 : rxPower,
4559 rxPower, // power detected on RU1 only if same 20 MHz as RU 2
4560 0.0,
4561 rxPower);
4562 ScheduleTest(delay,
4563 true,
4564 WifiPhyState::IDLE,
4565 0,
4566 0,
4567 0, // No transmission scheduled for STA 1
4568 1,
4569 0,
4570 1001, // One PSDU of 1001 bytes should have been successfully received from STA 2
4571 false,
4572 Seconds(0),
4573 WifiPhyState::RX); // Measurement channel is total channel width
4574 delay += Seconds(1.0);
4575
4576 //---------------------------------------------------------------------------
4577 // Measure the power of a solicited HE TB PPDU from STA 2 on RU 2 with power spectrum density
4578 // limitation enforced
4580 delay,
4582 this,
4583 "Measure power for reception of HE TB PPDU only on RU 2 with PSD limitation");
4584 // Configure PSD limitation at 3 dBm/MHz -> 3+13.0103=16.0103 dBm max for 20 MHz,
4585 // 3+9.0309=12.0309 dBm max for 106-tone RU, no impact for 40 MHz and above
4586 Simulator::Schedule(delay - NanoSeconds(1), // just before sending HE TB
4588 this,
4589 m_phySta2,
4590 3.0);
4591
4592 rxPower = (m_channelWidth > 40)
4593 ? DbmToW(19)
4594 : DbmToW(18.0103); // 15.0103+1 dBm at STA 2 and +2 at AP for non-OFDMA
4595 // transmitted only on one 20 MHz channel
4596 double rxPowerOfdma = rxPower;
4597 if (m_channelWidth <= 40)
4598 {
4599 rxPowerOfdma = (m_channelWidth == 20)
4600 ? DbmToW(14.0309) // 11.0309+1 dBm at STA and +2 at AP if 106-tone RU
4601 : DbmToW(18.0103); // 15.0103+1 dBm at STA 2 and +2 at AP if 242-tone RU
4602 }
4604 (m_channelWidth >= 40) ? 0.0 : rxPower,
4605 rxPower, // power detected on RU1 only if same 20 MHz as RU 2
4606 0.0,
4607 rxPowerOfdma);
4608
4609 // Reset PSD limitation once HE TB has been sent
4612 this,
4613 m_phySta2,
4614 100.0);
4615 ScheduleTest(delay,
4616 true,
4617 WifiPhyState::IDLE,
4618 0,
4619 0,
4620 0, // No transmission scheduled for STA 1
4621 1,
4622 0,
4623 1001, // One PSDU of 1001 bytes should have been successfully received from STA 2
4624 false,
4625 Seconds(0),
4626 WifiPhyState::RX); // Measurement channel is total channel width
4627 delay += Seconds(1.0);
4628
4629 //---------------------------------------------------------------------------
4630 // Measure the power of 2 solicited HE TB PPDU from both STAs
4631 Simulator::Schedule(delay,
4633 this,
4634 "Measure power for reception of HE TB PPDU on both RUs");
4635 rxPower = DbmToW(19); // 16+1 dBm at STAs and +2 at AP (no loss since all devices are colocated)
4636 double rxPowerNonOfdma = (m_channelWidth >= 40)
4637 ? rxPower
4638 : rxPower * 2; // both STAs transmit over the same 20 MHz channel
4639 SchedulePowerMeasurementChecks(delay, rxPowerNonOfdma, rxPowerNonOfdma, rxPower, rxPower);
4640 ScheduleTest(delay,
4641 true,
4642 WifiPhyState::IDLE,
4643 1,
4644 0,
4645 1000, // One PSDU of 1000 bytes should have been successfully received from STA 1
4646 1,
4647 0,
4648 1001); // One PSDU of 1001 bytes should have been successfully received from STA 2
4649 delay += Seconds(1.0);
4650
4651 //---------------------------------------------------------------------------
4652 // Verify that an HE TB PPDU from another BSS has been correctly received (no UL MU transmission
4653 // ongoing)
4654 Simulator::Schedule(delay,
4656 this,
4657 "Reception of an HE TB PPDU from another BSS");
4658 // One HE TB from another BSS (BSS color 2) arrives at AP (BSS color 1)
4660 Simulator::Schedule(delay + MilliSeconds(100),
4662 this,
4663 3,
4664 1,
4665 1002,
4666 1,
4667 2,
4668 false);
4669
4670 // Verify events data have been cleared
4671 Simulator::Schedule(delay + MilliSeconds(200),
4673 this);
4674
4676 delay += Seconds(1.0);
4677
4678 //---------------------------------------------------------------------------
4679 // Verify that two solicited HE TB PPDUs with delay (< 400ns) between the two signals have been
4680 // corrected received
4682 delay,
4684 this,
4685 "Reception of solicited HE TB PPDUs with delay (< 400ns) between the two signals and "
4686 "reception of an HE TB PPDU from another BSS between the ends of the two HE TB PPDUs");
4690 this,
4691 3,
4692 1,
4693 1002,
4694 1,
4695 2,
4696 true);
4697 ScheduleTest(delay,
4698 true,
4699 WifiPhyState::CCA_BUSY,
4700 1,
4701 0,
4702 1000, // One PSDU of 1000 bytes should have been successfully received from STA 1
4703 1,
4704 0,
4705 1001, // One PSDU of 1001 bytes should have been successfully received from STA 2
4706 true,
4707 NanoSeconds(200));
4708 delay += Seconds(1.0);
4709
4711}
4712
4713void
4715{
4716 m_frequency = 5180;
4717 m_channelWidth = 20;
4719 NS_LOG_DEBUG("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
4720 RunOne();
4721
4722 m_frequency = 5190;
4723 m_channelWidth = 40;
4725 NS_LOG_DEBUG("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
4726 RunOne();
4727
4728 m_frequency = 5210;
4729 m_channelWidth = 80;
4731 NS_LOG_DEBUG("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
4732 RunOne();
4733
4734 m_frequency = 5250;
4735 m_channelWidth = 160;
4737 NS_LOG_DEBUG("Run UL OFDMA PHY transmission test for " << m_channelWidth << " MHz");
4738 RunOne();
4739
4741}
4742
4750{
4751 public:
4753 ~TestPhyPaddingExclusion() override;
4754
4755 private:
4756 void DoSetup() override;
4757 void DoTeardown() override;
4758 void DoRun() override;
4759
4767 void SendHeTbPpdu(uint16_t txStaId,
4768 std::size_t index,
4769 std::size_t payloadSize,
4770 Time txDuration);
4776 void SetTrigVector(Time ppduDuration);
4777
4783 void GenerateInterference(Ptr<SpectrumValue> interferencePsd, Time duration);
4787 void StopInterference();
4788
4792 void RunOne();
4793
4800 void CheckRxFromSta1(uint32_t expectedSuccess,
4801 uint32_t expectedFailures,
4802 uint32_t expectedBytes);
4803
4810 void CheckRxFromSta2(uint32_t expectedSuccess,
4811 uint32_t expectedFailures,
4812 uint32_t expectedBytes);
4813
4817 void VerifyEventsCleared();
4818
4824 void CheckPhyState(Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
4827
4831 void Reset();
4832
4841 RxSignalInfo rxSignalInfo,
4842 WifiTxVector txVector,
4843 std::vector<bool> statusPerMpdu);
4844
4849 void RxFailure(Ptr<const WifiPsdu> psdu);
4850
4854
4856
4863};
4864
4866 : TestCase("PHY padding exclusion test"),
4867 m_countRxSuccessFromSta1(0),
4868 m_countRxSuccessFromSta2(0),
4869 m_countRxFailureFromSta1(0),
4870 m_countRxFailureFromSta2(0),
4871 m_countRxBytesFromSta1(0),
4872 m_countRxBytesFromSta2(0)
4873{
4874}
4875
4876void
4878 std::size_t index,
4879 std::size_t payloadSize,
4880 Time txDuration)
4881{
4882 WifiConstPsduMap psdus;
4883
4885 0,
4887 1600,
4888 1,
4889 1,
4890 0,
4892 false,
4893 false,
4894 1);
4895
4896 HeRu::RuSpec ru(HeRu::RU_106_TONE, index, false);
4897 txVector.SetRu(ru, txStaId);
4898 txVector.SetMode(HePhy::GetHeMcs7(), txStaId);
4899 txVector.SetNss(1, txStaId);
4900
4901 Ptr<Packet> pkt = Create<Packet>(payloadSize);
4902 WifiMacHeader hdr;
4904 hdr.SetQosTid(0);
4905 hdr.SetAddr1(Mac48Address("00:00:00:00:00:00"));
4906 std::ostringstream addr;
4907 addr << "00:00:00:00:00:0" << txStaId;
4908 hdr.SetAddr2(Mac48Address(addr.str().c_str()));
4909 hdr.SetSequenceNumber(1);
4910 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
4911 psdus.insert(std::make_pair(txStaId, psdu));
4912
4914 if (txStaId == 1)
4915 {
4916 phy = m_phySta1;
4917 }
4918 else if (txStaId == 2)
4919 {
4920 phy = m_phySta2;
4921 }
4922
4923 txVector.SetLength(
4924 HePhy::ConvertHeTbPpduDurationToLSigLength(txDuration, txVector, phy->GetPhyBand()).first);
4925
4926 phy->SetPpduUid(0);
4927 phy->Send(psdus, txVector);
4928}
4929
4930void
4932{
4934 m_phyInterferer->SetPeriod(duration);
4937}
4938
4939void
4941{
4943}
4944
4946{
4947}
4948
4949void
4951 RxSignalInfo rxSignalInfo,
4952 WifiTxVector txVector,
4953 std::vector<bool> /*statusPerMpdu*/)
4954{
4955 NS_LOG_FUNCTION(this << *psdu << psdu->GetAddr2() << rxSignalInfo << txVector);
4956 if (psdu->GetAddr2() == Mac48Address("00:00:00:00:00:01"))
4957 {
4959 m_countRxBytesFromSta1 += (psdu->GetSize() - 30);
4960 }
4961 else if (psdu->GetAddr2() == Mac48Address("00:00:00:00:00:02"))
4962 {
4964 m_countRxBytesFromSta2 += (psdu->GetSize() - 30);
4965 }
4966}
4967
4968void
4970{
4971 NS_LOG_FUNCTION(this << *psdu << psdu->GetAddr2());
4972 if (psdu->GetAddr2() == Mac48Address("00:00:00:00:00:01"))
4973 {
4975 }
4976 else if (psdu->GetAddr2() == Mac48Address("00:00:00:00:00:02"))
4977 {
4979 }
4980}
4981
4982void
4984 uint32_t expectedFailures,
4985 uint32_t expectedBytes)
4986{
4988 expectedSuccess,
4989 "The number of successfully received packets from STA 1 is not correct!");
4992 expectedFailures,
4993 "The number of unsuccessfuly received packets from STA 1 is not correct!");
4995 expectedBytes,
4996 "The number of bytes received from STA 1 is not correct!");
4997}
4998
4999void
5001 uint32_t expectedFailures,
5002 uint32_t expectedBytes)
5003{
5005 expectedSuccess,
5006 "The number of successfully received packets from STA 2 is not correct!");
5009 expectedFailures,
5010 "The number of unsuccessfuly received packets from STA 2 is not correct!");
5012 expectedBytes,
5013 "The number of bytes received from STA 2 is not correct!");
5014}
5015
5016void
5018{
5020 nullptr,
5021 "m_currentEvent for AP was not cleared");
5023 nullptr,
5024 "m_currentEvent for STA 1 was not cleared");
5026 nullptr,
5027 "m_currentEvent for STA 2 was not cleared");
5028}
5029
5030void
5032{
5033 // This is needed to make sure PHY state will be checked as the last event if a state change
5034 // occurred at the exact same time as the check
5036}
5037
5038void
5040{
5041 WifiPhyState currentState = phy->GetState()->GetState();
5042 NS_LOG_FUNCTION(this << currentState);
5043 NS_TEST_ASSERT_MSG_EQ(currentState,
5044 expectedState,
5045 "PHY State " << currentState << " does not match expected state "
5046 << expectedState << " at " << Simulator::Now());
5047}
5048
5049void
5051{
5061}
5062
5063void
5065{
5068 int64_t streamNumber = 0;
5069
5070 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
5071 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel>();
5072 lossModel->SetFrequency(DEFAULT_FREQUENCY * 1e6);
5073 spectrumChannel->AddPropagationLossModel(lossModel);
5075 CreateObject<ConstantSpeedPropagationDelayModel>();
5076 spectrumChannel->SetPropagationDelayModel(delayModel);
5077
5078 Ptr<Node> apNode = CreateObject<Node>();
5079 Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice>();
5080 Ptr<ApWifiMac> apMac = CreateObject<ApWifiMac>();
5081 apMac->SetAttribute("BeaconGeneration", BooleanValue(false));
5082 apDev->SetMac(apMac);
5083 m_phyAp = CreateObject<OfdmaSpectrumWifiPhy>(0);
5084 Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration>();
5085 apDev->SetHeConfiguration(heConfiguration);
5086 Ptr<InterferenceHelper> apInterferenceHelper = CreateObject<InterferenceHelper>();
5087 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
5088 Ptr<ErrorRateModel> apErrorModel = CreateObject<NistErrorRateModel>();
5089 m_phyAp->SetErrorRateModel(apErrorModel);
5090 m_phyAp->SetDevice(apDev);
5091 m_phyAp->AddChannel(spectrumChannel);
5093 m_phyAp->AssignStreams(streamNumber);
5094 auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0,
5099
5104 Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel>();
5105 m_phyAp->SetMobility(apMobility);
5106 apDev->SetPhy(m_phyAp);
5107 apDev->SetStandard(WIFI_STANDARD_80211ax);
5108 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
5109 apMac->SetWifiPhys({m_phyAp});
5110 apNode->AggregateObject(apMobility);
5111 apNode->AddDevice(apDev);
5112
5113 Ptr<Node> sta1Node = CreateObject<Node>();
5114 Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice>();
5115 m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy>(1);
5116 Ptr<InterferenceHelper> sta1InterferenceHelper = CreateObject<InterferenceHelper>();
5117 m_phySta1->SetInterferenceHelper(sta1InterferenceHelper);
5118 Ptr<ErrorRateModel> sta1ErrorModel = CreateObject<NistErrorRateModel>();
5119 m_phySta1->SetErrorRateModel(sta1ErrorModel);
5120 m_phySta1->SetDevice(sta1Dev);
5121 m_phySta1->AddChannel(spectrumChannel);
5123 m_phySta1->AssignStreams(streamNumber);
5126 Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel>();
5127 m_phySta1->SetMobility(sta1Mobility);
5128 sta1Dev->SetPhy(m_phySta1);
5129 sta1Dev->SetStandard(WIFI_STANDARD_80211ax);
5130 sta1Dev->SetHeConfiguration(CreateObject<HeConfiguration>());
5131 sta1Node->AggregateObject(sta1Mobility);
5132 sta1Node->AddDevice(sta1Dev);
5133
5134 Ptr<Node> sta2Node = CreateObject<Node>();
5135 Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice>();
5136 m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy>(2);
5137 Ptr<InterferenceHelper> sta2InterferenceHelper = CreateObject<InterferenceHelper>();
5138 m_phySta2->SetInterferenceHelper(sta2InterferenceHelper);
5139 Ptr<ErrorRateModel> sta2ErrorModel = CreateObject<NistErrorRateModel>();
5140 m_phySta2->SetErrorRateModel(sta2ErrorModel);
5141 m_phySta2->SetDevice(sta2Dev);
5142 m_phySta2->AddChannel(spectrumChannel);
5144 m_phySta2->AssignStreams(streamNumber);
5147 Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel>();
5148 m_phySta2->SetMobility(sta2Mobility);
5149 sta2Dev->SetPhy(m_phySta2);
5150 sta2Dev->SetStandard(WIFI_STANDARD_80211ax);
5151 sta2Dev->SetHeConfiguration(CreateObject<HeConfiguration>());
5152 sta2Node->AggregateObject(sta2Mobility);
5153 sta2Node->AddDevice(sta2Dev);
5154
5155 Ptr<Node> interfererNode = CreateObject<Node>();
5156 Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice>();
5157 m_phyInterferer = CreateObject<WaveformGenerator>();
5158 m_phyInterferer->SetDevice(interfererDev);
5159 m_phyInterferer->SetChannel(spectrumChannel);
5161 interfererNode->AddDevice(interfererDev);
5162}
5163
5164void
5166{
5167 m_phyAp->Dispose();
5168 m_phyAp = nullptr;
5169 m_phySta1->Dispose();
5170 m_phySta1 = nullptr;
5171 m_phySta2->Dispose();
5172 m_phySta2 = nullptr;
5174 m_phyInterferer = nullptr;
5175}
5176
5177void
5179{
5180 WifiTxVector trigVector(HePhy::GetHeMcs7(),
5181 0,
5183 1600,
5184 1,
5185 1,
5186 0,
5188 false,
5189 false,
5190 1);
5191 trigVector.SetRu(HeRu::RuSpec(HeRu::RU_106_TONE, 1, false), 1);
5192 trigVector.SetMode(HePhy::GetHeMcs7(), 1);
5193 trigVector.SetNss(1, 1);
5194 trigVector.SetRu(HeRu::RuSpec(HeRu::RU_106_TONE, 2, false), 2);
5195 trigVector.SetMode(HePhy::GetHeMcs7(), 2);
5196 trigVector.SetNss(1, 2);
5197 uint16_t length;
5198 std::tie(length, ppduDuration) =
5200 trigVector.SetLength(length);
5201 auto hePhyAp = DynamicCast<HePhy>(