A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-non-ht-dup-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022
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/he-configuration.h"
24#include "ns3/he-phy.h"
25#include "ns3/interference-helper.h"
26#include "ns3/log.h"
27#include "ns3/mobility-helper.h"
28#include "ns3/multi-model-spectrum-channel.h"
29#include "ns3/nist-error-rate-model.h"
30#include "ns3/node.h"
31#include "ns3/non-communicating-net-device.h"
32#include "ns3/rng-seed-manager.h"
33#include "ns3/simulator.h"
34#include "ns3/spectrum-wifi-helper.h"
35#include "ns3/spectrum-wifi-phy.h"
36#include "ns3/sta-wifi-mac.h"
37#include "ns3/test.h"
38#include "ns3/waveform-generator.h"
39#include "ns3/wifi-mac-header.h"
40#include "ns3/wifi-net-device.h"
41#include "ns3/wifi-psdu.h"
42#include "ns3/wifi-spectrum-signal-parameters.h"
43#include "ns3/wifi-spectrum-value-helper.h"
44#include "ns3/wifi-utils.h"
45
46#include <vector>
47
48using namespace ns3;
49
50NS_LOG_COMPONENT_DEFINE("WifiNonHtDuplicateTest");
51
52constexpr uint32_t DEFAULT_FREQUENCY = 5180; // MHz
53
57class MuRtsCtsHePhy : public HePhy
58{
59 public:
61 ~MuRtsCtsHePhy() override;
62
68 void SetPreviousTxPpduUid(uint64_t uid);
69
75 void SetMuRtsTxVector(const WifiTxVector& muRtsTxVector);
76}; // class MuRtsCtsHePhy
77
79 : HePhy()
80{
81 NS_LOG_FUNCTION(this);
82}
83
85{
86 NS_LOG_FUNCTION(this);
87}
88
89void
91{
92 NS_LOG_FUNCTION(this << uid);
94}
95
96void
98{
99 NS_LOG_FUNCTION(this << muRtsTxVector);
100 m_currentTxVector = muRtsTxVector;
101}
102
107{
108 public:
113 static TypeId GetTypeId();
114
116 ~MuRtsCtsSpectrumWifiPhy() override;
117
118 void DoInitialize() override;
119 void DoDispose() override;
120
126 void SetPpduUid(uint64_t uid);
127
133 void SetMuRtsTxVector(const WifiTxVector& muRtsTxVector);
134
135 private:
137}; // class MuRtsCtsSpectrumWifiPhy
138
139TypeId
141{
142 static TypeId tid =
143 TypeId("ns3::MuRtsCtsSpectrumWifiPhy").SetParent<SpectrumWifiPhy>().SetGroupName("Wifi");
144 return tid;
145}
146
149{
150 NS_LOG_FUNCTION(this);
151 m_muRtsCtsHePhy = Create<MuRtsCtsHePhy>();
153}
154
156{
157 NS_LOG_FUNCTION(this);
158}
159
160void
162{
163 // Replace HE PHY instance with test instance
166}
167
168void
170{
171 m_muRtsCtsHePhy = nullptr;
173}
174
175void
177{
178 NS_LOG_FUNCTION(this << uid);
181}
182
183void
185{
186 NS_LOG_FUNCTION(this << muRtsTxVector);
187 m_muRtsCtsHePhy->SetMuRtsTxVector(muRtsTxVector);
188}
189
202{
203 public:
205 using StasParams = std::vector<std::tuple<WifiStandard, uint16_t, uint8_t>>;
206
218 uint16_t apFrequency,
219 uint8_t apP20Index,
220 StasParams stasParams,
221 std::vector<bool> per20MhzInterference = {});
222
223 private:
224 void DoSetup() override;
225 void DoTeardown() override;
226 void DoRun() override;
227
236 void RxSuccess(std::size_t index,
238 RxSignalInfo rxSignalInfo,
239 WifiTxVector txVector,
240 std::vector<bool> statusPerMpdu);
241
247 void RxFailure(std::size_t index, Ptr<const WifiPsdu> psdu);
248
255 void CheckResults(std::size_t index, uint32_t expectedRxSuccess, uint32_t expectedRxFailure);
256
260 void ResetResults();
261
266 void SendNonHtDuplicatePpdu(uint16_t channelWidth);
267
275 Ptr<SpectrumValue> interferencePsd,
276 Time duration);
282
284 uint16_t m_apFrequency;
285 uint8_t m_apP20Index;
287 std::vector<bool>
290
291 std::vector<uint32_t> m_countRxSuccessStas;
292 std::vector<uint32_t> m_countRxFailureStas;
293
295 std::vector<Ptr<SpectrumWifiPhy>> m_phyStas;
296
297 std::vector<Ptr<WaveformGenerator>>
299};
300
302 WifiStandard apStandard,
303 uint16_t apFrequency,
304 uint8_t apP20Index,
305 StasParams stasParams,
306 std::vector<bool> per20MhzInterference)
307 : TestCase{"non-HT duplicate PHY reception test"},
308 m_apStandard{apStandard},
309 m_apFrequency{apFrequency},
310 m_apP20Index{apP20Index},
311 m_stasParams{stasParams},
312 m_per20MhzInterference{per20MhzInterference},
313 m_countRxSuccessStas{},
314 m_countRxFailureStas{},
315 m_phyStas{}
316{
317}
318
319void
321{
322 for (auto& countRxSuccess : m_countRxSuccessStas)
323 {
324 countRxSuccess = 0;
325 }
326 for (auto& countRxFailure : m_countRxFailureStas)
327 {
328 countRxFailure = 0;
329 }
330}
331
332void
334{
335 NS_LOG_FUNCTION(this << channelWidth);
337 0,
339 800,
340 1,
341 1,
342 0,
343 channelWidth,
344 false);
345
346 Ptr<Packet> pkt = Create<Packet>(1000);
347 WifiMacHeader hdr;
348
350 hdr.SetQosTid(0);
351
352 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
353 Time txDuration =
354 m_phyAp->CalculateTxDuration(psdu->GetSize(), txVector, m_phyAp->GetPhyBand());
355
356 m_phyAp->Send(WifiConstPsduMap({std::make_pair(SU_STA_ID, psdu)}), txVector);
357}
358
359void
361 Ptr<SpectrumValue> interferencePsd,
362 Time duration)
363{
364 NS_LOG_FUNCTION(this << interferer << duration);
365 interferer->SetTxPowerSpectralDensity(interferencePsd);
366 interferer->SetPeriod(duration);
367 interferer->Start();
368 Simulator::Schedule(duration,
370 this,
371 interferer);
372}
373
374void
376{
377 NS_LOG_FUNCTION(this << interferer);
378 interferer->Stop();
379}
380
381void
384 RxSignalInfo rxSignalInfo,
385 WifiTxVector txVector,
386 std::vector<bool> /*statusPerMpdu*/)
387{
388 NS_LOG_FUNCTION(this << index << *psdu << rxSignalInfo << txVector);
389 m_countRxSuccessStas.at(index)++;
390}
391
392void
394{
395 NS_LOG_FUNCTION(this << index << *psdu);
396 m_countRxFailureStas.at(index)++;
397}
398
399void
401 uint32_t expectedRxSuccess,
402 uint32_t expectedRxFailure)
403{
404 NS_LOG_FUNCTION(this << index << expectedRxSuccess << expectedRxFailure);
406 expectedRxSuccess,
407 "The number of successfully received packets by STA "
408 << index << " is not correct!");
410 expectedRxFailure,
411 "The number of unsuccessfully received packets by STA "
412 << index << " is not correct!");
413}
414
415void
417{
418 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
419 auto lossModel = CreateObject<FriisPropagationLossModel>();
420 lossModel->SetFrequency(m_apFrequency * 1e6);
421 spectrumChannel->AddPropagationLossModel(lossModel);
422 auto delayModel = CreateObject<ConstantSpeedPropagationDelayModel>();
423 spectrumChannel->SetPropagationDelayModel(delayModel);
424
425 auto apNode = CreateObject<Node>();
426 auto apDev = CreateObject<WifiNetDevice>();
427 m_phyAp = CreateObject<SpectrumWifiPhy>();
428 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
429 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
430 auto apErrorModel = CreateObject<NistErrorRateModel>();
431 m_phyAp->SetErrorRateModel(apErrorModel);
432 m_phyAp->SetDevice(apDev);
433 m_phyAp->AddChannel(spectrumChannel);
435 auto apMobility = CreateObject<ConstantPositionMobilityModel>();
436 m_phyAp->SetMobility(apMobility);
437 apDev->SetPhy(m_phyAp);
438 apNode->AggregateObject(apMobility);
439 apNode->AddDevice(apDev);
440
441 for (const auto& staParams : m_stasParams)
442 {
443 auto staNode = CreateObject<Node>();
444 auto staDev = CreateObject<WifiNetDevice>();
445 auto staPhy = CreateObject<SpectrumWifiPhy>();
446 auto sta1InterferenceHelper = CreateObject<InterferenceHelper>();
447 staPhy->SetInterferenceHelper(sta1InterferenceHelper);
448 auto sta1ErrorModel = CreateObject<NistErrorRateModel>();
449 staPhy->SetErrorRateModel(sta1ErrorModel);
450 staPhy->SetDevice(staDev);
451 staPhy->AddChannel(spectrumChannel);
452 staPhy->ConfigureStandard(std::get<0>(staParams));
453 staPhy->SetReceiveOkCallback(
455 staPhy->SetReceiveErrorCallback(
457 auto staMobility = CreateObject<ConstantPositionMobilityModel>();
458 staPhy->SetMobility(staMobility);
459 staDev->SetPhy(staPhy);
460 staNode->AggregateObject(staMobility);
461 staNode->AddDevice(staDev);
462 m_phyStas.push_back(staPhy);
463 m_countRxSuccessStas.push_back(0);
464 m_countRxFailureStas.push_back(0);
465 }
466
467 if (!m_per20MhzInterference.empty())
468 {
469 [[maybe_unused]] auto [channelNum, centerFreq, apChannelWidth, type, phyBand] =
472 0,
475 NS_ASSERT(m_per20MhzInterference.size() == (apChannelWidth / 20));
476 for (std::size_t i = 0; i < m_per20MhzInterference.size(); ++i)
477 {
478 auto interfererNode = CreateObject<Node>();
479 auto interfererDev = CreateObject<NonCommunicatingNetDevice>();
480 auto phyInterferer = CreateObject<WaveformGenerator>();
481 phyInterferer->SetDevice(interfererDev);
482 phyInterferer->SetChannel(spectrumChannel);
483 phyInterferer->SetDutyCycle(1);
484 interfererNode->AddDevice(interfererDev);
485 m_phyInterferers.push_back(phyInterferer);
486 }
487 }
488}
489
490void
492{
493 m_phyAp->Dispose();
494 m_phyAp = nullptr;
495 for (auto phySta : m_phyStas)
496 {
497 phySta->Dispose();
498 phySta = nullptr;
499 }
500 for (auto phyInterferer : m_phyInterferers)
501 {
502 phyInterferer->Dispose();
503 phyInterferer = nullptr;
504 }
505}
506
507void
509{
512 int64_t streamNumber = 0;
513 m_phyAp->AssignStreams(streamNumber);
514 for (auto phySta : m_phyStas)
515 {
516 phySta->AssignStreams(streamNumber);
517 }
518
519 [[maybe_unused]] auto [apChannelNum, centerFreq, apChannelWidth, type, phyBand] =
522 0,
526 WifiPhy::ChannelTuple{apChannelNum, apChannelWidth, WIFI_PHY_BAND_5GHZ, m_apP20Index});
527
528 auto index = 0;
529 for (const auto& [staStandard, staFrequency, staP20Index] : m_stasParams)
530 {
531 [[maybe_unused]] auto [staChannelNum, centerFreq, staChannelWidth, type, phyBand] =
533 staFrequency,
534 0,
535 staStandard,
537 m_phyStas.at(index++)->SetOperatingChannel(
538 WifiPhy::ChannelTuple{staChannelNum, staChannelWidth, WIFI_PHY_BAND_5GHZ, staP20Index});
539 }
540
541 index = 0;
542 const auto minApCenterFrequency =
543 m_phyAp->GetFrequency() - (m_phyAp->GetChannelWidth() / 2) + (20 / 2);
544 for (auto channelWidth = 20; channelWidth <= apChannelWidth; channelWidth *= 2, ++index)
545 {
546 if (!m_phyInterferers.empty())
547 {
548 for (std::size_t i = 0; i < m_phyInterferers.size(); ++i)
549 {
550 if (!m_per20MhzInterference.at(i))
551 {
552 continue;
553 }
554 BandInfo bandInfo;
555 bandInfo.fc = (minApCenterFrequency + (i * 20)) * 1e6;
556 bandInfo.fl = bandInfo.fc - (5 * 1e6);
557 bandInfo.fh = bandInfo.fc + (5 * 1e6);
558 Bands bands;
559 bands.push_back(bandInfo);
560 auto spectrumInterference = Create<SpectrumModel>(bands);
561 auto interferencePsd = Create<SpectrumValue>(spectrumInterference);
562 auto interferencePower = 0.005; // in watts (designed to make PHY headers reception
563 // successful but payload reception fail)
564 *interferencePsd = interferencePower / 10e6;
567 this,
568 m_phyInterferers.at(i),
569 interferencePsd,
570 Seconds(0.5));
571 }
572 }
573 const auto apCenterFreq =
575 const auto apMinFreq = apCenterFreq - (channelWidth / 2);
576 const auto apMaxFreq = apCenterFreq + (channelWidth / 2);
577 Simulator::Schedule(Seconds(index + 0.1),
579 this,
580 channelWidth);
581 for (std::size_t i = 0; i < m_stasParams.size(); ++i)
582 {
583 const auto p20Width = 20;
584 const auto staP20Freq =
585 m_phyStas.at(i)->GetOperatingChannel().GetPrimaryChannelCenterFrequency(p20Width);
586 const auto staP20MinFreq = staP20Freq - (p20Width / 2);
587 const auto staP20MaxFreq = staP20Freq + (p20Width / 2);
588 bool expectRx = (staP20MinFreq >= apMinFreq && staP20MaxFreq <= apMaxFreq);
589 bool expectSuccess = true;
590 if (!m_per20MhzInterference.empty())
591 {
592 const auto index20MhzSubBand = ((staP20Freq - minApCenterFrequency) / 20);
593 expectSuccess = !m_per20MhzInterference.at(index20MhzSubBand);
594 }
595 Simulator::Schedule(Seconds(index + 0.5),
597 this,
598 i,
599 expectRx ? expectSuccess : 0,
600 expectRx ? !expectSuccess : 0);
601 }
602 Simulator::Schedule(Seconds(index + 0.5),
604 this);
605 }
606
609}
610
622{
623 public:
628 TestMultipleCtsResponsesFromMuRts(const std::vector<uint16_t>& bwPerSta);
629
630 private:
631 void DoSetup() override;
632 void DoTeardown() override;
633 void DoRun() override;
634
640 void FakePreviousMuRts(uint16_t bw);
641
648 void TxNonHtDuplicateCts(Ptr<SpectrumWifiPhy> phy, uint16_t bw);
649
658 RxSignalInfo rxSignalInfo,
659 WifiTxVector txVector,
660 std::vector<bool> statusPerMpdu);
661
667
673 void CheckResults(std::size_t expectedRxCtsSuccess, std::size_t expectedRxCtsFailure);
674
676 std::vector<Ptr<MuRtsCtsSpectrumWifiPhy>> m_phyStas;
678
679 std::vector<uint16_t> m_bwPerSta;
680
683
685};
686
688 const std::vector<uint16_t>& bwPerSta)
689 : TestCase{"test PHY reception of multiple CTS frames following a MU-RTS frame"},
690 m_bwPerSta{bwPerSta},
691 m_countRxCtsSuccess{0},
692 m_countRxCtsFailure{0},
693 m_stasTxPowerDbm(10.0)
694{
695}
696
697void
699{
700 NS_LOG_FUNCTION(this << bw);
701
702 WifiTxVector txVector;
703 txVector.SetChannelWidth(bw); // only the channel width matters for this test
704
705 // set the TXVECTOR and the UID of the previously transmitted MU-RTS in the AP PHY
706 m_phyAp->SetMuRtsTxVector(txVector);
708
709 // set the UID of the previously received MU-RTS in the STAs PHYs
710 for (auto& phySta : m_phyStas)
711 {
712 phySta->SetPpduUid(0);
713 }
714}
715
716void
718{
719 NS_LOG_FUNCTION(this << phy << bw);
720
721 WifiTxVector txVector =
722 WifiTxVector(OfdmPhy::GetOfdmRate54Mbps(), // use less robust modulation for test purpose
723 0,
725 800,
726 1,
727 1,
728 0,
729 bw,
730 false,
731 false);
732 txVector.SetTriggerResponding(true);
733
734 WifiMacHeader hdr;
736 hdr.SetDsNotFrom();
737 hdr.SetDsNotTo();
738 hdr.SetNoMoreFragments();
739 hdr.SetNoRetry();
740
741 auto pkt = Create<Packet>();
742 auto mpdu = Create<WifiMpdu>(pkt, hdr);
743 auto psdu = Create<WifiPsdu>(mpdu, false);
744
745 phy->Send(psdu, txVector);
746}
747
748void
750 RxSignalInfo rxSignalInfo,
751 WifiTxVector txVector,
752 std::vector<bool> /*statusPerMpdu*/)
753{
754 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
755 NS_TEST_EXPECT_MSG_EQ_TOL(rxSignalInfo.rssi,
757 0.1,
758 "RX power is not correct!");
760}
761
762void
764{
765 NS_LOG_FUNCTION(this << *psdu);
767}
768
769void
770TestMultipleCtsResponsesFromMuRts::CheckResults(std::size_t expectedRxCtsSuccess,
771 std::size_t expectedRxCtsFailure)
772{
774 expectedRxCtsSuccess,
775 "The number of successfully received CTS frames by AP is not correct!");
777 expectedRxCtsFailure,
778 "The number of unsuccessfully received CTS frames by AP is not correct!");
779}
780
781void
783{
786 int64_t streamNumber = 0;
787
788 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
789 auto lossModel = CreateObject<FriisPropagationLossModel>();
790 lossModel->SetFrequency(DEFAULT_FREQUENCY * 1e6);
791 spectrumChannel->AddPropagationLossModel(lossModel);
792 auto delayModel = CreateObject<ConstantSpeedPropagationDelayModel>();
793 spectrumChannel->SetPropagationDelayModel(delayModel);
794
795 auto apNode = CreateObject<Node>();
796 auto apDev = CreateObject<WifiNetDevice>();
797 auto apMac = CreateObject<ApWifiMac>();
798 apMac->SetAttribute("BeaconGeneration", BooleanValue(false));
799 apDev->SetMac(apMac);
800 m_phyAp = CreateObject<MuRtsCtsSpectrumWifiPhy>();
801 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
802 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
803 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
804 auto apErrorModel = CreateObject<NistErrorRateModel>();
805 m_phyAp->SetErrorRateModel(apErrorModel);
806 m_phyAp->SetDevice(apDev);
807 m_phyAp->AddChannel(spectrumChannel);
809 m_phyAp->AssignStreams(streamNumber);
810
815
816 const auto apBw = *std::max_element(m_bwPerSta.cbegin(), m_bwPerSta.cend());
817 auto apChannelNum = std::get<0>(
819
821
822 auto apMobility = CreateObject<ConstantPositionMobilityModel>();
823 m_phyAp->SetMobility(apMobility);
824 apDev->SetPhy(m_phyAp);
825 apDev->SetStandard(WIFI_STANDARD_80211ax);
826 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
827 apMac->SetWifiPhys({m_phyAp});
828 apNode->AggregateObject(apMobility);
829 apNode->AddDevice(apDev);
830
831 for (std::size_t i = 0; i < m_bwPerSta.size(); ++i)
832 {
833 auto staNode = CreateObject<Node>();
834 auto staDev = CreateObject<WifiNetDevice>();
835 auto phySta = CreateObject<MuRtsCtsSpectrumWifiPhy>();
836 auto staInterferenceHelper = CreateObject<InterferenceHelper>();
837 phySta->SetInterferenceHelper(staInterferenceHelper);
838 auto staErrorModel = CreateObject<NistErrorRateModel>();
839 phySta->SetErrorRateModel(staErrorModel);
840 phySta->SetDevice(staDev);
841 phySta->AddChannel(spectrumChannel);
842 phySta->ConfigureStandard(WIFI_STANDARD_80211ax);
843 phySta->AssignStreams(streamNumber);
844 phySta->SetTxPowerStart(m_stasTxPowerDbm);
845 phySta->SetTxPowerEnd(m_stasTxPowerDbm);
846
847 auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0,
848 0,
849 m_bwPerSta.at(i),
852
853 phySta->SetOperatingChannel(
855
856 auto staMobility = CreateObject<ConstantPositionMobilityModel>();
857 phySta->SetMobility(staMobility);
858 staDev->SetPhy(phySta);
859 staDev->SetStandard(WIFI_STANDARD_80211ax);
860 staDev->SetHeConfiguration(CreateObject<HeConfiguration>());
861 staNode->AggregateObject(staMobility);
862 staNode->AddDevice(staDev);
863 m_phyStas.push_back(phySta);
864 }
865
866 // non-HE STA
867 auto nonHeStaNode = CreateObject<Node>();
868 auto nonHeStaDev = CreateObject<WifiNetDevice>();
869 m_nonHePhySta = CreateObject<SpectrumWifiPhy>();
870 auto nonHeStaInterferenceHelper = CreateObject<InterferenceHelper>();
871 m_nonHePhySta->SetInterferenceHelper(nonHeStaInterferenceHelper);
872 auto nonHeStaErrorModel = CreateObject<NistErrorRateModel>();
873 m_nonHePhySta->SetErrorRateModel(nonHeStaErrorModel);
874 m_nonHePhySta->SetDevice(nonHeStaDev);
875 m_nonHePhySta->AddChannel(spectrumChannel);
878 WifiPhy::ChannelTuple{apChannelNum, apBw, WIFI_PHY_BAND_5GHZ, 0});
879 auto nonHeStaMobility = CreateObject<ConstantPositionMobilityModel>();
880 m_nonHePhySta->SetMobility(nonHeStaMobility);
881 nonHeStaDev->SetPhy(m_nonHePhySta);
882 nonHeStaDev->SetStandard(WIFI_STANDARD_80211ac);
883 m_nonHePhySta->AssignStreams(streamNumber);
884 nonHeStaNode->AggregateObject(nonHeStaMobility);
885 nonHeStaNode->AddDevice(nonHeStaDev);
886}
887
888void
890{
891 m_phyAp->Dispose();
892 m_phyAp = nullptr;
893 for (auto& phySta : m_phyStas)
894 {
895 phySta->Dispose();
896 phySta = nullptr;
897 }
898 m_phyStas.clear();
899}
900
901void
903{
904 // Fake transmission of a MU-RTS frame preceding the CTS responses
907 this,
908 *std::max_element(m_bwPerSta.cbegin(), m_bwPerSta.cend()));
909
910 std::size_t index = 1;
911 for (auto& phySta : m_phyStas)
912 {
913 // Transmit CTS responses over their operating bandwidth with 1 nanosecond delay between
914 // each other
915 const auto delay = index * NanoSeconds(1.0);
916 Simulator::Schedule(Seconds(0.0) + delay,
918 this,
919 phySta,
920 m_bwPerSta.at(index - 1));
921 index++;
922 }
923
924 // Verify successful reception of the CTS frames: since multiple copies are sent
925 // simultaneously, a single CTS frame should be forwarded up to the MAC.
927
930}
931
939{
940 public:
942};
943
945 : TestSuite("wifi-non-ht-dup", UNIT)
946{
982 5210,
983 0,
984 {{WIFI_STANDARD_80211a, 5180, 0},
985 {WIFI_STANDARD_80211n, 5200, 0},
986 {WIFI_STANDARD_80211ac, 5230, 0}}),
988 /* same channel map and test scenario as previously but inject interference on channel 40 */
990 5210,
991 0,
992 {{WIFI_STANDARD_80211a, 5180, 0},
993 {WIFI_STANDARD_80211n, 5200, 0},
994 {WIFI_STANDARD_80211ac, 5230, 0}},
995 {false, true, false, false}),
997
998 /* test PHY reception of multiple CTS responses following a MU-RTS */
999 /* 4 STAs operating on 20 MHz */
1001 /* 4 STAs operating on 40 MHz */
1003 /* 4 STAs operating on 80 MHz */
1005 /* 4 STAs operating on 160 MHz */
1007 /* 4 STAs operating on different bandwidths: 160, 80, 40 and 20 MHz */
1009}
1010
HE PHY used for testing MU-RTS/CTS.
void SetPreviousTxPpduUid(uint64_t uid)
Set the previous TX PPDU UID counter.
void SetMuRtsTxVector(const WifiTxVector &muRtsTxVector)
Set the TXVECTOR of the previously transmitted MU-RTS.
~MuRtsCtsHePhy() override
Spectrum PHY used for testing MU-RTS/CTS.
void DoDispose() override
Destructor implementation.
Ptr< MuRtsCtsHePhy > m_muRtsCtsHePhy
Pointer to HE PHY instance used for MU-RTS/CTS PHY test.
void SetPpduUid(uint64_t uid)
Set the global PPDU UID counter.
void SetMuRtsTxVector(const WifiTxVector &muRtsTxVector)
Set the TXVECTOR of the previously transmitted MU-RTS.
void DoInitialize() override
Initialize() implementation.
static TypeId GetTypeId()
Get the type ID.
test PHY reception of multiple CTS frames as a response to a MU-RTS frame.
void FakePreviousMuRts(uint16_t bw)
Function called to fake the transmission of a MU-RTS.
Ptr< SpectrumWifiPhy > m_nonHePhySta
non-HE STA PHY
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void RxCtsFailure(Ptr< const WifiPsdu > psdu)
CTS RX failure function.
TestMultipleCtsResponsesFromMuRts(const std::vector< uint16_t > &bwPerSta)
Constructor.
std::vector< uint16_t > m_bwPerSta
Bandwidth per STA in MHz.
std::size_t m_countRxCtsFailure
count the number of unsuccessfully received CTS frames
void RxCtsSuccess(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
CTS RX success function.
std::vector< Ptr< MuRtsCtsSpectrumWifiPhy > > m_phyStas
STAs PHYs.
std::size_t m_countRxCtsSuccess
count the number of successfully received CTS frames
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
void CheckResults(std::size_t expectedRxCtsSuccess, std::size_t expectedRxCtsFailure)
Check the results.
Ptr< MuRtsCtsSpectrumWifiPhy > m_phyAp
AP PHY.
double m_stasTxPowerDbm
TX power in dBm configured for the STAs.
void TxNonHtDuplicateCts(Ptr< SpectrumWifiPhy > phy, uint16_t bw)
Function called to trigger a CTS frame sent by a STA using non-HT duplicate.
non-HT duplicate PHY reception test The test consists in an AP sending a single non-HT duplicate PPDU...
void GenerateInterference(Ptr< WaveformGenerator > interferer, Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
std::vector< bool > m_per20MhzInterference
flags per 20 MHz subchannel whether an interference should be generated on that subchannel
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void ResetResults()
Reset the results.
std::vector< Ptr< SpectrumWifiPhy > > m_phyStas
PHYs of STAs.
void RxFailure(std::size_t index, Ptr< const WifiPsdu > psdu)
Receive failure function.
std::vector< uint32_t > m_countRxFailureStas
count RX failure for STAs
void SendNonHtDuplicatePpdu(uint16_t channelWidth)
Send non-HT duplicate PPDU function.
StasParams m_stasParams
the parameters of the STAs
std::vector< std::tuple< WifiStandard, uint16_t, uint8_t > > StasParams
A vector containing parameters per STA: the standard, the center frequency and the P20 index.
void CheckResults(std::size_t index, uint32_t expectedRxSuccess, uint32_t expectedRxFailure)
Check the results.
void StopInterference(Ptr< WaveformGenerator > interferer)
Stop interference function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
TestNonHtDuplicatePhyReception(WifiStandard apStandard, uint16_t apFrequency, uint8_t apP20Index, StasParams stasParams, std::vector< bool > per20MhzInterference={})
Constructor.
void RxSuccess(std::size_t index, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function.
WifiStandard m_apStandard
the standard to use for the AP
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
uint8_t m_apP20Index
the index of the primary 20 MHz channel of the AP
void DoRun() override
Implementation to actually run this TestCase.
std::vector< uint32_t > m_countRxSuccessStas
count RX success for STAs
std::vector< Ptr< WaveformGenerator > > m_phyInterferers
PHYs of interferers (1 interferer per 20 MHz subchannel)
uint16_t m_apFrequency
the center frequency of the AP (in MHz)
wifi non-HT duplicate Test Suite
AttributeValue implementation for Boolean.
Definition: boolean.h:37
PHY entity for HE (11ax)
Definition: he-phy.h:68
std::optional< WifiTxVector > m_currentTxVector
If the STA is an AP STA, this holds the TXVECTOR of the PPDU that has been sent.
Definition: he-phy.h:572
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
Definition: he-phy.h:561
void Dispose()
Dispose of this Object.
Definition: object.cc:219
static WifiMode GetOfdmRate54Mbps()
Return a WifiMode for OFDM at 54 Mbps.
static WifiMode GetOfdmRate24Mbps()
Return a WifiMode for OFDM at 24 Mbps.
void SetOwner(Ptr< WifiPhy > wifiPhy)
Set the WifiPhy owning this PHY entity.
Definition: phy-entity.cc:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
802.11 PHY layer model
void SetDevice(const Ptr< WifiNetDevice > device) override
Sets the device this PHY is associated with.
void DoInitialize() override
Initialize() implementation.
void AddChannel(const Ptr< SpectrumChannel > channel, const FrequencyRange &freqRange=WHOLE_WIFI_SPECTRUM)
Attach a SpectrumChannel to use for a given frequency range.
void DoDispose() override
Destructor implementation.
encapsulates test code
Definition: test.h:1060
@ QUICK
Fast test.
Definition: test.h:1065
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Implements the IEEE 802.11 MAC header.
void SetNoMoreFragments()
Un-set the More Fragment bit in the Frame Control Field.
void SetDsNotFrom()
Un-set the From DS bit in the Frame Control field.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
void SetDsNotTo()
Un-set the To DS bit in the Frame Control field.
void SetNoRetry()
Un-set the Retry bit in the Frame Control field.
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition: wifi-phy.cc:633
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument.
Definition: wifi-phy.cc:1709
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:641
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1035
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1023
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:457
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:950
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1496
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1269
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:1082
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1005
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1249
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:621
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:451
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:872
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1017
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: wifi-phy.cc:2180
static ConstIterator FindFirst(uint8_t number, uint16_t frequency, uint16_t width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first channel matching the specified parameters.
uint16_t GetPrimaryChannelCenterFrequency(uint16_t primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetTriggerResponding(bool triggerResponding)
Set the Trigger Responding parameter to the given value.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition: test.h:510
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1372
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_PREAMBLE_LONG
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:46
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:702
std::vector< BandInfo > Bands
Container of BandInfo.
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:40
@ WIFI_MAC_CTL_CTS
@ WIFI_MAC_QOSDATA
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
The building block of a SpectrumModel.
double fc
center frequency
double fl
lower limit of subband
double fh
upper limit of subband
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:70
double rssi
RSSI in dBm.
Definition: phy-entity.h:72
static WifiNonHtDuplicateTestSuite wifiNonHtDuplicateTestSuite
the test suite
constexpr uint32_t DEFAULT_FREQUENCY