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>();
429 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
430 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
431 auto apErrorModel = CreateObject<NistErrorRateModel>();
432 m_phyAp->SetErrorRateModel(apErrorModel);
433 m_phyAp->SetDevice(apDev);
434 m_phyAp->SetChannel(spectrumChannel);
436 auto apMobility = CreateObject<ConstantPositionMobilityModel>();
437 m_phyAp->SetMobility(apMobility);
438 apDev->SetPhy(m_phyAp);
439 apNode->AggregateObject(apMobility);
440 apNode->AddDevice(apDev);
441
442 for (const auto& staParams : m_stasParams)
443 {
444 auto staNode = CreateObject<Node>();
445 auto staDev = CreateObject<WifiNetDevice>();
446 auto staPhy = CreateObject<SpectrumWifiPhy>();
447 staPhy->CreateWifiSpectrumPhyInterface(staDev);
448 auto sta1InterferenceHelper = CreateObject<InterferenceHelper>();
449 staPhy->SetInterferenceHelper(sta1InterferenceHelper);
450 auto sta1ErrorModel = CreateObject<NistErrorRateModel>();
451 staPhy->SetErrorRateModel(sta1ErrorModel);
452 staPhy->SetDevice(staDev);
453 staPhy->SetChannel(spectrumChannel);
454 staPhy->ConfigureStandard(std::get<0>(staParams));
455 staPhy->SetReceiveOkCallback(
457 staPhy->SetReceiveErrorCallback(
459 auto staMobility = CreateObject<ConstantPositionMobilityModel>();
460 staPhy->SetMobility(staMobility);
461 staDev->SetPhy(staPhy);
462 staNode->AggregateObject(staMobility);
463 staNode->AddDevice(staDev);
464 m_phyStas.push_back(staPhy);
465 m_countRxSuccessStas.push_back(0);
466 m_countRxFailureStas.push_back(0);
467 }
468
469 if (!m_per20MhzInterference.empty())
470 {
471 [[maybe_unused]] auto [channelNum, centerFreq, apChannelWidth, type, phyBand] =
474 0,
477 NS_ASSERT(m_per20MhzInterference.size() == (apChannelWidth / 20));
478 for (std::size_t i = 0; i < m_per20MhzInterference.size(); ++i)
479 {
480 auto interfererNode = CreateObject<Node>();
481 auto interfererDev = CreateObject<NonCommunicatingNetDevice>();
482 auto phyInterferer = CreateObject<WaveformGenerator>();
483 phyInterferer->SetDevice(interfererDev);
484 phyInterferer->SetChannel(spectrumChannel);
485 phyInterferer->SetDutyCycle(1);
486 interfererNode->AddDevice(interfererDev);
487 m_phyInterferers.push_back(phyInterferer);
488 }
489 }
490}
491
492void
494{
495 m_phyAp->Dispose();
496 m_phyAp = nullptr;
497 for (auto phySta : m_phyStas)
498 {
499 phySta->Dispose();
500 phySta = nullptr;
501 }
502 for (auto phyInterferer : m_phyInterferers)
503 {
504 phyInterferer->Dispose();
505 phyInterferer = nullptr;
506 }
507}
508
509void
511{
514 int64_t streamNumber = 0;
515 m_phyAp->AssignStreams(streamNumber);
516 for (auto phySta : m_phyStas)
517 {
518 phySta->AssignStreams(streamNumber);
519 }
520
521 [[maybe_unused]] auto [apChannelNum, centerFreq, apChannelWidth, type, phyBand] =
524 0,
528 WifiPhy::ChannelTuple{apChannelNum, apChannelWidth, WIFI_PHY_BAND_5GHZ, m_apP20Index});
529
530 auto index = 0;
531 for (const auto& [staStandard, staFrequency, staP20Index] : m_stasParams)
532 {
533 [[maybe_unused]] auto [staChannelNum, centerFreq, staChannelWidth, type, phyBand] =
535 staFrequency,
536 0,
537 staStandard,
539 m_phyStas.at(index++)->SetOperatingChannel(
540 WifiPhy::ChannelTuple{staChannelNum, staChannelWidth, WIFI_PHY_BAND_5GHZ, staP20Index});
541 }
542
543 index = 0;
544 const auto minApCenterFrequency =
545 m_phyAp->GetFrequency() - (m_phyAp->GetChannelWidth() / 2) + (20 / 2);
546 for (auto channelWidth = 20; channelWidth <= apChannelWidth; channelWidth *= 2, ++index)
547 {
548 if (!m_phyInterferers.empty())
549 {
550 for (std::size_t i = 0; i < m_phyInterferers.size(); ++i)
551 {
552 if (!m_per20MhzInterference.at(i))
553 {
554 continue;
555 }
556 BandInfo bandInfo;
557 bandInfo.fc = (minApCenterFrequency + (i * 20)) * 1e6;
558 bandInfo.fl = bandInfo.fc - (5 * 1e6);
559 bandInfo.fh = bandInfo.fc + (5 * 1e6);
560 Bands bands;
561 bands.push_back(bandInfo);
562 auto spectrumInterference = Create<SpectrumModel>(bands);
563 auto interferencePsd = Create<SpectrumValue>(spectrumInterference);
564 auto interferencePower = 0.005; // in watts (designed to make PHY headers reception
565 // successful but payload reception fail)
566 *interferencePsd = interferencePower / 10e6;
569 this,
570 m_phyInterferers.at(i),
571 interferencePsd,
572 Seconds(0.5));
573 }
574 }
575 const auto apCenterFreq =
577 const auto apMinFreq = apCenterFreq - (channelWidth / 2);
578 const auto apMaxFreq = apCenterFreq + (channelWidth / 2);
579 Simulator::Schedule(Seconds(index + 0.1),
581 this,
582 channelWidth);
583 for (std::size_t i = 0; i < m_stasParams.size(); ++i)
584 {
585 const auto p20Width = 20;
586 const auto staP20Freq =
587 m_phyStas.at(i)->GetOperatingChannel().GetPrimaryChannelCenterFrequency(p20Width);
588 const auto staP20MinFreq = staP20Freq - (p20Width / 2);
589 const auto staP20MaxFreq = staP20Freq + (p20Width / 2);
590 bool expectRx = (staP20MinFreq >= apMinFreq && staP20MaxFreq <= apMaxFreq);
591 bool expectSuccess = true;
592 if (!m_per20MhzInterference.empty())
593 {
594 const auto index20MhzSubBand = ((staP20Freq - minApCenterFrequency) / 20);
595 expectSuccess = !m_per20MhzInterference.at(index20MhzSubBand);
596 }
597 Simulator::Schedule(Seconds(index + 0.5),
599 this,
600 i,
601 expectRx ? expectSuccess : 0,
602 expectRx ? !expectSuccess : 0);
603 }
604 Simulator::Schedule(Seconds(index + 0.5),
606 this);
607 }
608
611}
612
624{
625 public:
630 TestMultipleCtsResponsesFromMuRts(const std::vector<uint16_t>& bwPerSta);
631
632 private:
633 void DoSetup() override;
634 void DoTeardown() override;
635 void DoRun() override;
636
642 void FakePreviousMuRts(uint16_t bw);
643
650 void TxNonHtDuplicateCts(Ptr<SpectrumWifiPhy> phy, uint16_t bw);
651
660 RxSignalInfo rxSignalInfo,
661 WifiTxVector txVector,
662 std::vector<bool> statusPerMpdu);
663
669
675 void CheckResults(std::size_t expectedRxCtsSuccess, std::size_t expectedRxCtsFailure);
676
678 std::vector<Ptr<MuRtsCtsSpectrumWifiPhy>> m_phyStas;
679
680 std::vector<uint16_t> m_bwPerSta;
681
684
686};
687
689 const std::vector<uint16_t>& bwPerSta)
690 : TestCase{"test PHY reception of multiple CTS frames following a MU-RTS frame"},
691 m_bwPerSta{bwPerSta},
692 m_countRxCtsSuccess{0},
693 m_countRxCtsFailure{0},
694 m_stasTxPowerDbm(10.0)
695{
696}
697
698void
700{
701 NS_LOG_FUNCTION(this << bw);
702
703 WifiTxVector txVector;
704 txVector.SetChannelWidth(bw); // only the channel width matters for this test
705
706 // set the TXVECTOR and the UID of the previously transmitted MU-RTS in the AP PHY
707 m_phyAp->SetMuRtsTxVector(txVector);
709
710 // set the UID of the previously received MU-RTS in the STAs PHYs
711 for (auto& phySta : m_phyStas)
712 {
713 phySta->SetPpduUid(0);
714 }
715}
716
717void
719{
720 NS_LOG_FUNCTION(this << phy << bw);
721
722 WifiTxVector txVector =
723 WifiTxVector(OfdmPhy::GetOfdmRate54Mbps(), // use less robust modulation for test purpose
724 0,
726 800,
727 1,
728 1,
729 0,
730 bw,
731 false,
732 false);
733 txVector.SetTriggerResponding(true);
734
735 WifiMacHeader hdr;
737 hdr.SetDsNotFrom();
738 hdr.SetDsNotTo();
739 hdr.SetNoMoreFragments();
740 hdr.SetNoRetry();
741
742 auto pkt = Create<Packet>();
743 auto mpdu = Create<WifiMpdu>(pkt, hdr);
744 auto psdu = Create<WifiPsdu>(mpdu, false);
745
746 phy->Send(psdu, txVector);
747}
748
749void
751 RxSignalInfo rxSignalInfo,
752 WifiTxVector txVector,
753 std::vector<bool> /*statusPerMpdu*/)
754{
755 NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
756 NS_TEST_EXPECT_MSG_EQ_TOL(rxSignalInfo.rssi,
758 0.1,
759 "RX power is not correct!");
761}
762
763void
765{
766 NS_LOG_FUNCTION(this << *psdu);
768}
769
770void
771TestMultipleCtsResponsesFromMuRts::CheckResults(std::size_t expectedRxCtsSuccess,
772 std::size_t expectedRxCtsFailure)
773{
775 expectedRxCtsSuccess,
776 "The number of successfully received CTS frames by AP is not correct!");
778 expectedRxCtsFailure,
779 "The number of unsuccessfully received CTS frames by AP is not correct!");
780}
781
782void
784{
787 int64_t streamNumber = 0;
788
789 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
790 auto lossModel = CreateObject<FriisPropagationLossModel>();
791 lossModel->SetFrequency(DEFAULT_FREQUENCY * 1e6);
792 spectrumChannel->AddPropagationLossModel(lossModel);
793 auto delayModel = CreateObject<ConstantSpeedPropagationDelayModel>();
794 spectrumChannel->SetPropagationDelayModel(delayModel);
795
796 auto apNode = CreateObject<Node>();
797 auto apDev = CreateObject<WifiNetDevice>();
798 auto apMac = CreateObject<ApWifiMac>();
799 apMac->SetAttribute("BeaconGeneration", BooleanValue(false));
800 apDev->SetMac(apMac);
801 m_phyAp = CreateObject<MuRtsCtsSpectrumWifiPhy>();
803 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
804 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
805 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
806 auto apErrorModel = CreateObject<NistErrorRateModel>();
807 m_phyAp->SetErrorRateModel(apErrorModel);
808 m_phyAp->SetDevice(apDev);
809 m_phyAp->SetChannel(spectrumChannel);
811 m_phyAp->AssignStreams(streamNumber);
812
817
818 const auto apBw = *std::max_element(m_bwPerSta.cbegin(), m_bwPerSta.cend());
819 auto channelNum = std::get<0>(
821
823
824 auto apMobility = CreateObject<ConstantPositionMobilityModel>();
825 m_phyAp->SetMobility(apMobility);
826 apDev->SetPhy(m_phyAp);
827 apDev->SetStandard(WIFI_STANDARD_80211ax);
828 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
829 apMac->SetWifiPhys({m_phyAp});
830 apNode->AggregateObject(apMobility);
831 apNode->AddDevice(apDev);
832
833 for (std::size_t i = 0; i < m_bwPerSta.size(); ++i)
834 {
835 auto staNode = CreateObject<Node>();
836 auto staDev = CreateObject<WifiNetDevice>();
837 auto phySta = CreateObject<MuRtsCtsSpectrumWifiPhy>();
838 phySta->CreateWifiSpectrumPhyInterface(staDev);
839 auto staInterferenceHelper = CreateObject<InterferenceHelper>();
840 phySta->SetInterferenceHelper(staInterferenceHelper);
841 auto staErrorModel = CreateObject<NistErrorRateModel>();
842 phySta->SetErrorRateModel(staErrorModel);
843 phySta->SetDevice(staDev);
844 phySta->SetChannel(spectrumChannel);
845 phySta->ConfigureStandard(WIFI_STANDARD_80211ax);
846 phySta->AssignStreams(streamNumber);
847 phySta->SetTxPowerStart(m_stasTxPowerDbm);
848 phySta->SetTxPowerEnd(m_stasTxPowerDbm);
849
850 channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0,
851 0,
852 m_bwPerSta.at(i),
855
856 phySta->SetOperatingChannel(
858
859 auto staMobility = CreateObject<ConstantPositionMobilityModel>();
860 phySta->SetMobility(staMobility);
861 staDev->SetPhy(phySta);
862 staDev->SetStandard(WIFI_STANDARD_80211ax);
863 staDev->SetHeConfiguration(CreateObject<HeConfiguration>());
864 staNode->AggregateObject(staMobility);
865 staNode->AddDevice(staDev);
866 m_phyStas.push_back(phySta);
867 }
868}
869
870void
872{
873 m_phyAp->Dispose();
874 m_phyAp = nullptr;
875 for (auto& phySta : m_phyStas)
876 {
877 phySta->Dispose();
878 phySta = nullptr;
879 }
880 m_phyStas.clear();
881}
882
883void
885{
886 // Fake transmission of a MU-RTS frame preceding the CTS responses
889 this,
890 *std::max_element(m_bwPerSta.cbegin(), m_bwPerSta.cend()));
891
892 std::size_t index = 1;
893 for (auto& phySta : m_phyStas)
894 {
895 // Transmit CTS responses over their operating bandwidth with 1 nanosecond delay between
896 // each other
897 const auto delay = index * NanoSeconds(1.0);
898 Simulator::Schedule(Seconds(0.0) + delay,
900 this,
901 phySta,
902 m_bwPerSta.at(index - 1));
903 index++;
904 }
905
906 // Verify successful reception of the CTS frames: since multiple copies are sent
907 // simultaneously, a single CTS frame should be forwarded up to the MAC.
909
912}
913
921{
922 public:
924};
925
927 : TestSuite("wifi-non-ht-dup", UNIT)
928{
964 5210,
965 0,
966 {{WIFI_STANDARD_80211a, 5180, 0},
967 {WIFI_STANDARD_80211n, 5200, 0},
968 {WIFI_STANDARD_80211ac, 5230, 0}}),
970 /* same channel map and test scenario as previously but inject interference on channel 40 */
972 5210,
973 0,
974 {{WIFI_STANDARD_80211a, 5180, 0},
975 {WIFI_STANDARD_80211n, 5200, 0},
976 {WIFI_STANDARD_80211ac, 5230, 0}},
977 {false, true, false, false}),
979
980 /* test PHY reception of multiple CTS responses following a MU-RTS */
981 /* 4 STAs operating on 20 MHz */
983 /* 4 STAs operating on 40 MHz */
985 /* 4 STAs operating on 80 MHz */
987 /* 4 STAs operating on 160 MHz */
989 /* 4 STAs operating on different bandwidths: 160, 80, 40 and 20 MHz */
991}
992
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.
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:529
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
Definition: he-phy.h:518
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 DoInitialize() override
Initialize() implementation.
void SetChannel(const Ptr< SpectrumChannel > channel)
Set the SpectrumChannel this SpectrumWifiPhy is to be connected to.
void DoDispose() override
Destructor implementation.
void CreateWifiSpectrumPhyInterface(Ptr< NetDevice > device)
Method to encapsulate the creation of the WifiSpectrumPhyInterface object (used to bind the WifiSpect...
encapsulates test code
Definition: test.h:1060
@ QUICK
Fast test.
Definition: test.h:1065
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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:624
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:1693
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:632
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1026
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1014
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:448
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:941
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1480
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1244
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:1062
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:996
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1224
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:600
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:612
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:442
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:870
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1008
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: wifi-phy.cc:2184
static ConstIterator FindFirst(uint8_t number, uint16_t frequency, uint16_t width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first channel matching the specified parameters.
uint16_t GetPrimaryChannelCenterFrequency(uint16_t primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
This 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:707
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
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
#define SU_STA_ID
Definition: wifi-mode.h:34
static WifiNonHtDuplicateTestSuite wifiNonHtDuplicateTestSuite
the test suite
constexpr uint32_t DEFAULT_FREQUENCY