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 std::shared_ptr<MuRtsCtsHePhy>
131 m_muRtsCtsHePhy; ///< Pointer to HE PHY instance used for MU-RTS/CTS PHY test
132
133 // end of class MuRtsCtsSpectrumWifiPhy
134};
135
136TypeId
138{
139 static TypeId tid =
140 TypeId("ns3::MuRtsCtsSpectrumWifiPhy").SetParent<SpectrumWifiPhy>().SetGroupName("Wifi");
141 return tid;
142}
143
146{
147 NS_LOG_FUNCTION(this);
148 m_muRtsCtsHePhy = std::make_shared<MuRtsCtsHePhy>();
149 m_muRtsCtsHePhy->SetOwner(this);
150}
151
156
157void
159{
160 // Replace HE PHY instance with test instance
163}
164
165void
171
172void
174{
175 NS_LOG_FUNCTION(this << uid);
176 m_muRtsCtsHePhy->SetPreviousTxPpduUid(uid);
178}
179
180void
182{
183 NS_LOG_FUNCTION(this << muRtsTxVector);
184 m_muRtsCtsHePhy->SetMuRtsTxVector(muRtsTxVector);
185}
186
187/**
188 * @ingroup wifi-test
189 * @ingroup tests
190 *
191 * @brief non-HT duplicate PHY reception test
192 * The test consists in an AP sending a single non-HT duplicate PPDU
193 * of a given channel width (multiple of 20 MHz) over a spectrum
194 * channel and it checks whether the STAs attached to the channel
195 * receive the PPDU. If an interference is injected on a given 20 MHz
196 * subchannel, the payload reception should fail, otherwise it should succeed.
197 */
199{
200 public:
201 /// A vector containing parameters per STA: the standard, the center frequency and the P20 index
202 using StasParams = std::vector<std::tuple<WifiStandard, MHz_u, uint8_t>>;
203
204 /**
205 * Constructor
206 * @param apStandard the standard to use for the AP
207 * @param apFrequency the center frequency of the AP
208 * @param apP20Index the index of the primary 20 MHz channel of the AP
209 * @param stasParams the parameters of the STAs (\see StasParams)
210 * @param per20MhzInterference flags per 20 MHz subchannel whether an interference should be
211 * generated on that subchannel. An empty vector means that the test will not generate any
212 * interference.
213 */
215 MHz_u apFrequency,
216 uint8_t apP20Index,
217 StasParams stasParams,
218 std::vector<bool> per20MhzInterference = {});
219
220 private:
221 void DoSetup() override;
222 void DoTeardown() override;
223 void DoRun() override;
224
225 /**
226 * Receive success function
227 * @param index index of the RX STA
228 * @param psdu the PSDU
229 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
230 * @param txVector the transmit vector
231 * @param statusPerMpdu reception status per MPDU
232 */
233 void RxSuccess(std::size_t index,
235 RxSignalInfo rxSignalInfo,
236 const WifiTxVector& txVector,
237 const std::vector<bool>& statusPerMpdu);
238
239 /**
240 * Receive failure function
241 * @param index index of the RX STA
242 * @param psdu the PSDU
243 */
244 void RxFailure(std::size_t index, Ptr<const WifiPsdu> psdu);
245
246 /**
247 * Check the results
248 * @param index index of the RX STA
249 * @param expectedRxSuccess the expected number of RX success
250 * @param expectedRxFailure the expected number of RX failures
251 */
252 void CheckResults(std::size_t index, uint32_t expectedRxSuccess, uint32_t expectedRxFailure);
253
254 /**
255 * Reset the results
256 */
257 void ResetResults();
258
259 /**
260 * Send non-HT duplicate PPDU function
261 * @param channelWidth the channel width to use to transmit the non-HT PPDU
262 */
263 void SendNonHtDuplicatePpdu(MHz_u channelWidth);
264
265 /**
266 * Generate interference function
267 * @param interferer the PHY of the interferer to use to generate the signal
268 * @param interferencePsd the PSD of the interference to be generated
269 * @param duration the duration of the interference
270 */
272 Ptr<SpectrumValue> interferencePsd,
273 Time duration);
274 /**
275 * Stop interference function
276 * @param interferer the PHY of the interferer that was used to generate the signal
277 */
279
280 WifiStandard m_apStandard; ///< the standard to use for the AP
281 MHz_u m_apFrequency; ///< the center frequency of the AP
282 uint8_t m_apP20Index; ///< the index of the primary 20 MHz channel of the AP
283 StasParams m_stasParams; ///< the parameters of the STAs
284 std::vector<bool>
285 m_per20MhzInterference; ///< flags per 20 MHz subchannel whether an interference should be
286 ///< generated on that subchannel
287
288 std::vector<uint32_t> m_countRxSuccessStas; ///< count RX success for STAs
289 std::vector<uint32_t> m_countRxFailureStas; ///< count RX failure for STAs
290
292 std::vector<Ptr<SpectrumWifiPhy>> m_phyStas; ///< PHYs of STAs
293
294 std::vector<Ptr<WaveformGenerator>>
295 m_phyInterferers; ///< PHYs of interferers (1 interferer per 20 MHz subchannel)
296};
297
299 WifiStandard apStandard,
300 MHz_u apFrequency,
301 uint8_t apP20Index,
302 StasParams stasParams,
303 std::vector<bool> per20MhzInterference)
304 : TestCase{"non-HT duplicate PHY reception test"},
305 m_apStandard{apStandard},
306 m_apFrequency{apFrequency},
307 m_apP20Index{apP20Index},
308 m_stasParams{stasParams},
309 m_per20MhzInterference{per20MhzInterference},
312 m_phyStas{}
313{
314}
315
316void
318{
319 for (auto& countRxSuccess : m_countRxSuccessStas)
320 {
321 countRxSuccess = 0;
322 }
323 for (auto& countRxFailure : m_countRxFailureStas)
324 {
325 countRxFailure = 0;
326 }
327}
328
329void
331{
332 NS_LOG_FUNCTION(this << channelWidth);
334 0,
336 NanoSeconds(800),
337 1,
338 1,
339 0,
340 channelWidth,
341 false);
342
343 auto pkt = Create<Packet>(1000);
344 WifiMacHeader hdr;
345 auto psdu = Create<WifiPsdu>(pkt, hdr);
346 m_phyAp->Send(WifiConstPsduMap({std::make_pair(SU_STA_ID, psdu)}), txVector);
347}
348
349void
351 Ptr<SpectrumValue> interferencePsd,
352 Time duration)
353{
354 NS_LOG_FUNCTION(this << interferer << duration);
355 interferer->SetTxPowerSpectralDensity(interferencePsd);
356 interferer->SetPeriod(duration);
357 interferer->Start();
358 Simulator::Schedule(duration,
360 this,
361 interferer);
362}
363
364void
366{
367 NS_LOG_FUNCTION(this << interferer);
368 interferer->Stop();
369}
370
371void
374 RxSignalInfo rxSignalInfo,
375 const WifiTxVector& txVector,
376 const std::vector<bool>& /*statusPerMpdu*/)
377{
378 NS_LOG_FUNCTION(this << index << *psdu << rxSignalInfo << txVector);
379 const auto expectedWidth =
380 std::min(m_phyAp->GetChannelWidth(), m_phyStas.at(index)->GetChannelWidth());
382 expectedWidth,
383 "Incorrect channel width in TXVECTOR");
384 m_countRxSuccessStas.at(index)++;
385}
386
387void
389{
390 NS_LOG_FUNCTION(this << index << *psdu);
391 m_countRxFailureStas.at(index)++;
392}
393
394void
396 uint32_t expectedRxSuccess,
397 uint32_t expectedRxFailure)
398{
399 NS_LOG_FUNCTION(this << index << expectedRxSuccess << expectedRxFailure);
401 expectedRxSuccess,
402 "The number of successfully received packets by STA "
403 << index << " is not correct!");
405 expectedRxFailure,
406 "The number of unsuccessfully received packets by STA "
407 << index << " is not correct!");
408}
409
410void
412{
413 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
415 lossModel->SetFrequency(MHzToHz(m_apFrequency));
416 spectrumChannel->AddPropagationLossModel(lossModel);
418 spectrumChannel->SetPropagationDelayModel(delayModel);
419
420 auto apNode = CreateObject<Node>();
421 auto apDev = CreateObject<WifiNetDevice>();
423 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
424 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
425 auto apErrorModel = CreateObject<NistErrorRateModel>();
426 m_phyAp->SetErrorRateModel(apErrorModel);
427 m_phyAp->SetDevice(apDev);
428 m_phyAp->AddChannel(spectrumChannel);
429 m_phyAp->ConfigureStandard(WIFI_STANDARD_80211ax);
431 m_phyAp->SetMobility(apMobility);
432 apDev->SetPhy(m_phyAp);
433 apNode->AggregateObject(apMobility);
434 apNode->AddDevice(apDev);
435
436 for (const auto& staParams : m_stasParams)
437 {
438 auto staNode = CreateObject<Node>();
439 auto staDev = CreateObject<WifiNetDevice>();
440 auto staPhy = CreateObject<SpectrumWifiPhy>();
441 auto sta1InterferenceHelper = CreateObject<InterferenceHelper>();
442 staPhy->SetInterferenceHelper(sta1InterferenceHelper);
443 auto sta1ErrorModel = CreateObject<NistErrorRateModel>();
444 staPhy->SetErrorRateModel(sta1ErrorModel);
445 staPhy->SetDevice(staDev);
446 staPhy->AddChannel(spectrumChannel);
447 staPhy->ConfigureStandard(std::get<0>(staParams));
448 staPhy->SetReceiveOkCallback(
450 staPhy->SetReceiveErrorCallback(
453 staPhy->SetMobility(staMobility);
454 staDev->SetPhy(staPhy);
455 staNode->AggregateObject(staMobility);
456 staNode->AddDevice(staDev);
457 m_phyStas.push_back(staPhy);
458 m_countRxSuccessStas.push_back(0);
459 m_countRxFailureStas.push_back(0);
460 }
461
462 if (!m_per20MhzInterference.empty())
463 {
464 const auto& channelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
466 MHz_u{0},
469 NS_ASSERT(m_per20MhzInterference.size() == Count20MHzSubchannels(channelInfo.width));
470 for (std::size_t i = 0; i < m_per20MhzInterference.size(); ++i)
471 {
472 auto interfererNode = CreateObject<Node>();
473 auto interfererDev = CreateObject<NonCommunicatingNetDevice>();
474 auto phyInterferer = CreateObject<WaveformGenerator>();
475 phyInterferer->SetDevice(interfererDev);
476 phyInterferer->SetChannel(spectrumChannel);
477 phyInterferer->SetDutyCycle(1);
478 interfererNode->AddDevice(interfererDev);
479 m_phyInterferers.push_back(phyInterferer);
480 }
481 }
482}
483
484void
486{
487 m_phyAp->Dispose();
488 m_phyAp = nullptr;
489 for (auto phySta : m_phyStas)
490 {
491 phySta->Dispose();
492 phySta = nullptr;
493 }
494 for (auto phyInterferer : m_phyInterferers)
495 {
496 phyInterferer->Dispose();
497 phyInterferer = nullptr;
498 }
499}
500
501void
503{
506 int64_t streamNumber = 0;
507 m_phyAp->AssignStreams(streamNumber);
508 for (auto phySta : m_phyStas)
509 {
510 phySta->AssignStreams(streamNumber);
511 }
512
513 const auto& apchannelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
515 MHz_u{0},
518 m_phyAp->SetOperatingChannel(WifiPhy::ChannelTuple{apchannelInfo.number,
519 apchannelInfo.width,
521 m_apP20Index});
522
523 auto index = 0;
524 for (const auto& [staStandard, staFrequency, staP20Index] : m_stasParams)
525 {
526 const auto& stachannelInfo = (*WifiPhyOperatingChannel::FindFirst(0,
527 staFrequency,
528 MHz_u{0},
529 staStandard,
531 m_phyStas.at(index++)->SetOperatingChannel(WifiPhy::ChannelTuple{stachannelInfo.number,
532 stachannelInfo.width,
534 staP20Index});
535 }
536
537 index = 0;
538 const auto minApCenterFrequency =
539 m_phyAp->GetFrequency() - (m_phyAp->GetChannelWidth() / 2) + (MHz_u{20} / 2);
540 for (MHz_u channelWidth{20}; channelWidth <= apchannelInfo.width; channelWidth *= 2, ++index)
541 {
542 if (!m_phyInterferers.empty())
543 {
544 for (std::size_t i = 0; i < m_phyInterferers.size(); ++i)
545 {
546 if (!m_per20MhzInterference.at(i))
547 {
548 continue;
549 }
550 BandInfo bandInfo;
551 bandInfo.fc = MHzToHz(minApCenterFrequency + (i * MHz_u{20}));
552 bandInfo.fl = bandInfo.fc - MHzToHz(5);
553 bandInfo.fh = bandInfo.fc + MHzToHz(5);
554 Bands bands;
555 bands.push_back(bandInfo);
556 auto spectrumInterference = Create<SpectrumModel>(bands);
557 auto interferencePsd = Create<SpectrumValue>(spectrumInterference);
558 Watt_u interferencePower{0.005}; // designed to make PHY headers reception
559 // successful but payload reception fail
560 *interferencePsd = interferencePower / 10e6;
563 this,
564 m_phyInterferers.at(i),
565 interferencePsd,
566 Seconds(0.5));
567 }
568 }
569 const auto apCenterFreq =
570 m_phyAp->GetOperatingChannel().GetPrimaryChannelCenterFrequency(channelWidth);
571 const auto apMinFreq = apCenterFreq - (channelWidth / 2);
572 const auto apMaxFreq = apCenterFreq + (channelWidth / 2);
573 Simulator::Schedule(Seconds(index + 0.1),
575 this,
576 channelWidth);
577 for (std::size_t i = 0; i < m_stasParams.size(); ++i)
578 {
579 const MHz_u p20Width{20};
580 const auto staP20Freq =
581 m_phyStas.at(i)->GetOperatingChannel().GetPrimaryChannelCenterFrequency(p20Width);
582 const auto staP20MinFreq = staP20Freq - (p20Width / 2);
583 const auto staP20MaxFreq = staP20Freq + (p20Width / 2);
584 bool expectRx = (staP20MinFreq >= apMinFreq && staP20MaxFreq <= apMaxFreq);
585 bool expectSuccess = true;
586 if (!m_per20MhzInterference.empty())
587 {
588 const auto index20MhzSubBand =
589 Count20MHzSubchannels(staP20Freq - minApCenterFrequency);
590 expectSuccess = !m_per20MhzInterference.at(index20MhzSubBand);
591 }
592 Simulator::Schedule(Seconds(index + 0.5),
594 this,
595 i,
596 expectRx ? expectSuccess : 0,
597 expectRx ? !expectSuccess : 0);
598 }
599 Simulator::Schedule(Seconds(index + 0.5),
601 this);
602 }
603
606}
607
608/**
609 * @ingroup wifi-test
610 * @ingroup tests
611 *
612 * @brief test PHY reception of multiple CTS frames as a response to a MU-RTS frame.
613 * The test is checking whether the reception of multiple identical CTS frames as a response to a
614 * MU-RTS frame is successfully received by the AP PHY and that only a single CTS frame is forwarded
615 * up to the MAC. Since the test is focusing on the PHY reception of multiple CTS response, the
616 * transmission of the MU-RTS frame is faked. The test also checks the correct channel width is
617 * passed to the MAC layer through the TXVECTOR. The test also consider the case some STAs do not
618 * respond to verify the largest channel width of the successfully CTS responses is reported to the
619 * MAC.
620 */
622{
623 public:
624 /// Information about CTS responses to expect in the test
626 {
627 MHz_u bw{20}; ///< the width of the CTS response
628 bool discard{false}; ///< flag whether the CTS response shall be discarded
629 };
630
631 /**
632 * Constructor
633 * @param ctsTxInfosPerSta the information about CTS responses to generate
634 */
635 TestMultipleCtsResponsesFromMuRts(const std::vector<CtsTxInfos>& ctsTxInfosPerSta);
636
637 private:
638 void DoSetup() override;
639 void DoTeardown() override;
640 void DoRun() override;
641
642 /**
643 * Function called to fake the transmission of a MU-RTS.
644 */
645 void FakePreviousMuRts();
646
647 /**
648 * Function called to trigger a CTS frame sent by a STA using non-HT duplicate.
649 *
650 * @param phyIndex the index of the TX PHY
651 */
652 void TxNonHtDuplicateCts(std::size_t phyIndex);
653
654 /**
655 * CTS RX success function
656 * @param phyIndex the index of the PHY (0 for AP)
657 * @param psdu the PSDU
658 * @param rxSignalInfo the info on the received signal (\see RxSignalInfo)
659 * @param txVector the transmit vector
660 * @param statusPerMpdu reception status per MPDU
661 */
662 void RxCtsSuccess(std::size_t phyIndex,
664 RxSignalInfo rxSignalInfo,
665 const WifiTxVector& txVector,
666 const std::vector<bool>& statusPerMpdu);
667
668 /**
669 * CTS RX failure function
670 * @param phyIndex the index of the PHY (0 for AP)
671 * @param psdu the PSDU
672 */
673 void RxCtsFailure(std::size_t phyIndex, Ptr<const WifiPsdu> psdu);
674
675 /**
676 * Check the results
677 */
678 void CheckResults();
679
681 std::vector<Ptr<MuRtsCtsSpectrumWifiPhy>> m_phyStas; ///< STAs PHYs
682
683 std::vector<CtsTxInfos> m_ctsTxInfosPerSta; ///< information about CTS responses
684
685 std::size_t
686 m_countApRxCtsSuccess; ///< count the number of successfully received CTS frames by the AP
687 std::size_t
688 m_countApRxCtsFailure; ///< count the number of unsuccessfully received CTS frames by the AP
689 std::size_t m_countStaRxCtsSuccess; ///< count the number of successfully received CTS frames by
690 ///< the non-participating STA
691 std::size_t m_countStaRxCtsFailure; ///< count the number of unsuccessfully received CTS frames
692 ///< by the non-participating STA
693
694 dBm_u m_stasTxPower; ///< TX power configured for the STAs
695};
696
698 const std::vector<CtsTxInfos>& ctsTxInfosPerSta)
699 : TestCase{"test PHY reception of multiple CTS frames following a MU-RTS frame"},
700 m_ctsTxInfosPerSta{ctsTxInfosPerSta},
706{
707}
708
709void
711{
712 NS_LOG_FUNCTION(this);
713
714 const auto bw =
715 std::max_element(m_ctsTxInfosPerSta.cbegin(),
716 m_ctsTxInfosPerSta.cend(),
717 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
718 ->bw;
719 WifiTxVector txVector;
720 txVector.SetChannelWidth(bw); // only the channel width matters for this test
721
722 // set the TXVECTOR and the UID of the previously transmitted MU-RTS in the AP PHY
723 m_phyAp->SetMuRtsTxVector(txVector);
724 m_phyAp->SetPpduUid(0);
725
726 // set the UID of the previously received MU-RTS in the STAs PHYs
727 for (auto& phySta : m_phyStas)
728 {
729 phySta->SetPpduUid(0);
730 }
731}
732
733void
735{
736 const auto bw = m_ctsTxInfosPerSta.at(phyIndex).bw;
737 const auto discarded = m_ctsTxInfosPerSta.at(phyIndex).discard;
738 NS_LOG_FUNCTION(this << phyIndex << bw << discarded);
739
740 if (discarded)
741 {
742 return;
743 }
744
745 WifiTxVector txVector =
746 WifiTxVector(OfdmPhy::GetOfdmRate54Mbps(), // use less robust modulation for test purpose
747 0,
749 NanoSeconds(800),
750 1,
751 1,
752 0,
753 bw,
754 false,
755 false);
756 txVector.SetTriggerResponding(true);
757
758 WifiMacHeader hdr;
760 hdr.SetDsNotFrom();
761 hdr.SetDsNotTo();
762 hdr.SetNoMoreFragments();
763 hdr.SetNoRetry();
764
765 auto pkt = Create<Packet>();
766 auto mpdu = Create<WifiMpdu>(pkt, hdr);
767 auto psdu = Create<WifiPsdu>(mpdu, false);
768
769 m_phyStas.at(phyIndex)->Send(psdu, txVector);
770}
771
772void
775 RxSignalInfo rxSignalInfo,
776 const WifiTxVector& txVector,
777 const std::vector<bool>& /*statusPerMpdu*/)
778{
779 NS_LOG_FUNCTION(this << phyIndex << *psdu << rxSignalInfo << txVector);
780 std::vector<CtsTxInfos> successfulCtsInfos{};
781 std::copy_if(m_ctsTxInfosPerSta.cbegin(),
782 m_ctsTxInfosPerSta.cend(),
783 std::back_inserter(successfulCtsInfos),
784 [](const auto& info) { return !info.discard; });
785 const auto isAp = (phyIndex == 0);
786 if (isAp)
787 {
788 NS_TEST_EXPECT_MSG_EQ_TOL(rxSignalInfo.rssi,
789 WToDbm(DbmToW(m_stasTxPower) * successfulCtsInfos.size()),
790 0.1,
791 "RX power is not correct!");
792 }
793 auto expectedWidth =
794 std::max_element(successfulCtsInfos.cbegin(),
795 successfulCtsInfos.cend(),
796 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
797 ->bw;
798 if (!isAp)
799 {
800 expectedWidth = std::min(m_ctsTxInfosPerSta.at(phyIndex - 1).bw, expectedWidth);
801 }
803 expectedWidth,
804 "Incorrect channel width in TXVECTOR");
805 if (isAp)
806 {
808 }
809 else
810 {
812 }
813}
814
815void
817{
818 NS_LOG_FUNCTION(this << phyIndex << *psdu);
819 const auto isAp = (phyIndex == 0);
820 if (isAp)
821 {
823 }
824 else
825 {
827 }
828}
829
830void
832{
834 1,
835 "The number of successfully received CTS frames by AP is not correct!");
838 m_ctsTxInfosPerSta.size(),
839 "The number of successfully received CTS frames by non-participating STAs is not correct!");
841 0,
842 "The number of unsuccessfully received CTS frames by AP is not correct!");
844 0,
845 "The number of unsuccessfully received CTS frames by non-participating "
846 "STAs is not correct!");
847}
848
849void
851{
854 int64_t streamNumber = 0;
855
856 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
858 lossModel->SetFrequency(MHzToHz(DEFAULT_FREQUENCY));
859 spectrumChannel->AddPropagationLossModel(lossModel);
861 spectrumChannel->SetPropagationDelayModel(delayModel);
862
863 auto apNode = CreateObject<Node>();
864 auto apDev = CreateObject<WifiNetDevice>();
866 "Txop",
868 apMac->SetAttribute("BeaconGeneration", BooleanValue(false));
869 apDev->SetMac(apMac);
871 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
872 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
873 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
874 auto apErrorModel = CreateObject<NistErrorRateModel>();
875 m_phyAp->SetErrorRateModel(apErrorModel);
876 m_phyAp->SetDevice(apDev);
877 m_phyAp->AddChannel(spectrumChannel);
878 m_phyAp->ConfigureStandard(WIFI_STANDARD_80211ax);
879 m_phyAp->AssignStreams(streamNumber);
880
881 m_phyAp->SetReceiveOkCallback(
883 m_phyAp->SetReceiveErrorCallback(
885
886 const auto apBw =
887 std::max_element(m_ctsTxInfosPerSta.cbegin(),
888 m_ctsTxInfosPerSta.cend(),
889 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
890 ->bw;
891 auto apChannelNum = WifiPhyOperatingChannel::FindFirst(0,
892 MHz_u{0},
893 apBw,
896 ->number;
897
898 m_phyAp->SetOperatingChannel(WifiPhy::ChannelTuple{apChannelNum, apBw, WIFI_PHY_BAND_5GHZ, 0});
899
901 m_phyAp->SetMobility(apMobility);
902 apDev->SetPhy(m_phyAp);
903 apDev->SetStandard(WIFI_STANDARD_80211ax);
904 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
905 apMac->SetWifiPhys({m_phyAp});
906 apNode->AggregateObject(apMobility);
907 apNode->AddDevice(apDev);
908
909 for (std::size_t i = 0; i < m_ctsTxInfosPerSta.size(); ++i)
910 {
911 auto staNode = CreateObject<Node>();
912 auto staDev = CreateObject<WifiNetDevice>();
914 auto staInterferenceHelper = CreateObject<InterferenceHelper>();
915 phySta->SetInterferenceHelper(staInterferenceHelper);
916 auto staErrorModel = CreateObject<NistErrorRateModel>();
917 phySta->SetErrorRateModel(staErrorModel);
918 phySta->SetDevice(staDev);
919 phySta->AddChannel(spectrumChannel);
920 phySta->ConfigureStandard(WIFI_STANDARD_80211ax);
921 phySta->AssignStreams(streamNumber);
922 phySta->SetTxPowerStart(m_stasTxPower);
923 phySta->SetTxPowerEnd(m_stasTxPower);
924
925 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
926 MHz_u{0},
927 m_ctsTxInfosPerSta.at(i).bw,
930 ->number;
931
932 phySta->SetOperatingChannel(
934
936 phySta->SetMobility(staMobility);
937 staDev->SetPhy(phySta);
938 staDev->SetStandard(WIFI_STANDARD_80211ax);
939 staDev->SetHeConfiguration(CreateObject<HeConfiguration>());
940 staNode->AggregateObject(staMobility);
941 staNode->AddDevice(staDev);
942 m_phyStas.push_back(phySta);
943
944 // non-participating HE STA
945 auto nonParticipatingHeStaNode = CreateObject<Node>();
946 auto nonParticipatingHeStaDev = CreateObject<WifiNetDevice>();
947 auto nonParticipatingHePhySta = CreateObject<SpectrumWifiPhy>();
948 auto nonParticipatingHeStaInterferenceHelper = CreateObject<InterferenceHelper>();
949 nonParticipatingHePhySta->SetInterferenceHelper(nonParticipatingHeStaInterferenceHelper);
950 auto nonParticipatingHeStaErrorModel = CreateObject<NistErrorRateModel>();
951 nonParticipatingHePhySta->SetErrorRateModel(nonParticipatingHeStaErrorModel);
952 nonParticipatingHePhySta->SetDevice(nonParticipatingHeStaDev);
953 nonParticipatingHePhySta->AddChannel(spectrumChannel);
954 nonParticipatingHePhySta->ConfigureStandard(WIFI_STANDARD_80211ax);
955
956 nonParticipatingHePhySta->SetOperatingChannel(
958
959 auto nonParticipatingHeStaMobility = CreateObject<ConstantPositionMobilityModel>();
960 nonParticipatingHePhySta->SetMobility(nonParticipatingHeStaMobility);
961 nonParticipatingHeStaDev->SetPhy(nonParticipatingHePhySta);
962 nonParticipatingHeStaDev->SetStandard(WIFI_STANDARD_80211ax);
963 nonParticipatingHeStaDev->SetHeConfiguration(CreateObject<HeConfiguration>());
964 nonParticipatingHePhySta->AssignStreams(streamNumber);
965 nonParticipatingHeStaNode->AggregateObject(nonParticipatingHeStaMobility);
966 nonParticipatingHeStaNode->AddDevice(nonParticipatingHeStaDev);
967
968 nonParticipatingHePhySta->SetReceiveOkCallback(
970 nonParticipatingHePhySta->SetReceiveErrorCallback(
972 }
973
974 // non-HE STA
975 auto nonHeStaNode = CreateObject<Node>();
976 auto nonHeStaDev = CreateObject<WifiNetDevice>();
977 auto nonHePhySta = CreateObject<SpectrumWifiPhy>();
978 auto nonHeStaInterferenceHelper = CreateObject<InterferenceHelper>();
979 nonHePhySta->SetInterferenceHelper(nonHeStaInterferenceHelper);
980 auto nonHeStaErrorModel = CreateObject<NistErrorRateModel>();
981 nonHePhySta->SetErrorRateModel(nonHeStaErrorModel);
982 nonHePhySta->SetDevice(nonHeStaDev);
983 nonHePhySta->AddChannel(spectrumChannel);
984 nonHePhySta->ConfigureStandard(WIFI_STANDARD_80211ac);
985 nonHePhySta->SetOperatingChannel(
986 WifiPhy::ChannelTuple{apChannelNum, apBw, WIFI_PHY_BAND_5GHZ, 0});
987 auto nonHeStaMobility = CreateObject<ConstantPositionMobilityModel>();
988 nonHePhySta->SetMobility(nonHeStaMobility);
989 nonHeStaDev->SetPhy(nonHePhySta);
990 nonHeStaDev->SetStandard(WIFI_STANDARD_80211ac);
991 nonHePhySta->AssignStreams(streamNumber);
992 nonHeStaNode->AggregateObject(nonHeStaMobility);
993 nonHeStaNode->AddDevice(nonHeStaDev);
994}
995
996void
998{
999 m_phyAp->Dispose();
1000 m_phyAp = nullptr;
1001 for (auto& phySta : m_phyStas)
1002 {
1003 phySta->Dispose();
1004 phySta = nullptr;
1005 }
1006 m_phyStas.clear();
1007}
1008
1009void
1011{
1012 // Fake transmission of a MU-RTS frame preceding the CTS responses
1014
1015 for (std::size_t index = 0; index < m_phyStas.size(); ++index)
1016 {
1017 // Transmit CTS responses over their operating bandwidth with 1 nanosecond delay between
1018 // each other
1019 const auto delay = (index + 1) * NanoSeconds(1);
1020 Simulator::Schedule(delay,
1022 this,
1023 index);
1024 }
1025
1026 // Verify successful reception of the CTS frames: since multiple copies are sent
1027 // simultaneously, a single CTS frame should be forwarded up to the MAC.
1029
1032}
1033
1034/**
1035 * @ingroup wifi-test
1036 * @ingroup tests
1037 *
1038 * @brief wifi non-HT duplicate Test Suite
1039 */
1041{
1042 public:
1044};
1045
1047 : TestSuite("wifi-non-ht-dup", Type::UNIT)
1048{
1049 /**
1050 * Channel map:
1051 *
1052 * | 20MHz | 20MHz | 20MHz | 20MHz |
1053 *
1054 * ┌────────┬────────┬────────┬────────┐
1055 * AP 802.11ax │CH 36(P)│ CH 40 │ CH 44 │ CH 48 │
1056 * └────────┴────────┴────────┴────────┘
1057 *
1058 * ┌────────┐
1059 * STA1 802.11a │ CH 36 │
1060 * └────────┘
1061 *
1062 * ┌────────┐
1063 * STA2 802.11n │ CH 40 │
1064 * └────────┘
1065 *
1066 * ┌────────┬────────┐
1067 * STA3 802.11ac │CH 44(P)│ CH 48 │
1068 * └────────┴────────┘
1069 *
1070 * Test scenario:
1071 * ┌────────┐ ┌──────────────────────┐
1072 * │ │ │RX non-HT PPDU @ STA 1│
1073 * │ 80 MHz │ └──────────────────────┘
1074 * │ non-HT │ ┌──────────────────────┐
1075 * │ PPDU │ │RX non-HT PPDU @ STA 2│
1076 * │ sent │ └──────────────────────┘
1077 * │ from │ ┌──────────────────────┐
1078 * │ AP │ │ │
1079 * │ │ │RX non-HT PPDU @ STA 3│
1080 * │ │ │ │
1081 * └────────┘ └──────────────────────┘
1082 */
1084 MHz_u{5210},
1085 0,
1086 {{WIFI_STANDARD_80211a, MHz_u{5180}, 0},
1087 {WIFI_STANDARD_80211n, MHz_u{5200}, 0},
1088 {WIFI_STANDARD_80211ac, MHz_u{5230}, 0}}),
1090 /* same channel map and test scenario as previously but inject interference on channel 40 */
1092 MHz_u{5210},
1093 0,
1094 {{WIFI_STANDARD_80211a, MHz_u{5180}, 0},
1095 {WIFI_STANDARD_80211n, MHz_u{5200}, 0},
1096 {WIFI_STANDARD_80211ac, MHz_u{5230}, 0}},
1097 {false, true, false, false}),
1099 /* test PHY reception of multiple CTS responses following a MU-RTS */
1100 /* 4 STAs operating on 20 MHz */
1102 new TestMultipleCtsResponsesFromMuRts({{MHz_u{20}}, {MHz_u{20}}, {MHz_u{20}}, {MHz_u{20}}}),
1104 /* 4 STAs operating on 40 MHz */
1106 new TestMultipleCtsResponsesFromMuRts({{MHz_u{40}}, {MHz_u{40}}, {MHz_u{40}}, {MHz_u{40}}}),
1108 /* 4 STAs operating on 80 MHz */
1110 new TestMultipleCtsResponsesFromMuRts({{MHz_u{80}}, {MHz_u{80}}, {MHz_u{80}}, {MHz_u{80}}}),
1112 /* 4 STAs operating on 160 MHz */
1114 {{MHz_u{160}}, {MHz_u{160}}, {MHz_u{160}}, {MHz_u{160}}}),
1116 /* 4 STAs operating on different bandwidths with PPDUs sent with decreasing BW: 160, 80, 40 and
1117 * 20 MHz */
1119 {{MHz_u{160}}, {MHz_u{80}}, {MHz_u{40}}, {MHz_u{20}}}),
1121 /* 4 STAs operating on different bandwidths with PPDUs sent with increasing BW: 20, 40, 80 and
1122 * 160 MHz */
1124 {{MHz_u{20}}, {MHz_u{40}}, {MHz_u{80}}, {MHz_u{160}}}),
1126 /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the first STA
1127 * does not respond */
1128 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{MHz_u{80}, true}, {MHz_u{40}, false}}),
1130 /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the second
1131 * STA does not respond */
1132 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{MHz_u{80}, false}, {MHz_u{40}, true}}),
1134 /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the first STA
1135 * does not respond */
1136 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{MHz_u{40}, true}, {MHz_u{80}, false}}),
1138 /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the second
1139 * STA does not respond */
1140 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{MHz_u{40}, false}, {MHz_u{80}, true}}),
1142}
1143
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.
void DoDispose() override
Destructor implementation.
std::shared_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
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:567
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
Definition he-phy.h:556
HePhy(bool buildModeList=true)
Constructor for HE PHY.
Definition he-phy.cc:70
static WifiMode GetOfdmRate54Mbps()
Return a WifiMode for OFDM at 54 Mbps.
static WifiMode GetOfdmRate24Mbps()
Return a WifiMode for OFDM at 24 Mbps.
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
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
void DoInitialize() override
Initialize() implementation.
void DoDispose() override
Destructor implementation.
Hold variables of type string.
Definition string.h:45
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
@ QUICK
Fast test.
Definition test.h:1055
TestCase(const TestCase &)=delete
Type
Type of test.
Definition test.h:1274
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:490
static constexpr auto UNIT
Definition test.h:1291
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
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.
std::map< WifiModulationClass, std::shared_ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition wifi-phy.h:1390
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:944
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition wifi-phy.h:1370
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=GetFrequencyChannels().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:439
#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:1405
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
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:38
double MHz_u
MHz weak type.
Definition wifi-units.h:31
std::size_t Count20MHzSubchannels(MHz_u channelWidth)
Return the number of 20 MHz subchannels covering the channel width.
Definition wifi-utils.h:138
double dBm_u
dBm weak type
Definition wifi-units.h:27
@ WIFI_MAC_CTL_CTS
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:32
Hz_u MHzToHz(MHz_u val)
Convert from MHz to Hz.
Definition wifi-utils.h:113
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)
double Watt_u
Watt weak type.
Definition wifi-units.h:25
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:79
dBm_u rssi
RSSI.
Definition wifi-types.h:81
constexpr MHz_u DEFAULT_FREQUENCY
static WifiNonHtDuplicateTestSuite wifiNonHtDuplicateTestSuite
the test suite