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}; // class MuRtsCtsHePhy
69
75
80
81void
83{
84 NS_LOG_FUNCTION(this << uid);
86}
87
88void
90{
91 NS_LOG_FUNCTION(this << muRtsTxVector);
92 m_currentTxVector = muRtsTxVector;
93}
94
95/**
96 * Spectrum PHY used for testing MU-RTS/CTS.
97 */
99{
100 public:
101 /**
102 * \brief Get the type ID.
103 * \return the object TypeId
104 */
105 static TypeId GetTypeId();
106
108 ~MuRtsCtsSpectrumWifiPhy() override;
109
110 void DoInitialize() override;
111 void DoDispose() override;
112
113 /**
114 * Set the global PPDU UID counter.
115 *
116 * \param uid the value to which the global PPDU UID counter should be set
117 */
118 void SetPpduUid(uint64_t uid);
119
120 /**
121 * Set the TXVECTOR of the previously transmitted MU-RTS.
122 *
123 * \param muRtsTxVector the TXVECTOR used to transmit MU-RTS trigger frame
124 */
125 void SetMuRtsTxVector(const WifiTxVector& muRtsTxVector);
126
127 private:
128 Ptr<MuRtsCtsHePhy> m_muRtsCtsHePhy; ///< Pointer to HE PHY instance used for MU-RTS/CTS PHY test
129}; // class MuRtsCtsSpectrumWifiPhy
130
131TypeId
133{
134 static TypeId tid =
135 TypeId("ns3::MuRtsCtsSpectrumWifiPhy").SetParent<SpectrumWifiPhy>().SetGroupName("Wifi");
136 return tid;
137}
138
146
151
152void
154{
155 // Replace HE PHY instance with test instance
158}
159
160void
166
167void
174
175void
177{
178 NS_LOG_FUNCTION(this << muRtsTxVector);
179 m_muRtsCtsHePhy->SetMuRtsTxVector(muRtsTxVector);
180}
181
182/**
183 * \ingroup wifi-test
184 * \ingroup tests
185 *
186 * \brief non-HT duplicate PHY reception test
187 * The test consists in an AP sending a single non-HT duplicate PPDU
188 * of a given channel width (multiple of 20 MHz) over a spectrum
189 * channel and it checks whether the STAs attached to the channel
190 * receive the PPDU. If an interference is injected on a given 20 MHz
191 * subchannel, the payload reception should fail, otherwise it should succeed.
192 */
194{
195 public:
196 /// A vector containing parameters per STA: the standard, the center frequency and the P20 index
197 using StasParams = std::vector<std::tuple<WifiStandard, MHz_u, uint8_t>>;
198
199 /**
200 * Constructor
201 * \param apStandard the standard to use for the AP
202 * \param apFrequency the center frequency of the AP
203 * \param apP20Index the index of the primary 20 MHz channel of the AP
204 * \param stasParams the parameters of the STAs (\see StasParams)
205 * \param per20MhzInterference flags per 20 MHz subchannel whether an interference should be
206 * generated on that subchannel. An empty vector means that the test will not generate any
207 * interference.
208 */
210 MHz_u apFrequency,
211 uint8_t apP20Index,
212 StasParams stasParams,
213 std::vector<bool> per20MhzInterference = {});
214
215 private:
216 void DoSetup() override;
217 void DoTeardown() override;
218 void DoRun() override;
219
220 /**
221 * Receive success function
222 * \param index index of the RX STA
223 * \param psdu the PSDU
224 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
225 * \param txVector the transmit vector
226 * \param statusPerMpdu reception status per MPDU
227 */
228 void RxSuccess(std::size_t index,
230 RxSignalInfo rxSignalInfo,
231 WifiTxVector txVector,
232 std::vector<bool> statusPerMpdu);
233
234 /**
235 * Receive failure function
236 * \param index index of the RX STA
237 * \param psdu the PSDU
238 */
239 void RxFailure(std::size_t index, Ptr<const WifiPsdu> psdu);
240
241 /**
242 * Check the results
243 * \param index index of the RX STA
244 * \param expectedRxSuccess the expected number of RX success
245 * \param expectedRxFailure the expected number of RX failures
246 */
247 void CheckResults(std::size_t index, uint32_t expectedRxSuccess, uint32_t expectedRxFailure);
248
249 /**
250 * Reset the results
251 */
252 void ResetResults();
253
254 /**
255 * Send non-HT duplicate PPDU function
256 * \param channelWidth the channel width to use to transmit the non-HT PPDU
257 */
258 void SendNonHtDuplicatePpdu(MHz_u channelWidth);
259
260 /**
261 * Generate interference function
262 * \param interferer the PHY of the interferer to use to generate the signal
263 * \param interferencePsd the PSD of the interference to be generated
264 * \param duration the duration of the interference
265 */
267 Ptr<SpectrumValue> interferencePsd,
268 Time duration);
269 /**
270 * Stop interference function
271 * \param interferer the PHY of the interferer that was used to generate the signal
272 */
274
275 WifiStandard m_apStandard; ///< the standard to use for the AP
276 MHz_u m_apFrequency; ///< the center frequency of the AP
277 uint8_t m_apP20Index; ///< the index of the primary 20 MHz channel of the AP
278 StasParams m_stasParams; ///< the parameters of the STAs
279 std::vector<bool>
280 m_per20MhzInterference; ///< flags per 20 MHz subchannel whether an interference should be
281 ///< generated on that subchannel
282
283 std::vector<uint32_t> m_countRxSuccessStas; ///< count RX success for STAs
284 std::vector<uint32_t> m_countRxFailureStas; ///< count RX failure for STAs
285
287 std::vector<Ptr<SpectrumWifiPhy>> m_phyStas; ///< PHYs of STAs
288
289 std::vector<Ptr<WaveformGenerator>>
290 m_phyInterferers; ///< PHYs of interferers (1 interferer per 20 MHz subchannel)
291};
292
294 WifiStandard apStandard,
295 MHz_u apFrequency,
296 uint8_t apP20Index,
297 StasParams stasParams,
298 std::vector<bool> per20MhzInterference)
299 : TestCase{"non-HT duplicate PHY reception test"},
300 m_apStandard{apStandard},
301 m_apFrequency{apFrequency},
302 m_apP20Index{apP20Index},
303 m_stasParams{stasParams},
304 m_per20MhzInterference{per20MhzInterference},
305 m_countRxSuccessStas{},
306 m_countRxFailureStas{},
307 m_phyStas{}
308{
309}
310
311void
313{
314 for (auto& countRxSuccess : m_countRxSuccessStas)
315 {
316 countRxSuccess = 0;
317 }
318 for (auto& countRxFailure : m_countRxFailureStas)
319 {
320 countRxFailure = 0;
321 }
322}
323
324void
326{
327 NS_LOG_FUNCTION(this << channelWidth);
329 0,
331 NanoSeconds(800),
332 1,
333 1,
334 0,
335 channelWidth,
336 false);
337
338 Ptr<Packet> pkt = Create<Packet>(1000);
339 WifiMacHeader hdr;
340
342 hdr.SetQosTid(0);
343
344 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
345 Time txDuration =
346 m_phyAp->CalculateTxDuration(psdu->GetSize(), txVector, m_phyAp->GetPhyBand());
347
348 m_phyAp->Send(WifiConstPsduMap({std::make_pair(SU_STA_ID, psdu)}), txVector);
349}
350
351void
353 Ptr<SpectrumValue> interferencePsd,
354 Time duration)
355{
356 NS_LOG_FUNCTION(this << interferer << duration);
357 interferer->SetTxPowerSpectralDensity(interferencePsd);
358 interferer->SetPeriod(duration);
359 interferer->Start();
360 Simulator::Schedule(duration,
362 this,
363 interferer);
364}
365
366void
368{
369 NS_LOG_FUNCTION(this << interferer);
370 interferer->Stop();
371}
372
373void
376 RxSignalInfo rxSignalInfo,
377 WifiTxVector txVector,
378 std::vector<bool> /*statusPerMpdu*/)
379{
380 NS_LOG_FUNCTION(this << index << *psdu << rxSignalInfo << txVector);
381 const auto expectedWidth =
382 std::min(m_phyAp->GetChannelWidth(), m_phyStas.at(index)->GetChannelWidth());
384 expectedWidth,
385 "Incorrect channel width in TXVECTOR");
386 m_countRxSuccessStas.at(index)++;
387}
388
389void
391{
392 NS_LOG_FUNCTION(this << index << *psdu);
393 m_countRxFailureStas.at(index)++;
394}
395
396void
398 uint32_t expectedRxSuccess,
399 uint32_t expectedRxFailure)
400{
401 NS_LOG_FUNCTION(this << index << expectedRxSuccess << expectedRxFailure);
403 expectedRxSuccess,
404 "The number of successfully received packets by STA "
405 << index << " is not correct!");
407 expectedRxFailure,
408 "The number of unsuccessfully received packets by STA "
409 << index << " is not correct!");
410}
411
412void
414{
415 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
417 lossModel->SetFrequency(m_apFrequency * 1e6);
418 spectrumChannel->AddPropagationLossModel(lossModel);
420 spectrumChannel->SetPropagationDelayModel(delayModel);
421
422 auto apNode = CreateObject<Node>();
423 auto apDev = CreateObject<WifiNetDevice>();
425 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
426 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
427 auto apErrorModel = CreateObject<NistErrorRateModel>();
428 m_phyAp->SetErrorRateModel(apErrorModel);
429 m_phyAp->SetDevice(apDev);
430 m_phyAp->AddChannel(spectrumChannel);
431 m_phyAp->ConfigureStandard(WIFI_STANDARD_80211ax);
433 m_phyAp->SetMobility(apMobility);
434 apDev->SetPhy(m_phyAp);
435 apNode->AggregateObject(apMobility);
436 apNode->AddDevice(apDev);
437
438 for (const auto& staParams : m_stasParams)
439 {
440 auto staNode = CreateObject<Node>();
441 auto staDev = CreateObject<WifiNetDevice>();
442 auto staPhy = CreateObject<SpectrumWifiPhy>();
443 auto sta1InterferenceHelper = CreateObject<InterferenceHelper>();
444 staPhy->SetInterferenceHelper(sta1InterferenceHelper);
445 auto sta1ErrorModel = CreateObject<NistErrorRateModel>();
446 staPhy->SetErrorRateModel(sta1ErrorModel);
447 staPhy->SetDevice(staDev);
448 staPhy->AddChannel(spectrumChannel);
449 staPhy->ConfigureStandard(std::get<0>(staParams));
450 staPhy->SetReceiveOkCallback(
452 staPhy->SetReceiveErrorCallback(
455 staPhy->SetMobility(staMobility);
456 staDev->SetPhy(staPhy);
457 staNode->AggregateObject(staMobility);
458 staNode->AddDevice(staDev);
459 m_phyStas.push_back(staPhy);
460 m_countRxSuccessStas.push_back(0);
461 m_countRxFailureStas.push_back(0);
462 }
463
464 if (!m_per20MhzInterference.empty())
465 {
466 const auto& channelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
468 0,
471 [[maybe_unused]] const std::size_t num20MhzSubchannels = channelInfo.width / 20;
472 NS_ASSERT(m_per20MhzInterference.size() == num20MhzSubchannels);
473 for (std::size_t i = 0; i < m_per20MhzInterference.size(); ++i)
474 {
475 auto interfererNode = CreateObject<Node>();
476 auto interfererDev = CreateObject<NonCommunicatingNetDevice>();
477 auto phyInterferer = CreateObject<WaveformGenerator>();
478 phyInterferer->SetDevice(interfererDev);
479 phyInterferer->SetChannel(spectrumChannel);
480 phyInterferer->SetDutyCycle(1);
481 interfererNode->AddDevice(interfererDev);
482 m_phyInterferers.push_back(phyInterferer);
483 }
484 }
485}
486
487void
489{
490 m_phyAp->Dispose();
491 m_phyAp = nullptr;
492 for (auto phySta : m_phyStas)
493 {
494 phySta->Dispose();
495 phySta = nullptr;
496 }
497 for (auto phyInterferer : m_phyInterferers)
498 {
499 phyInterferer->Dispose();
500 phyInterferer = nullptr;
501 }
502}
503
504void
506{
509 int64_t streamNumber = 0;
510 m_phyAp->AssignStreams(streamNumber);
511 for (auto phySta : m_phyStas)
512 {
513 phySta->AssignStreams(streamNumber);
514 }
515
516 const auto& apchannelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
518 0,
521 m_phyAp->SetOperatingChannel(WifiPhy::ChannelTuple{apchannelInfo.number,
522 apchannelInfo.width,
524 m_apP20Index});
525
526 auto index = 0;
527 for (const auto& [staStandard, staFrequency, staP20Index] : m_stasParams)
528 {
529 const auto& stachannelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
530 staFrequency,
531 0,
532 staStandard,
534 m_phyStas.at(index++)->SetOperatingChannel(WifiPhy::ChannelTuple{stachannelInfo.number,
535 stachannelInfo.width,
537 staP20Index});
538 }
539
540 index = 0;
541 const auto minApCenterFrequency =
542 m_phyAp->GetFrequency() - (m_phyAp->GetChannelWidth() / 2) + (20 / 2);
543 for (auto channelWidth = 20; channelWidth <= apchannelInfo.width; channelWidth *= 2, ++index)
544 {
545 if (!m_phyInterferers.empty())
546 {
547 for (std::size_t i = 0; i < m_phyInterferers.size(); ++i)
548 {
549 if (!m_per20MhzInterference.at(i))
550 {
551 continue;
552 }
553 BandInfo bandInfo;
554 bandInfo.fc = (minApCenterFrequency + (i * 20)) * 1e6;
555 bandInfo.fl = bandInfo.fc - (5 * 1e6);
556 bandInfo.fh = bandInfo.fc + (5 * 1e6);
557 Bands bands;
558 bands.push_back(bandInfo);
559 auto spectrumInterference = Create<SpectrumModel>(bands);
560 auto interferencePsd = Create<SpectrumValue>(spectrumInterference);
561 Watt_u interferencePower = 0.005; // designed to make PHY headers reception
562 // successful but payload reception fail
563 *interferencePsd = interferencePower / 10e6;
566 this,
567 m_phyInterferers.at(i),
568 interferencePsd,
569 Seconds(0.5));
570 }
571 }
572 const auto apCenterFreq =
573 m_phyAp->GetOperatingChannel().GetPrimaryChannelCenterFrequency(channelWidth);
574 const auto apMinFreq = apCenterFreq - (channelWidth / 2);
575 const auto apMaxFreq = apCenterFreq + (channelWidth / 2);
576 Simulator::Schedule(Seconds(index + 0.1),
578 this,
579 channelWidth);
580 for (std::size_t i = 0; i < m_stasParams.size(); ++i)
581 {
582 const auto p20Width = 20;
583 const auto staP20Freq =
584 m_phyStas.at(i)->GetOperatingChannel().GetPrimaryChannelCenterFrequency(p20Width);
585 const auto staP20MinFreq = staP20Freq - (p20Width / 2);
586 const auto staP20MaxFreq = staP20Freq + (p20Width / 2);
587 bool expectRx = (staP20MinFreq >= apMinFreq && staP20MaxFreq <= apMaxFreq);
588 bool expectSuccess = true;
589 if (!m_per20MhzInterference.empty())
590 {
591 const auto index20MhzSubBand = ((staP20Freq - minApCenterFrequency) / 20);
592 expectSuccess = !m_per20MhzInterference.at(index20MhzSubBand);
593 }
594 Simulator::Schedule(Seconds(index + 0.5),
596 this,
597 i,
598 expectRx ? expectSuccess : 0,
599 expectRx ? !expectSuccess : 0);
600 }
601 Simulator::Schedule(Seconds(index + 0.5),
603 this);
604 }
605
608}
609
610/**
611 * \ingroup wifi-test
612 * \ingroup tests
613 *
614 * \brief test PHY reception of multiple CTS frames as a response to a MU-RTS frame.
615 * The test is checking whether the reception of multiple identical CTS frames as a response to a
616 * MU-RTS frame is successfully received by the AP PHY and that only a single CTS frame is forwarded
617 * up to the MAC. Since the test is focusing on the PHY reception of multiple CTS response, the
618 * transmission of the MU-RTS frame is faked. The test also checks the correct channel width is
619 * passed to the MAC layer through the TXVECTOR. The test also consider the case some STAs do not
620 * respond to verify the largest channel width of the successfully CTS responses is reported to the
621 * MAC.
622 */
624{
625 public:
626 /// Information about CTS responses to expect in the test
628 {
629 MHz_u bw{20}; ///< the width of the CTS response
630 bool discard{false}; ///< flag whether the CTS response shall be discarded
631 };
632
633 /**
634 * Constructor
635 * \param ctsTxInfosPerSta the information about CTS responses to generate
636 */
637 TestMultipleCtsResponsesFromMuRts(const std::vector<CtsTxInfos>& ctsTxInfosPerSta);
638
639 private:
640 void DoSetup() override;
641 void DoTeardown() override;
642 void DoRun() override;
643
644 /**
645 * Function called to fake the transmission of a MU-RTS.
646 */
647 void FakePreviousMuRts();
648
649 /**
650 * Function called to trigger a CTS frame sent by a STA using non-HT duplicate.
651 *
652 * \param phyIndex the index of the TX PHY
653 */
654 void TxNonHtDuplicateCts(std::size_t phyIndex);
655
656 /**
657 * CTS RX success function
658 * \param phyIndex the index of the PHY (0 for AP)
659 * \param psdu the PSDU
660 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
661 * \param txVector the transmit vector
662 * \param statusPerMpdu reception status per MPDU
663 */
664 void RxCtsSuccess(std::size_t phyIndex,
666 RxSignalInfo rxSignalInfo,
667 WifiTxVector txVector,
668 std::vector<bool> statusPerMpdu);
669
670 /**
671 * CTS RX failure function
672 * \param phyIndex the index of the PHY (0 for AP)
673 * \param psdu the PSDU
674 */
675 void RxCtsFailure(std::size_t phyIndex, Ptr<const WifiPsdu> psdu);
676
677 /**
678 * Check the results
679 */
680 void CheckResults();
681
683 std::vector<Ptr<MuRtsCtsSpectrumWifiPhy>> m_phyStas; ///< STAs PHYs
684
685 std::vector<CtsTxInfos> m_ctsTxInfosPerSta; ///< information about CTS responses
686
687 std::size_t
688 m_countApRxCtsSuccess; ///< count the number of successfully received CTS frames by the AP
689 std::size_t
690 m_countApRxCtsFailure; ///< count the number of unsuccessfully received CTS frames by the AP
691 std::size_t m_countStaRxCtsSuccess; ///< count the number of successfully received CTS frames by
692 ///< the non-participating STA
693 std::size_t m_countStaRxCtsFailure; ///< count the number of unsuccessfully received CTS frames
694 ///< by the non-participating STA
695
696 dBm_u m_stasTxPower; ///< TX power configured for the STAs
697};
698
700 const std::vector<CtsTxInfos>& ctsTxInfosPerSta)
701 : TestCase{"test PHY reception of multiple CTS frames following a MU-RTS frame"},
702 m_ctsTxInfosPerSta{ctsTxInfosPerSta},
703 m_countApRxCtsSuccess{0},
704 m_countApRxCtsFailure{0},
705 m_countStaRxCtsSuccess{0},
706 m_countStaRxCtsFailure{0},
707 m_stasTxPower(10.0)
708{
709}
710
711void
713{
714 NS_LOG_FUNCTION(this);
715
716 const auto bw =
717 std::max_element(m_ctsTxInfosPerSta.cbegin(),
718 m_ctsTxInfosPerSta.cend(),
719 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
720 ->bw;
721 WifiTxVector txVector;
722 txVector.SetChannelWidth(bw); // only the channel width matters for this test
723
724 // set the TXVECTOR and the UID of the previously transmitted MU-RTS in the AP PHY
725 m_phyAp->SetMuRtsTxVector(txVector);
727
728 // set the UID of the previously received MU-RTS in the STAs PHYs
729 for (auto& phySta : m_phyStas)
730 {
731 phySta->SetPpduUid(0);
732 }
733}
734
735void
737{
738 const auto bw = m_ctsTxInfosPerSta.at(phyIndex).bw;
739 const auto discarded = m_ctsTxInfosPerSta.at(phyIndex).discard;
740 NS_LOG_FUNCTION(this << phyIndex << bw << discarded);
741
742 if (discarded)
743 {
744 return;
745 }
746
747 WifiTxVector txVector =
748 WifiTxVector(OfdmPhy::GetOfdmRate54Mbps(), // use less robust modulation for test purpose
749 0,
751 NanoSeconds(800),
752 1,
753 1,
754 0,
755 bw,
756 false,
757 false);
758 txVector.SetTriggerResponding(true);
759
760 WifiMacHeader hdr;
762 hdr.SetDsNotFrom();
763 hdr.SetDsNotTo();
764 hdr.SetNoMoreFragments();
765 hdr.SetNoRetry();
766
767 auto pkt = Create<Packet>();
768 auto mpdu = Create<WifiMpdu>(pkt, hdr);
769 auto psdu = Create<WifiPsdu>(mpdu, false);
770
771 m_phyStas.at(phyIndex)->Send(psdu, txVector);
772}
773
774void
777 RxSignalInfo rxSignalInfo,
778 WifiTxVector txVector,
779 std::vector<bool> /*statusPerMpdu*/)
780{
781 NS_LOG_FUNCTION(this << phyIndex << *psdu << rxSignalInfo << txVector);
782 std::vector<CtsTxInfos> successfulCtsInfos{};
783 std::copy_if(m_ctsTxInfosPerSta.cbegin(),
784 m_ctsTxInfosPerSta.cend(),
785 std::back_inserter(successfulCtsInfos),
786 [](const auto& info) { return !info.discard; });
787 const auto isAp = (phyIndex == 0);
788 if (isAp)
789 {
790 NS_TEST_EXPECT_MSG_EQ_TOL(rxSignalInfo.rssi,
791 WToDbm(DbmToW(m_stasTxPower) * successfulCtsInfos.size()),
792 0.1,
793 "RX power is not correct!");
794 }
795 auto expectedWidth =
796 std::max_element(successfulCtsInfos.cbegin(),
797 successfulCtsInfos.cend(),
798 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
799 ->bw;
800 if (!isAp)
801 {
802 expectedWidth = std::min(m_ctsTxInfosPerSta.at(phyIndex - 1).bw, expectedWidth);
803 }
805 expectedWidth,
806 "Incorrect channel width in TXVECTOR");
807 if (isAp)
808 {
810 }
811 else
812 {
814 }
815}
816
817void
819{
820 NS_LOG_FUNCTION(this << phyIndex << *psdu);
821 const auto isAp = (phyIndex == 0);
822 if (isAp)
823 {
825 }
826 else
827 {
829 }
830}
831
832void
834{
836 1,
837 "The number of successfully received CTS frames by AP is not correct!");
840 m_ctsTxInfosPerSta.size(),
841 "The number of successfully received CTS frames by non-participating STAs is not correct!");
843 0,
844 "The number of unsuccessfully received CTS frames by AP is not correct!");
846 0,
847 "The number of unsuccessfully received CTS frames by non-participating "
848 "STAs is not correct!");
849}
850
851void
853{
856 int64_t streamNumber = 0;
857
858 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
860 lossModel->SetFrequency(DEFAULT_FREQUENCY * 1e6);
861 spectrumChannel->AddPropagationLossModel(lossModel);
863 spectrumChannel->SetPropagationDelayModel(delayModel);
864
865 auto apNode = CreateObject<Node>();
866 auto apDev = CreateObject<WifiNetDevice>();
868 "Txop",
870 apMac->SetAttribute("BeaconGeneration", BooleanValue(false));
871 apDev->SetMac(apMac);
873 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
874 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
875 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
876 auto apErrorModel = CreateObject<NistErrorRateModel>();
877 m_phyAp->SetErrorRateModel(apErrorModel);
878 m_phyAp->SetDevice(apDev);
879 m_phyAp->AddChannel(spectrumChannel);
881 m_phyAp->AssignStreams(streamNumber);
882
887
888 const auto apBw =
889 std::max_element(m_ctsTxInfosPerSta.cbegin(),
890 m_ctsTxInfosPerSta.cend(),
891 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
892 ->bw;
893 auto apChannelNum =
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 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.0);
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 5210,
1084 0,
1085 {{WIFI_STANDARD_80211a, 5180, 0},
1086 {WIFI_STANDARD_80211n, 5200, 0},
1087 {WIFI_STANDARD_80211ac, 5230, 0}}),
1088 TestCase::Duration::QUICK);
1089 /* same channel map and test scenario as previously but inject interference on channel 40 */
1091 5210,
1092 0,
1093 {{WIFI_STANDARD_80211a, 5180, 0},
1094 {WIFI_STANDARD_80211n, 5200, 0},
1095 {WIFI_STANDARD_80211ac, 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 */
1100 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{20}, {20}, {20}, {20}}),
1101 TestCase::Duration::QUICK);
1102 /* 4 STAs operating on 40 MHz */
1103 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{40}, {40}, {40}, {40}}),
1104 TestCase::Duration::QUICK);
1105 /* 4 STAs operating on 80 MHz */
1106 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{80}, {80}, {80}, {80}}),
1107 TestCase::Duration::QUICK);
1108 /* 4 STAs operating on 160 MHz */
1109 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{160}, {160}, {160}, {160}}),
1110 TestCase::Duration::QUICK);
1111 /* 4 STAs operating on different bandwidths with PPDUs sent with decreasing BW: 160, 80, 40 and
1112 * 20 MHz */
1113 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{160}, {80}, {40}, {20}}),
1114 TestCase::Duration::QUICK);
1115 /* 4 STAs operating on different bandwidths with PPDUs sent with increasing BW: 20, 40, 80 and
1116 * 160 MHz */
1117 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{20}, {40}, {80}, {160}}),
1118 TestCase::Duration::QUICK);
1119 /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the first STA
1120 * does not respond */
1121 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{80, true}, {40, false}}),
1122 TestCase::Duration::QUICK);
1123 /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the second
1124 * STA does not respond */
1125 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{80, false}, {40, true}}),
1126 TestCase::Duration::QUICK);
1127 /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the first STA
1128 * does not respond */
1129 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{40, true}, {80, false}}),
1130 TestCase::Duration::QUICK);
1131 /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the second
1132 * STA does not respond */
1133 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{40, false}, {80, true}}),
1134 TestCase::Duration::QUICK);
1135}
1136
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 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 RxCtsSuccess(std::size_t phyIndex, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
CTS RX success function.
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.
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)
wifi non-HT duplicate Test Suite
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:563
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
Definition he-phy.h:552
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:560
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:48
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 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:672
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition wifi-phy.cc:681
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:919
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition wifi-phy.cc:478
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition wifi-phy.cc:1003
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition wifi-phy.h:1360
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition wifi-phy.h:1340
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:1129
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition wifi-phy.cc:647
void SetReceiveOkCallback(RxOkCallback callback)
Definition wifi-phy.cc:472
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:2330
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:1344
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
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:37
@ WIFI_MAC_CTL_CTS
@ WIFI_MAC_QOSDATA
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:31
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:72
dBm_u rssi
RSSI.
Definition wifi-types.h:74
constexpr MHz_u DEFAULT_FREQUENCY
static WifiNonHtDuplicateTestSuite wifiNonHtDuplicateTestSuite
the test suite