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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7 */
8
9#include "ns3/ap-wifi-mac.h"
10#include "ns3/boolean.h"
11#include "ns3/constant-position-mobility-model.h"
12#include "ns3/he-configuration.h"
13#include "ns3/he-phy.h"
14#include "ns3/interference-helper.h"
15#include "ns3/log.h"
16#include "ns3/mobility-helper.h"
17#include "ns3/multi-model-spectrum-channel.h"
18#include "ns3/nist-error-rate-model.h"
19#include "ns3/node.h"
20#include "ns3/non-communicating-net-device.h"
21#include "ns3/pointer.h"
22#include "ns3/rng-seed-manager.h"
23#include "ns3/simulator.h"
24#include "ns3/spectrum-wifi-helper.h"
25#include "ns3/spectrum-wifi-phy.h"
26#include "ns3/sta-wifi-mac.h"
27#include "ns3/string.h"
28#include "ns3/test.h"
29#include "ns3/txop.h"
30#include "ns3/waveform-generator.h"
31#include "ns3/wifi-mac-header.h"
32#include "ns3/wifi-net-device.h"
33#include "ns3/wifi-psdu.h"
34#include "ns3/wifi-spectrum-signal-parameters.h"
35#include "ns3/wifi-spectrum-value-helper.h"
36#include "ns3/wifi-utils.h"
37
38#include <vector>
39
40using namespace ns3;
41
42NS_LOG_COMPONENT_DEFINE("WifiNonHtDuplicateTest");
43
44constexpr MHz_u DEFAULT_FREQUENCY{5180};
45
46/**
47 * HE PHY used for testing MU-RTS/CTS.
48 */
49class MuRtsCtsHePhy : public HePhy
50{
51 public:
53 ~MuRtsCtsHePhy() override;
54
55 /**
56 * Set the previous TX PPDU UID counter.
57 *
58 * @param uid the value to which the previous TX PPDU UID counter should be set
59 */
60 void SetPreviousTxPpduUid(uint64_t uid);
61
62 /**
63 * Set the TXVECTOR of the previously transmitted MU-RTS.
64 *
65 * @param muRtsTxVector the TXVECTOR used to transmit MU-RTS trigger frame
66 */
67 void SetMuRtsTxVector(const WifiTxVector& muRtsTxVector);
68
69 // end of class MuRtsCtsHePhy
70};
71
77
82
83void
85{
86 NS_LOG_FUNCTION(this << uid);
88}
89
90void
92{
93 NS_LOG_FUNCTION(this << muRtsTxVector);
94 m_currentTxVector = muRtsTxVector;
95}
96
97/**
98 * Spectrum PHY used for testing MU-RTS/CTS.
99 */
101{
102 public:
103 /**
104 * @brief Get the type ID.
105 * @return the object TypeId
106 */
107 static TypeId GetTypeId();
108
110 ~MuRtsCtsSpectrumWifiPhy() override;
111
112 void DoInitialize() override;
113 void DoDispose() override;
114
115 /**
116 * Set the global PPDU UID counter.
117 *
118 * @param uid the value to which the global PPDU UID counter should be set
119 */
120 void SetPpduUid(uint64_t uid);
121
122 /**
123 * Set the TXVECTOR of the previously transmitted MU-RTS.
124 *
125 * @param muRtsTxVector the TXVECTOR used to transmit MU-RTS trigger frame
126 */
127 void SetMuRtsTxVector(const WifiTxVector& muRtsTxVector);
128
129 private:
130 Ptr<MuRtsCtsHePhy> m_muRtsCtsHePhy; ///< Pointer to HE PHY instance used for MU-RTS/CTS PHY test
131
132 // end of class MuRtsCtsSpectrumWifiPhy
133};
134
135TypeId
137{
138 static TypeId tid =
139 TypeId("ns3::MuRtsCtsSpectrumWifiPhy").SetParent<SpectrumWifiPhy>().SetGroupName("Wifi");
140 return tid;
141}
142
150
155
156void
158{
159 // Replace HE PHY instance with test instance
162}
163
164void
170
171void
178
179void
181{
182 NS_LOG_FUNCTION(this << muRtsTxVector);
183 m_muRtsCtsHePhy->SetMuRtsTxVector(muRtsTxVector);
184}
185
186/**
187 * @ingroup wifi-test
188 * @ingroup tests
189 *
190 * @brief non-HT duplicate PHY reception test
191 * The test consists in an AP sending a single non-HT duplicate PPDU
192 * of a given channel width (multiple of 20 MHz) over a spectrum
193 * channel and it checks whether the STAs attached to the channel
194 * receive the PPDU. If an interference is injected on a given 20 MHz
195 * subchannel, the payload reception should fail, otherwise it should succeed.
196 */
198{
199 public:
200 /// A vector containing parameters per STA: the standard, the center frequency and the P20 index
201 using StasParams = std::vector<std::tuple<WifiStandard, MHz_u, uint8_t>>;
202
203 /**
204 * Constructor
205 * @param apStandard the standard to use for the AP
206 * @param apFrequency the center frequency of the AP
207 * @param apP20Index the index of the primary 20 MHz channel of the AP
208 * @param stasParams the parameters of the STAs (\see StasParams)
209 * @param per20MhzInterference flags per 20 MHz subchannel whether an interference should be
210 * generated on that subchannel. An empty vector means that the test will not generate any
211 * interference.
212 */
214 MHz_u apFrequency,
215 uint8_t apP20Index,
216 StasParams stasParams,
217 std::vector<bool> per20MhzInterference = {});
218
219 private:
220 void DoSetup() override;
221 void DoTeardown() override;
222 void DoRun() override;
223
224 /**
225 * Receive success function
226 * @param index index of the RX STA
227 * @param psdu the PSDU
228 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
229 * @param txVector the transmit vector
230 * @param statusPerMpdu reception status per MPDU
231 */
232 void RxSuccess(std::size_t index,
234 RxSignalInfo rxSignalInfo,
235 const WifiTxVector& txVector,
236 const std::vector<bool>& statusPerMpdu);
237
238 /**
239 * Receive failure function
240 * @param index index of the RX STA
241 * @param psdu the PSDU
242 */
243 void RxFailure(std::size_t index, Ptr<const WifiPsdu> psdu);
244
245 /**
246 * Check the results
247 * @param index index of the RX STA
248 * @param expectedRxSuccess the expected number of RX success
249 * @param expectedRxFailure the expected number of RX failures
250 */
251 void CheckResults(std::size_t index, uint32_t expectedRxSuccess, uint32_t expectedRxFailure);
252
253 /**
254 * Reset the results
255 */
256 void ResetResults();
257
258 /**
259 * Send non-HT duplicate PPDU function
260 * @param channelWidth the channel width to use to transmit the non-HT PPDU
261 */
262 void SendNonHtDuplicatePpdu(MHz_u channelWidth);
263
264 /**
265 * Generate interference function
266 * @param interferer the PHY of the interferer to use to generate the signal
267 * @param interferencePsd the PSD of the interference to be generated
268 * @param duration the duration of the interference
269 */
271 Ptr<SpectrumValue> interferencePsd,
272 Time duration);
273 /**
274 * Stop interference function
275 * @param interferer the PHY of the interferer that was used to generate the signal
276 */
278
279 WifiStandard m_apStandard; ///< the standard to use for the AP
280 MHz_u m_apFrequency; ///< the center frequency of the AP
281 uint8_t m_apP20Index; ///< the index of the primary 20 MHz channel of the AP
282 StasParams m_stasParams; ///< the parameters of the STAs
283 std::vector<bool>
284 m_per20MhzInterference; ///< flags per 20 MHz subchannel whether an interference should be
285 ///< generated on that subchannel
286
287 std::vector<uint32_t> m_countRxSuccessStas; ///< count RX success for STAs
288 std::vector<uint32_t> m_countRxFailureStas; ///< count RX failure for STAs
289
291 std::vector<Ptr<SpectrumWifiPhy>> m_phyStas; ///< PHYs of STAs
292
293 std::vector<Ptr<WaveformGenerator>>
294 m_phyInterferers; ///< PHYs of interferers (1 interferer per 20 MHz subchannel)
295};
296
298 WifiStandard apStandard,
299 MHz_u apFrequency,
300 uint8_t apP20Index,
301 StasParams stasParams,
302 std::vector<bool> per20MhzInterference)
303 : TestCase{"non-HT duplicate PHY reception test"},
304 m_apStandard{apStandard},
305 m_apFrequency{apFrequency},
306 m_apP20Index{apP20Index},
307 m_stasParams{stasParams},
308 m_per20MhzInterference{per20MhzInterference},
309 m_countRxSuccessStas{},
310 m_countRxFailureStas{},
311 m_phyStas{}
312{
313}
314
315void
317{
318 for (auto& countRxSuccess : m_countRxSuccessStas)
319 {
320 countRxSuccess = 0;
321 }
322 for (auto& countRxFailure : m_countRxFailureStas)
323 {
324 countRxFailure = 0;
325 }
326}
327
328void
330{
331 NS_LOG_FUNCTION(this << channelWidth);
333 0,
335 NanoSeconds(800),
336 1,
337 1,
338 0,
339 channelWidth,
340 false);
341
342 auto pkt = Create<Packet>(1000);
343 WifiMacHeader hdr;
344 auto psdu = Create<WifiPsdu>(pkt, hdr);
345 m_phyAp->Send(WifiConstPsduMap({std::make_pair(SU_STA_ID, psdu)}), txVector);
346}
347
348void
350 Ptr<SpectrumValue> interferencePsd,
351 Time duration)
352{
353 NS_LOG_FUNCTION(this << interferer << duration);
354 interferer->SetTxPowerSpectralDensity(interferencePsd);
355 interferer->SetPeriod(duration);
356 interferer->Start();
357 Simulator::Schedule(duration,
359 this,
360 interferer);
361}
362
363void
365{
366 NS_LOG_FUNCTION(this << interferer);
367 interferer->Stop();
368}
369
370void
373 RxSignalInfo rxSignalInfo,
374 const WifiTxVector& txVector,
375 const std::vector<bool>& /*statusPerMpdu*/)
376{
377 NS_LOG_FUNCTION(this << index << *psdu << rxSignalInfo << txVector);
378 const auto expectedWidth =
379 std::min(m_phyAp->GetChannelWidth(), m_phyStas.at(index)->GetChannelWidth());
381 expectedWidth,
382 "Incorrect channel width in TXVECTOR");
383 m_countRxSuccessStas.at(index)++;
384}
385
386void
388{
389 NS_LOG_FUNCTION(this << index << *psdu);
390 m_countRxFailureStas.at(index)++;
391}
392
393void
395 uint32_t expectedRxSuccess,
396 uint32_t expectedRxFailure)
397{
398 NS_LOG_FUNCTION(this << index << expectedRxSuccess << expectedRxFailure);
400 expectedRxSuccess,
401 "The number of successfully received packets by STA "
402 << index << " is not correct!");
404 expectedRxFailure,
405 "The number of unsuccessfully received packets by STA "
406 << index << " is not correct!");
407}
408
409void
411{
412 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
414 lossModel->SetFrequency(MHzToHz(m_apFrequency));
415 spectrumChannel->AddPropagationLossModel(lossModel);
417 spectrumChannel->SetPropagationDelayModel(delayModel);
418
419 auto apNode = CreateObject<Node>();
420 auto apDev = CreateObject<WifiNetDevice>();
422 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
423 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
424 auto apErrorModel = CreateObject<NistErrorRateModel>();
425 m_phyAp->SetErrorRateModel(apErrorModel);
426 m_phyAp->SetDevice(apDev);
427 m_phyAp->AddChannel(spectrumChannel);
428 m_phyAp->ConfigureStandard(WIFI_STANDARD_80211ax);
430 m_phyAp->SetMobility(apMobility);
431 apDev->SetPhy(m_phyAp);
432 apNode->AggregateObject(apMobility);
433 apNode->AddDevice(apDev);
434
435 for (const auto& staParams : m_stasParams)
436 {
437 auto staNode = CreateObject<Node>();
438 auto staDev = CreateObject<WifiNetDevice>();
439 auto staPhy = CreateObject<SpectrumWifiPhy>();
440 auto sta1InterferenceHelper = CreateObject<InterferenceHelper>();
441 staPhy->SetInterferenceHelper(sta1InterferenceHelper);
442 auto sta1ErrorModel = CreateObject<NistErrorRateModel>();
443 staPhy->SetErrorRateModel(sta1ErrorModel);
444 staPhy->SetDevice(staDev);
445 staPhy->AddChannel(spectrumChannel);
446 staPhy->ConfigureStandard(std::get<0>(staParams));
447 staPhy->SetReceiveOkCallback(
449 staPhy->SetReceiveErrorCallback(
452 staPhy->SetMobility(staMobility);
453 staDev->SetPhy(staPhy);
454 staNode->AggregateObject(staMobility);
455 staNode->AddDevice(staDev);
456 m_phyStas.push_back(staPhy);
457 m_countRxSuccessStas.push_back(0);
458 m_countRxFailureStas.push_back(0);
459 }
460
461 if (!m_per20MhzInterference.empty())
462 {
463 const auto& channelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
465 MHz_u{0},
468 NS_ASSERT(m_per20MhzInterference.size() == Count20MHzSubchannels(channelInfo.width));
469 for (std::size_t i = 0; i < m_per20MhzInterference.size(); ++i)
470 {
471 auto interfererNode = CreateObject<Node>();
472 auto interfererDev = CreateObject<NonCommunicatingNetDevice>();
473 auto phyInterferer = CreateObject<WaveformGenerator>();
474 phyInterferer->SetDevice(interfererDev);
475 phyInterferer->SetChannel(spectrumChannel);
476 phyInterferer->SetDutyCycle(1);
477 interfererNode->AddDevice(interfererDev);
478 m_phyInterferers.push_back(phyInterferer);
479 }
480 }
481}
482
483void
485{
486 m_phyAp->Dispose();
487 m_phyAp = nullptr;
488 for (auto phySta : m_phyStas)
489 {
490 phySta->Dispose();
491 phySta = nullptr;
492 }
493 for (auto phyInterferer : m_phyInterferers)
494 {
495 phyInterferer->Dispose();
496 phyInterferer = nullptr;
497 }
498}
499
500void
502{
505 int64_t streamNumber = 0;
506 m_phyAp->AssignStreams(streamNumber);
507 for (auto phySta : m_phyStas)
508 {
509 phySta->AssignStreams(streamNumber);
510 }
511
512 const auto& apchannelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
514 MHz_u{0},
517 m_phyAp->SetOperatingChannel(WifiPhy::ChannelTuple{apchannelInfo.number,
518 apchannelInfo.width,
520 m_apP20Index});
521
522 auto index = 0;
523 for (const auto& [staStandard, staFrequency, staP20Index] : m_stasParams)
524 {
525 const auto& stachannelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
526 staFrequency,
527 MHz_u{0},
528 staStandard,
530 m_phyStas.at(index++)->SetOperatingChannel(WifiPhy::ChannelTuple{stachannelInfo.number,
531 stachannelInfo.width,
533 staP20Index});
534 }
535
536 index = 0;
537 const auto minApCenterFrequency =
538 m_phyAp->GetFrequency() - (m_phyAp->GetChannelWidth() / 2) + (MHz_u{20} / 2);
539 for (MHz_u channelWidth{20}; channelWidth <= apchannelInfo.width; channelWidth *= 2, ++index)
540 {
541 if (!m_phyInterferers.empty())
542 {
543 for (std::size_t i = 0; i < m_phyInterferers.size(); ++i)
544 {
545 if (!m_per20MhzInterference.at(i))
546 {
547 continue;
548 }
549 BandInfo bandInfo;
550 bandInfo.fc = MHzToHz(minApCenterFrequency + (i * MHz_u{20}));
551 bandInfo.fl = bandInfo.fc - MHzToHz(5);
552 bandInfo.fh = bandInfo.fc + MHzToHz(5);
553 Bands bands;
554 bands.push_back(bandInfo);
555 auto spectrumInterference = Create<SpectrumModel>(bands);
556 auto interferencePsd = Create<SpectrumValue>(spectrumInterference);
557 Watt_u interferencePower{0.005}; // designed to make PHY headers reception
558 // successful but payload reception fail
559 *interferencePsd = interferencePower / 10e6;
562 this,
563 m_phyInterferers.at(i),
564 interferencePsd,
565 Seconds(0.5));
566 }
567 }
568 const auto apCenterFreq =
569 m_phyAp->GetOperatingChannel().GetPrimaryChannelCenterFrequency(channelWidth);
570 const auto apMinFreq = apCenterFreq - (channelWidth / 2);
571 const auto apMaxFreq = apCenterFreq + (channelWidth / 2);
572 Simulator::Schedule(Seconds(index + 0.1),
574 this,
575 channelWidth);
576 for (std::size_t i = 0; i < m_stasParams.size(); ++i)
577 {
578 const MHz_u p20Width{20};
579 const auto staP20Freq =
580 m_phyStas.at(i)->GetOperatingChannel().GetPrimaryChannelCenterFrequency(p20Width);
581 const auto staP20MinFreq = staP20Freq - (p20Width / 2);
582 const auto staP20MaxFreq = staP20Freq + (p20Width / 2);
583 bool expectRx = (staP20MinFreq >= apMinFreq && staP20MaxFreq <= apMaxFreq);
584 bool expectSuccess = true;
585 if (!m_per20MhzInterference.empty())
586 {
587 const auto index20MhzSubBand =
588 Count20MHzSubchannels(staP20Freq - minApCenterFrequency);
589 expectSuccess = !m_per20MhzInterference.at(index20MhzSubBand);
590 }
591 Simulator::Schedule(Seconds(index + 0.5),
593 this,
594 i,
595 expectRx ? expectSuccess : 0,
596 expectRx ? !expectSuccess : 0);
597 }
598 Simulator::Schedule(Seconds(index + 0.5),
600 this);
601 }
602
605}
606
607/**
608 * @ingroup wifi-test
609 * @ingroup tests
610 *
611 * @brief test PHY reception of multiple CTS frames as a response to a MU-RTS frame.
612 * The test is checking whether the reception of multiple identical CTS frames as a response to a
613 * MU-RTS frame is successfully received by the AP PHY and that only a single CTS frame is forwarded
614 * up to the MAC. Since the test is focusing on the PHY reception of multiple CTS response, the
615 * transmission of the MU-RTS frame is faked. The test also checks the correct channel width is
616 * passed to the MAC layer through the TXVECTOR. The test also consider the case some STAs do not
617 * respond to verify the largest channel width of the successfully CTS responses is reported to the
618 * MAC.
619 */
621{
622 public:
623 /// Information about CTS responses to expect in the test
625 {
626 MHz_u bw{20}; ///< the width of the CTS response
627 bool discard{false}; ///< flag whether the CTS response shall be discarded
628 };
629
630 /**
631 * Constructor
632 * @param ctsTxInfosPerSta the information about CTS responses to generate
633 */
634 TestMultipleCtsResponsesFromMuRts(const std::vector<CtsTxInfos>& ctsTxInfosPerSta);
635
636 private:
637 void DoSetup() override;
638 void DoTeardown() override;
639 void DoRun() override;
640
641 /**
642 * Function called to fake the transmission of a MU-RTS.
643 */
644 void FakePreviousMuRts();
645
646 /**
647 * Function called to trigger a CTS frame sent by a STA using non-HT duplicate.
648 *
649 * @param phyIndex the index of the TX PHY
650 */
651 void TxNonHtDuplicateCts(std::size_t phyIndex);
652
653 /**
654 * CTS RX success function
655 * @param phyIndex the index of the PHY (0 for AP)
656 * @param psdu the PSDU
657 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
658 * @param txVector the transmit vector
659 * @param statusPerMpdu reception status per MPDU
660 */
661 void RxCtsSuccess(std::size_t phyIndex,
663 RxSignalInfo rxSignalInfo,
664 const WifiTxVector& txVector,
665 const std::vector<bool>& statusPerMpdu);
666
667 /**
668 * CTS RX failure function
669 * @param phyIndex the index of the PHY (0 for AP)
670 * @param psdu the PSDU
671 */
672 void RxCtsFailure(std::size_t phyIndex, Ptr<const WifiPsdu> psdu);
673
674 /**
675 * Check the results
676 */
677 void CheckResults();
678
680 std::vector<Ptr<MuRtsCtsSpectrumWifiPhy>> m_phyStas; ///< STAs PHYs
681
682 std::vector<CtsTxInfos> m_ctsTxInfosPerSta; ///< information about CTS responses
683
684 std::size_t
685 m_countApRxCtsSuccess; ///< count the number of successfully received CTS frames by the AP
686 std::size_t
687 m_countApRxCtsFailure; ///< count the number of unsuccessfully received CTS frames by the AP
688 std::size_t m_countStaRxCtsSuccess; ///< count the number of successfully received CTS frames by
689 ///< the non-participating STA
690 std::size_t m_countStaRxCtsFailure; ///< count the number of unsuccessfully received CTS frames
691 ///< by the non-participating STA
692
693 dBm_u m_stasTxPower; ///< TX power configured for the STAs
694};
695
697 const std::vector<CtsTxInfos>& ctsTxInfosPerSta)
698 : TestCase{"test PHY reception of multiple CTS frames following a MU-RTS frame"},
699 m_ctsTxInfosPerSta{ctsTxInfosPerSta},
700 m_countApRxCtsSuccess{0},
701 m_countApRxCtsFailure{0},
702 m_countStaRxCtsSuccess{0},
703 m_countStaRxCtsFailure{0},
704 m_stasTxPower(dBm_u{10})
705{
706}
707
708void
710{
711 NS_LOG_FUNCTION(this);
712
713 const auto bw =
714 std::max_element(m_ctsTxInfosPerSta.cbegin(),
715 m_ctsTxInfosPerSta.cend(),
716 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
717 ->bw;
718 WifiTxVector txVector;
719 txVector.SetChannelWidth(bw); // only the channel width matters for this test
720
721 // set the TXVECTOR and the UID of the previously transmitted MU-RTS in the AP PHY
722 m_phyAp->SetMuRtsTxVector(txVector);
724
725 // set the UID of the previously received MU-RTS in the STAs PHYs
726 for (auto& phySta : m_phyStas)
727 {
728 phySta->SetPpduUid(0);
729 }
730}
731
732void
734{
735 const auto bw = m_ctsTxInfosPerSta.at(phyIndex).bw;
736 const auto discarded = m_ctsTxInfosPerSta.at(phyIndex).discard;
737 NS_LOG_FUNCTION(this << phyIndex << bw << discarded);
738
739 if (discarded)
740 {
741 return;
742 }
743
744 WifiTxVector txVector =
745 WifiTxVector(OfdmPhy::GetOfdmRate54Mbps(), // use less robust modulation for test purpose
746 0,
748 NanoSeconds(800),
749 1,
750 1,
751 0,
752 bw,
753 false,
754 false);
755 txVector.SetTriggerResponding(true);
756
757 WifiMacHeader hdr;
759 hdr.SetDsNotFrom();
760 hdr.SetDsNotTo();
761 hdr.SetNoMoreFragments();
762 hdr.SetNoRetry();
763
764 auto pkt = Create<Packet>();
765 auto mpdu = Create<WifiMpdu>(pkt, hdr);
766 auto psdu = Create<WifiPsdu>(mpdu, false);
767
768 m_phyStas.at(phyIndex)->Send(psdu, txVector);
769}
770
771void
774 RxSignalInfo rxSignalInfo,
775 const WifiTxVector& txVector,
776 const std::vector<bool>& /*statusPerMpdu*/)
777{
778 NS_LOG_FUNCTION(this << phyIndex << *psdu << rxSignalInfo << txVector);
779 std::vector<CtsTxInfos> successfulCtsInfos{};
780 std::copy_if(m_ctsTxInfosPerSta.cbegin(),
781 m_ctsTxInfosPerSta.cend(),
782 std::back_inserter(successfulCtsInfos),
783 [](const auto& info) { return !info.discard; });
784 const auto isAp = (phyIndex == 0);
785 if (isAp)
786 {
787 NS_TEST_EXPECT_MSG_EQ_TOL(rxSignalInfo.rssi,
788 WToDbm(DbmToW(m_stasTxPower) * successfulCtsInfos.size()),
789 0.1,
790 "RX power is not correct!");
791 }
792 auto expectedWidth =
793 std::max_element(successfulCtsInfos.cbegin(),
794 successfulCtsInfos.cend(),
795 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
796 ->bw;
797 if (!isAp)
798 {
799 expectedWidth = std::min(m_ctsTxInfosPerSta.at(phyIndex - 1).bw, expectedWidth);
800 }
802 expectedWidth,
803 "Incorrect channel width in TXVECTOR");
804 if (isAp)
805 {
807 }
808 else
809 {
811 }
812}
813
814void
816{
817 NS_LOG_FUNCTION(this << phyIndex << *psdu);
818 const auto isAp = (phyIndex == 0);
819 if (isAp)
820 {
822 }
823 else
824 {
826 }
827}
828
829void
831{
833 1,
834 "The number of successfully received CTS frames by AP is not correct!");
837 m_ctsTxInfosPerSta.size(),
838 "The number of successfully received CTS frames by non-participating STAs is not correct!");
840 0,
841 "The number of unsuccessfully received CTS frames by AP is not correct!");
843 0,
844 "The number of unsuccessfully received CTS frames by non-participating "
845 "STAs is not correct!");
846}
847
848void
850{
853 int64_t streamNumber = 0;
854
855 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
857 lossModel->SetFrequency(MHzToHz(DEFAULT_FREQUENCY));
858 spectrumChannel->AddPropagationLossModel(lossModel);
860 spectrumChannel->SetPropagationDelayModel(delayModel);
861
862 auto apNode = CreateObject<Node>();
863 auto apDev = CreateObject<WifiNetDevice>();
865 "Txop",
867 apMac->SetAttribute("BeaconGeneration", BooleanValue(false));
868 apDev->SetMac(apMac);
870 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
871 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
872 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
873 auto apErrorModel = CreateObject<NistErrorRateModel>();
874 m_phyAp->SetErrorRateModel(apErrorModel);
875 m_phyAp->SetDevice(apDev);
876 m_phyAp->AddChannel(spectrumChannel);
878 m_phyAp->AssignStreams(streamNumber);
879
884
885 const auto apBw =
886 std::max_element(m_ctsTxInfosPerSta.cbegin(),
887 m_ctsTxInfosPerSta.cend(),
888 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
889 ->bw;
890 auto apChannelNum = WifiPhyOperatingChannel::FindFirst(0,
891 MHz_u{0},
892 apBw,
895 ->number;
896
898
900 m_phyAp->SetMobility(apMobility);
901 apDev->SetPhy(m_phyAp);
902 apDev->SetStandard(WIFI_STANDARD_80211ax);
903 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
904 apMac->SetWifiPhys({m_phyAp});
905 apNode->AggregateObject(apMobility);
906 apNode->AddDevice(apDev);
907
908 for (std::size_t i = 0; i < m_ctsTxInfosPerSta.size(); ++i)
909 {
910 auto staNode = CreateObject<Node>();
911 auto staDev = CreateObject<WifiNetDevice>();
913 auto staInterferenceHelper = CreateObject<InterferenceHelper>();
914 phySta->SetInterferenceHelper(staInterferenceHelper);
915 auto staErrorModel = CreateObject<NistErrorRateModel>();
916 phySta->SetErrorRateModel(staErrorModel);
917 phySta->SetDevice(staDev);
918 phySta->AddChannel(spectrumChannel);
919 phySta->ConfigureStandard(WIFI_STANDARD_80211ax);
920 phySta->AssignStreams(streamNumber);
921 phySta->SetTxPowerStart(m_stasTxPower);
922 phySta->SetTxPowerEnd(m_stasTxPower);
923
924 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
925 MHz_u{0},
926 m_ctsTxInfosPerSta.at(i).bw,
929 ->number;
930
931 phySta->SetOperatingChannel(
933
935 phySta->SetMobility(staMobility);
936 staDev->SetPhy(phySta);
937 staDev->SetStandard(WIFI_STANDARD_80211ax);
938 staDev->SetHeConfiguration(CreateObject<HeConfiguration>());
939 staNode->AggregateObject(staMobility);
940 staNode->AddDevice(staDev);
941 m_phyStas.push_back(phySta);
942
943 // non-participating HE STA
944 auto nonParticipatingHeStaNode = CreateObject<Node>();
945 auto nonParticipatingHeStaDev = CreateObject<WifiNetDevice>();
946 auto nonParticipatingHePhySta = CreateObject<SpectrumWifiPhy>();
947 auto nonParticipatingHeStaInterferenceHelper = CreateObject<InterferenceHelper>();
948 nonParticipatingHePhySta->SetInterferenceHelper(nonParticipatingHeStaInterferenceHelper);
949 auto nonParticipatingHeStaErrorModel = CreateObject<NistErrorRateModel>();
950 nonParticipatingHePhySta->SetErrorRateModel(nonParticipatingHeStaErrorModel);
951 nonParticipatingHePhySta->SetDevice(nonParticipatingHeStaDev);
952 nonParticipatingHePhySta->AddChannel(spectrumChannel);
953 nonParticipatingHePhySta->ConfigureStandard(WIFI_STANDARD_80211ax);
954
955 nonParticipatingHePhySta->SetOperatingChannel(
957
958 auto nonParticipatingHeStaMobility = CreateObject<ConstantPositionMobilityModel>();
959 nonParticipatingHePhySta->SetMobility(nonParticipatingHeStaMobility);
960 nonParticipatingHeStaDev->SetPhy(nonParticipatingHePhySta);
961 nonParticipatingHeStaDev->SetStandard(WIFI_STANDARD_80211ax);
962 nonParticipatingHeStaDev->SetHeConfiguration(CreateObject<HeConfiguration>());
963 nonParticipatingHePhySta->AssignStreams(streamNumber);
964 nonParticipatingHeStaNode->AggregateObject(nonParticipatingHeStaMobility);
965 nonParticipatingHeStaNode->AddDevice(nonParticipatingHeStaDev);
966
967 nonParticipatingHePhySta->SetReceiveOkCallback(
969 nonParticipatingHePhySta->SetReceiveErrorCallback(
971 }
972
973 // non-HE STA
974 auto nonHeStaNode = CreateObject<Node>();
975 auto nonHeStaDev = CreateObject<WifiNetDevice>();
976 auto nonHePhySta = CreateObject<SpectrumWifiPhy>();
977 auto nonHeStaInterferenceHelper = CreateObject<InterferenceHelper>();
978 nonHePhySta->SetInterferenceHelper(nonHeStaInterferenceHelper);
979 auto nonHeStaErrorModel = CreateObject<NistErrorRateModel>();
980 nonHePhySta->SetErrorRateModel(nonHeStaErrorModel);
981 nonHePhySta->SetDevice(nonHeStaDev);
982 nonHePhySta->AddChannel(spectrumChannel);
983 nonHePhySta->ConfigureStandard(WIFI_STANDARD_80211ac);
984 nonHePhySta->SetOperatingChannel(
985 WifiPhy::ChannelTuple{apChannelNum, apBw, WIFI_PHY_BAND_5GHZ, 0});
986 auto nonHeStaMobility = CreateObject<ConstantPositionMobilityModel>();
987 nonHePhySta->SetMobility(nonHeStaMobility);
988 nonHeStaDev->SetPhy(nonHePhySta);
989 nonHeStaDev->SetStandard(WIFI_STANDARD_80211ac);
990 nonHePhySta->AssignStreams(streamNumber);
991 nonHeStaNode->AggregateObject(nonHeStaMobility);
992 nonHeStaNode->AddDevice(nonHeStaDev);
993}
994
995void
997{
998 m_phyAp->Dispose();
999 m_phyAp = nullptr;
1000 for (auto& phySta : m_phyStas)
1001 {
1002 phySta->Dispose();
1003 phySta = nullptr;
1004 }
1005 m_phyStas.clear();
1006}
1007
1008void
1010{
1011 // Fake transmission of a MU-RTS frame preceding the CTS responses
1013
1014 for (std::size_t index = 0; index < m_phyStas.size(); ++index)
1015 {
1016 // Transmit CTS responses over their operating bandwidth with 1 nanosecond delay between
1017 // each other
1018 const auto delay = (index + 1) * NanoSeconds(1);
1019 Simulator::Schedule(delay,
1021 this,
1022 index);
1023 }
1024
1025 // Verify successful reception of the CTS frames: since multiple copies are sent
1026 // simultaneously, a single CTS frame should be forwarded up to the MAC.
1028
1031}
1032
1033/**
1034 * @ingroup wifi-test
1035 * @ingroup tests
1036 *
1037 * @brief wifi non-HT duplicate Test Suite
1038 */
1040{
1041 public:
1043};
1044
1046 : TestSuite("wifi-non-ht-dup", Type::UNIT)
1047{
1048 /**
1049 * Channel map:
1050 *
1051 * | 20MHz | 20MHz | 20MHz | 20MHz |
1052 *
1053 * ┌────────┬────────┬────────┬────────┐
1054 * AP 802.11ax │CH 36(P)│ CH 40 │ CH 44 │ CH 48 │
1055 * └────────┴────────┴────────┴────────┘
1056 *
1057 * ┌────────┐
1058 * STA1 802.11a │ CH 36 │
1059 * └────────┘
1060 *
1061 * ┌────────┐
1062 * STA2 802.11n │ CH 40 │
1063 * └────────┘
1064 *
1065 * ┌────────┬────────┐
1066 * STA3 802.11ac │CH 44(P)│ CH 48 │
1067 * └────────┴────────┘
1068 *
1069 * Test scenario:
1070 * ┌────────┐ ┌──────────────────────┐
1071 * │ │ │RX non-HT PPDU @ STA 1│
1072 * │ 80 MHz │ └──────────────────────┘
1073 * │ non-HT │ ┌──────────────────────┐
1074 * │ PPDU │ │RX non-HT PPDU @ STA 2│
1075 * │ sent │ └──────────────────────┘
1076 * │ from │ ┌──────────────────────┐
1077 * │ AP │ │ │
1078 * │ │ │RX non-HT PPDU @ STA 3│
1079 * │ │ │ │
1080 * └────────┘ └──────────────────────┘
1081 */
1083 MHz_u{5210},
1084 0,
1085 {{WIFI_STANDARD_80211a, MHz_u{5180}, 0},
1086 {WIFI_STANDARD_80211n, MHz_u{5200}, 0},
1087 {WIFI_STANDARD_80211ac, MHz_u{5230}, 0}}),
1088 TestCase::Duration::QUICK);
1089 /* same channel map and test scenario as previously but inject interference on channel 40 */
1091 MHz_u{5210},
1092 0,
1093 {{WIFI_STANDARD_80211a, MHz_u{5180}, 0},
1094 {WIFI_STANDARD_80211n, MHz_u{5200}, 0},
1095 {WIFI_STANDARD_80211ac, MHz_u{5230}, 0}},
1096 {false, true, false, false}),
1097 TestCase::Duration::QUICK);
1098 /* test PHY reception of multiple CTS responses following a MU-RTS */
1099 /* 4 STAs operating on 20 MHz */
1101 new TestMultipleCtsResponsesFromMuRts({{MHz_u{20}}, {MHz_u{20}}, {MHz_u{20}}, {MHz_u{20}}}),
1102 TestCase::Duration::QUICK);
1103 /* 4 STAs operating on 40 MHz */
1105 new TestMultipleCtsResponsesFromMuRts({{MHz_u{40}}, {MHz_u{40}}, {MHz_u{40}}, {MHz_u{40}}}),
1106 TestCase::Duration::QUICK);
1107 /* 4 STAs operating on 80 MHz */
1109 new TestMultipleCtsResponsesFromMuRts({{MHz_u{80}}, {MHz_u{80}}, {MHz_u{80}}, {MHz_u{80}}}),
1110 TestCase::Duration::QUICK);
1111 /* 4 STAs operating on 160 MHz */
1113 {{MHz_u{160}}, {MHz_u{160}}, {MHz_u{160}}, {MHz_u{160}}}),
1114 TestCase::Duration::QUICK);
1115 /* 4 STAs operating on different bandwidths with PPDUs sent with decreasing BW: 160, 80, 40 and
1116 * 20 MHz */
1118 {{MHz_u{160}}, {MHz_u{80}}, {MHz_u{40}}, {MHz_u{20}}}),
1119 TestCase::Duration::QUICK);
1120 /* 4 STAs operating on different bandwidths with PPDUs sent with increasing BW: 20, 40, 80 and
1121 * 160 MHz */
1123 {{MHz_u{20}}, {MHz_u{40}}, {MHz_u{80}}, {MHz_u{160}}}),
1124 TestCase::Duration::QUICK);
1125 /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the first STA
1126 * does not respond */
1127 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{MHz_u{80}, true}, {MHz_u{40}, false}}),
1128 TestCase::Duration::QUICK);
1129 /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the second
1130 * STA does not respond */
1131 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{MHz_u{80}, false}, {MHz_u{40}, true}}),
1132 TestCase::Duration::QUICK);
1133 /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the first STA
1134 * does not respond */
1135 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{MHz_u{40}, true}, {MHz_u{80}, false}}),
1136 TestCase::Duration::QUICK);
1137 /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the second
1138 * STA does not respond */
1139 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{MHz_u{40}, false}, {MHz_u{80}, true}}),
1140 TestCase::Duration::QUICK);
1141}
1142
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.
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.
TestMultipleCtsResponsesFromMuRts(const std::vector< CtsTxInfos > &ctsTxInfosPerSta)
Constructor.
std::size_t m_countApRxCtsFailure
count the number of unsuccessfully received CTS frames by the AP
void RxCtsSuccess(std::size_t phyIndex, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
CTS RX success function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
std::size_t m_countStaRxCtsFailure
count the number of unsuccessfully received CTS frames by the non-participating STA
dBm_u m_stasTxPower
TX power configured for the STAs.
void FakePreviousMuRts()
Function called to fake the transmission of a MU-RTS.
std::vector< CtsTxInfos > m_ctsTxInfosPerSta
information about CTS responses
std::vector< Ptr< MuRtsCtsSpectrumWifiPhy > > m_phyStas
STAs PHYs.
void TxNonHtDuplicateCts(std::size_t phyIndex)
Function called to trigger a CTS frame sent by a STA using non-HT duplicate.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
std::size_t m_countApRxCtsSuccess
count the number of successfully received CTS frames by the AP
Ptr< MuRtsCtsSpectrumWifiPhy > m_phyAp
AP PHY.
void RxCtsFailure(std::size_t phyIndex, Ptr< const WifiPsdu > psdu)
CTS RX failure function.
std::size_t m_countStaRxCtsSuccess
count the number of successfully received CTS frames by the non-participating STA
non-HT duplicate PHY reception test The test consists in an AP sending a single non-HT duplicate PPDU...
MHz_u m_apFrequency
the center frequency of the AP
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.
TestNonHtDuplicatePhyReception(WifiStandard apStandard, MHz_u apFrequency, uint8_t apP20Index, StasParams stasParams, std::vector< bool > per20MhzInterference={})
Constructor.
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< std::tuple< WifiStandard, MHz_u, uint8_t > > StasParams
A vector containing parameters per STA: the standard, the center frequency and the P20 index.
std::vector< uint32_t > m_countRxFailureStas
count RX failure for STAs
StasParams m_stasParams
the parameters of the STAs
void SendNonHtDuplicatePpdu(MHz_u channelWidth)
Send non-HT duplicate PPDU function.
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.
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.
void RxSuccess(std::size_t index, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &statusPerMpdu)
Receive success function.
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)
wifi non-HT duplicate Test Suite
AttributeValue implementation for Boolean.
Definition boolean.h:26
PHY entity for HE (11ax)
Definition he-phy.h:58
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:554
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
Definition he-phy.h:543
void Dispose()
Dispose of this Object.
Definition object.cc:247
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:82
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
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:561
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
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.
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
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.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
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:679
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition wifi-phy.cc:688
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:940
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition wifi-phy.cc:485
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition wifi-phy.cc:1010
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition wifi-phy.h:1384
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition wifi-phy.h:1364
void SetOperatingChannel(const WifiPhyOperatingChannel &channel)
If the standard for this object has not been set yet, store the channel settings corresponding to the...
Definition wifi-phy.cc:1136
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition wifi-phy.cc:654
void SetReceiveOkCallback(RxOkCallback callback)
Definition wifi-phy.cc:479
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:2364
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first frequency segment matching the specified parameters.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetTriggerResponding(bool triggerResponding)
Set the Trigger Responding parameter to the given value.
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
MHz_u GetChannelWidth() const
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#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:134
#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:500
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
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.
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
std::vector< BandInfo > Bands
Container of BandInfo.
dBm_u WToDbm(Watt_u val)
Convert from Watts to dBm.
Definition wifi-utils.cc:39
std::size_t Count20MHzSubchannels(MHz_u channelWidth)
Return the number of 20 MHz subchannels covering the channel width.
Definition wifi-utils.h:135
@ WIFI_MAC_CTL_CTS
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:33
Hz_u MHzToHz(MHz_u val)
Convert from MHz to Hz.
Definition wifi-utils.h:110
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition wifi-mode.h:24
Information about CTS responses to expect in the test.
bool discard
flag whether the CTS response shall be discarded
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 wifi-types.h:78
dBm_u rssi
RSSI.
Definition wifi-types.h:80
constexpr MHz_u DEFAULT_FREQUENCY
static WifiNonHtDuplicateTestSuite wifiNonHtDuplicateTestSuite
the test suite