A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-non-ht-dup-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
18 */
19
20#include "ns3/ap-wifi-mac.h"
21#include "ns3/boolean.h"
22#include "ns3/constant-position-mobility-model.h"
23#include "ns3/he-configuration.h"
24#include "ns3/he-phy.h"
25#include "ns3/interference-helper.h"
26#include "ns3/log.h"
27#include "ns3/mobility-helper.h"
28#include "ns3/multi-model-spectrum-channel.h"
29#include "ns3/nist-error-rate-model.h"
30#include "ns3/node.h"
31#include "ns3/non-communicating-net-device.h"
32#include "ns3/pointer.h"
33#include "ns3/rng-seed-manager.h"
34#include "ns3/simulator.h"
35#include "ns3/spectrum-wifi-helper.h"
36#include "ns3/spectrum-wifi-phy.h"
37#include "ns3/sta-wifi-mac.h"
38#include "ns3/string.h"
39#include "ns3/test.h"
40#include "ns3/txop.h"
41#include "ns3/waveform-generator.h"
42#include "ns3/wifi-mac-header.h"
43#include "ns3/wifi-net-device.h"
44#include "ns3/wifi-psdu.h"
45#include "ns3/wifi-spectrum-signal-parameters.h"
46#include "ns3/wifi-spectrum-value-helper.h"
47#include "ns3/wifi-utils.h"
48
49#include <vector>
50
51using namespace ns3;
52
53NS_LOG_COMPONENT_DEFINE("WifiNonHtDuplicateTest");
54
55constexpr uint32_t DEFAULT_FREQUENCY = 5180; // MHz
56
57/**
58 * HE PHY used for testing MU-RTS/CTS.
59 */
60class MuRtsCtsHePhy : public HePhy
61{
62 public:
64 ~MuRtsCtsHePhy() override;
65
66 /**
67 * Set the previous TX PPDU UID counter.
68 *
69 * \param uid the value to which the previous TX PPDU UID counter should be set
70 */
71 void SetPreviousTxPpduUid(uint64_t uid);
72
73 /**
74 * Set the TXVECTOR of the previously transmitted MU-RTS.
75 *
76 * \param muRtsTxVector the TXVECTOR used to transmit MU-RTS trigger frame
77 */
78 void SetMuRtsTxVector(const WifiTxVector& muRtsTxVector);
79}; // class MuRtsCtsHePhy
80
82 : HePhy()
83{
84 NS_LOG_FUNCTION(this);
85}
86
88{
89 NS_LOG_FUNCTION(this);
90}
91
92void
94{
95 NS_LOG_FUNCTION(this << uid);
97}
98
99void
101{
102 NS_LOG_FUNCTION(this << muRtsTxVector);
103 m_currentTxVector = muRtsTxVector;
104}
105
106/**
107 * Spectrum PHY used for testing MU-RTS/CTS.
108 */
110{
111 public:
112 /**
113 * \brief Get the type ID.
114 * \return the object TypeId
115 */
116 static TypeId GetTypeId();
117
119 ~MuRtsCtsSpectrumWifiPhy() override;
120
121 void DoInitialize() override;
122 void DoDispose() override;
123
124 /**
125 * Set the global PPDU UID counter.
126 *
127 * \param uid the value to which the global PPDU UID counter should be set
128 */
129 void SetPpduUid(uint64_t uid);
130
131 /**
132 * Set the TXVECTOR of the previously transmitted MU-RTS.
133 *
134 * \param muRtsTxVector the TXVECTOR used to transmit MU-RTS trigger frame
135 */
136 void SetMuRtsTxVector(const WifiTxVector& muRtsTxVector);
137
138 private:
139 Ptr<MuRtsCtsHePhy> m_muRtsCtsHePhy; ///< Pointer to HE PHY instance used for MU-RTS/CTS PHY test
140}; // class MuRtsCtsSpectrumWifiPhy
141
142TypeId
144{
145 static TypeId tid =
146 TypeId("ns3::MuRtsCtsSpectrumWifiPhy").SetParent<SpectrumWifiPhy>().SetGroupName("Wifi");
147 return tid;
148}
149
152{
153 NS_LOG_FUNCTION(this);
154 m_muRtsCtsHePhy = Create<MuRtsCtsHePhy>();
156}
157
159{
160 NS_LOG_FUNCTION(this);
161}
162
163void
165{
166 // Replace HE PHY instance with test instance
169}
170
171void
173{
174 m_muRtsCtsHePhy = nullptr;
176}
177
178void
180{
181 NS_LOG_FUNCTION(this << uid);
184}
185
186void
188{
189 NS_LOG_FUNCTION(this << muRtsTxVector);
190 m_muRtsCtsHePhy->SetMuRtsTxVector(muRtsTxVector);
191}
192
193/**
194 * \ingroup wifi-test
195 * \ingroup tests
196 *
197 * \brief non-HT duplicate PHY reception test
198 * The test consists in an AP sending a single non-HT duplicate PPDU
199 * of a given channel width (multiple of 20 MHz) over a spectrum
200 * channel and it checks whether the STAs attached to the channel
201 * receive the PPDU. If an interference is injected on a given 20 MHz
202 * subchannel, the payload reception should fail, otherwise it should succeed.
203 */
205{
206 public:
207 /// A vector containing parameters per STA: the standard, the center frequency and the P20 index
208 using StasParams = std::vector<std::tuple<WifiStandard, uint16_t, uint8_t>>;
209
210 /**
211 * Constructor
212 * \param apStandard the standard to use for the AP
213 * \param apFrequency the center frequency of the AP (in MHz)
214 * \param apP20Index the index of the primary 20 MHz channel of the AP
215 * \param stasParams the parameters of the STAs (\see StasParams)
216 * \param per20MhzInterference flags per 20 MHz subchannel whether an interference should be
217 * generated on that subchannel. An empty vector means that the test will not generate any
218 * interference.
219 */
221 uint16_t apFrequency,
222 uint8_t apP20Index,
223 StasParams stasParams,
224 std::vector<bool> per20MhzInterference = {});
225
226 private:
227 void DoSetup() override;
228 void DoTeardown() override;
229 void DoRun() override;
230
231 /**
232 * Receive success function
233 * \param index index of the RX STA
234 * \param psdu the PSDU
235 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
236 * \param txVector the transmit vector
237 * \param statusPerMpdu reception status per MPDU
238 */
239 void RxSuccess(std::size_t index,
241 RxSignalInfo rxSignalInfo,
242 WifiTxVector txVector,
243 std::vector<bool> statusPerMpdu);
244
245 /**
246 * Receive failure function
247 * \param index index of the RX STA
248 * \param psdu the PSDU
249 */
250 void RxFailure(std::size_t index, Ptr<const WifiPsdu> psdu);
251
252 /**
253 * Check the results
254 * \param index index of the RX STA
255 * \param expectedRxSuccess the expected number of RX success
256 * \param expectedRxFailure the expected number of RX failures
257 */
258 void CheckResults(std::size_t index, uint32_t expectedRxSuccess, uint32_t expectedRxFailure);
259
260 /**
261 * Reset the results
262 */
263 void ResetResults();
264
265 /**
266 * Send non-HT duplicate PPDU function
267 * \param channelWidth the channel width to use to transmit the non-HT PPDU (in MHz)
268 */
269 void SendNonHtDuplicatePpdu(uint16_t channelWidth);
270
271 /**
272 * Generate interference function
273 * \param interferer the PHY of the interferer to use to generate the signal
274 * \param interferencePsd the PSD of the interference to be generated
275 * \param duration the duration of the interference
276 */
278 Ptr<SpectrumValue> interferencePsd,
279 Time duration);
280 /**
281 * Stop interference function
282 * \param interferer the PHY of the interferer that was used to generate the signal
283 */
285
286 WifiStandard m_apStandard; ///< the standard to use for the AP
287 uint16_t m_apFrequency; ///< the center frequency of the AP (in MHz)
288 uint8_t m_apP20Index; ///< the index of the primary 20 MHz channel of the AP
289 StasParams m_stasParams; ///< the parameters of the STAs
290 std::vector<bool>
291 m_per20MhzInterference; ///< flags per 20 MHz subchannel whether an interference should be
292 ///< generated on that subchannel
293
294 std::vector<uint32_t> m_countRxSuccessStas; ///< count RX success for STAs
295 std::vector<uint32_t> m_countRxFailureStas; ///< count RX failure for STAs
296
298 std::vector<Ptr<SpectrumWifiPhy>> m_phyStas; ///< PHYs of STAs
299
300 std::vector<Ptr<WaveformGenerator>>
301 m_phyInterferers; ///< PHYs of interferers (1 interferer per 20 MHz subchannel)
302};
303
305 WifiStandard apStandard,
306 uint16_t apFrequency,
307 uint8_t apP20Index,
308 StasParams stasParams,
309 std::vector<bool> per20MhzInterference)
310 : TestCase{"non-HT duplicate PHY reception test"},
311 m_apStandard{apStandard},
312 m_apFrequency{apFrequency},
313 m_apP20Index{apP20Index},
314 m_stasParams{stasParams},
315 m_per20MhzInterference{per20MhzInterference},
316 m_countRxSuccessStas{},
317 m_countRxFailureStas{},
318 m_phyStas{}
319{
320}
321
322void
324{
325 for (auto& countRxSuccess : m_countRxSuccessStas)
326 {
327 countRxSuccess = 0;
328 }
329 for (auto& countRxFailure : m_countRxFailureStas)
330 {
331 countRxFailure = 0;
332 }
333}
334
335void
337{
338 NS_LOG_FUNCTION(this << channelWidth);
340 0,
342 800,
343 1,
344 1,
345 0,
346 channelWidth,
347 false);
348
349 Ptr<Packet> pkt = Create<Packet>(1000);
350 WifiMacHeader hdr;
351
353 hdr.SetQosTid(0);
354
355 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(pkt, hdr);
356 Time txDuration =
357 m_phyAp->CalculateTxDuration(psdu->GetSize(), txVector, m_phyAp->GetPhyBand());
358
359 m_phyAp->Send(WifiConstPsduMap({std::make_pair(SU_STA_ID, psdu)}), txVector);
360}
361
362void
364 Ptr<SpectrumValue> interferencePsd,
365 Time duration)
366{
367 NS_LOG_FUNCTION(this << interferer << duration);
368 interferer->SetTxPowerSpectralDensity(interferencePsd);
369 interferer->SetPeriod(duration);
370 interferer->Start();
371 Simulator::Schedule(duration,
373 this,
374 interferer);
375}
376
377void
379{
380 NS_LOG_FUNCTION(this << interferer);
381 interferer->Stop();
382}
383
384void
387 RxSignalInfo rxSignalInfo,
388 WifiTxVector txVector,
389 std::vector<bool> /*statusPerMpdu*/)
390{
391 NS_LOG_FUNCTION(this << index << *psdu << rxSignalInfo << txVector);
392 const auto expectedWidth =
393 std::min(m_phyAp->GetChannelWidth(), m_phyStas.at(index)->GetChannelWidth());
395 expectedWidth,
396 "Incorrect channel width in TXVECTOR");
397 m_countRxSuccessStas.at(index)++;
398}
399
400void
402{
403 NS_LOG_FUNCTION(this << index << *psdu);
404 m_countRxFailureStas.at(index)++;
405}
406
407void
409 uint32_t expectedRxSuccess,
410 uint32_t expectedRxFailure)
411{
412 NS_LOG_FUNCTION(this << index << expectedRxSuccess << expectedRxFailure);
414 expectedRxSuccess,
415 "The number of successfully received packets by STA "
416 << index << " is not correct!");
418 expectedRxFailure,
419 "The number of unsuccessfully received packets by STA "
420 << index << " is not correct!");
421}
422
423void
425{
426 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
427 auto lossModel = CreateObject<FriisPropagationLossModel>();
428 lossModel->SetFrequency(m_apFrequency * 1e6);
429 spectrumChannel->AddPropagationLossModel(lossModel);
430 auto delayModel = CreateObject<ConstantSpeedPropagationDelayModel>();
431 spectrumChannel->SetPropagationDelayModel(delayModel);
432
433 auto apNode = CreateObject<Node>();
434 auto apDev = CreateObject<WifiNetDevice>();
435 m_phyAp = CreateObject<SpectrumWifiPhy>();
436 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
437 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
438 auto apErrorModel = CreateObject<NistErrorRateModel>();
439 m_phyAp->SetErrorRateModel(apErrorModel);
440 m_phyAp->SetDevice(apDev);
441 m_phyAp->AddChannel(spectrumChannel);
443 auto apMobility = CreateObject<ConstantPositionMobilityModel>();
444 m_phyAp->SetMobility(apMobility);
445 apDev->SetPhy(m_phyAp);
446 apNode->AggregateObject(apMobility);
447 apNode->AddDevice(apDev);
448
449 for (const auto& staParams : m_stasParams)
450 {
451 auto staNode = CreateObject<Node>();
452 auto staDev = CreateObject<WifiNetDevice>();
453 auto staPhy = CreateObject<SpectrumWifiPhy>();
454 auto sta1InterferenceHelper = CreateObject<InterferenceHelper>();
455 staPhy->SetInterferenceHelper(sta1InterferenceHelper);
456 auto sta1ErrorModel = CreateObject<NistErrorRateModel>();
457 staPhy->SetErrorRateModel(sta1ErrorModel);
458 staPhy->SetDevice(staDev);
459 staPhy->AddChannel(spectrumChannel);
460 staPhy->ConfigureStandard(std::get<0>(staParams));
461 staPhy->SetReceiveOkCallback(
463 staPhy->SetReceiveErrorCallback(
465 auto staMobility = CreateObject<ConstantPositionMobilityModel>();
466 staPhy->SetMobility(staMobility);
467 staDev->SetPhy(staPhy);
468 staNode->AggregateObject(staMobility);
469 staNode->AddDevice(staDev);
470 m_phyStas.push_back(staPhy);
471 m_countRxSuccessStas.push_back(0);
472 m_countRxFailureStas.push_back(0);
473 }
474
475 if (!m_per20MhzInterference.empty())
476 {
477 [[maybe_unused]] auto [channelNum, centerFreq, apChannelWidth, type, phyBand] =
480 0,
483 NS_ASSERT(m_per20MhzInterference.size() == (apChannelWidth / 20));
484 for (std::size_t i = 0; i < m_per20MhzInterference.size(); ++i)
485 {
486 auto interfererNode = CreateObject<Node>();
487 auto interfererDev = CreateObject<NonCommunicatingNetDevice>();
488 auto phyInterferer = CreateObject<WaveformGenerator>();
489 phyInterferer->SetDevice(interfererDev);
490 phyInterferer->SetChannel(spectrumChannel);
491 phyInterferer->SetDutyCycle(1);
492 interfererNode->AddDevice(interfererDev);
493 m_phyInterferers.push_back(phyInterferer);
494 }
495 }
496}
497
498void
500{
501 m_phyAp->Dispose();
502 m_phyAp = nullptr;
503 for (auto phySta : m_phyStas)
504 {
505 phySta->Dispose();
506 phySta = nullptr;
507 }
508 for (auto phyInterferer : m_phyInterferers)
509 {
510 phyInterferer->Dispose();
511 phyInterferer = nullptr;
512 }
513}
514
515void
517{
520 int64_t streamNumber = 0;
521 m_phyAp->AssignStreams(streamNumber);
522 for (auto phySta : m_phyStas)
523 {
524 phySta->AssignStreams(streamNumber);
525 }
526
527 [[maybe_unused]] auto [apChannelNum, centerFreq, apChannelWidth, type, phyBand] =
530 0,
534 WifiPhy::ChannelTuple{apChannelNum, apChannelWidth, WIFI_PHY_BAND_5GHZ, m_apP20Index});
535
536 auto index = 0;
537 for (const auto& [staStandard, staFrequency, staP20Index] : m_stasParams)
538 {
539 [[maybe_unused]] auto [staChannelNum, centerFreq, staChannelWidth, type, phyBand] =
541 staFrequency,
542 0,
543 staStandard,
545 m_phyStas.at(index++)->SetOperatingChannel(
546 WifiPhy::ChannelTuple{staChannelNum, staChannelWidth, WIFI_PHY_BAND_5GHZ, staP20Index});
547 }
548
549 index = 0;
550 const auto minApCenterFrequency =
551 m_phyAp->GetFrequency() - (m_phyAp->GetChannelWidth() / 2) + (20 / 2);
552 for (auto channelWidth = 20; channelWidth <= apChannelWidth; channelWidth *= 2, ++index)
553 {
554 if (!m_phyInterferers.empty())
555 {
556 for (std::size_t i = 0; i < m_phyInterferers.size(); ++i)
557 {
558 if (!m_per20MhzInterference.at(i))
559 {
560 continue;
561 }
562 BandInfo bandInfo;
563 bandInfo.fc = (minApCenterFrequency + (i * 20)) * 1e6;
564 bandInfo.fl = bandInfo.fc - (5 * 1e6);
565 bandInfo.fh = bandInfo.fc + (5 * 1e6);
566 Bands bands;
567 bands.push_back(bandInfo);
568 auto spectrumInterference = Create<SpectrumModel>(bands);
569 auto interferencePsd = Create<SpectrumValue>(spectrumInterference);
570 auto interferencePower = 0.005; // in watts (designed to make PHY headers reception
571 // successful but payload reception fail)
572 *interferencePsd = interferencePower / 10e6;
575 this,
576 m_phyInterferers.at(i),
577 interferencePsd,
578 Seconds(0.5));
579 }
580 }
581 const auto apCenterFreq =
583 const auto apMinFreq = apCenterFreq - (channelWidth / 2);
584 const auto apMaxFreq = apCenterFreq + (channelWidth / 2);
585 Simulator::Schedule(Seconds(index + 0.1),
587 this,
588 channelWidth);
589 for (std::size_t i = 0; i < m_stasParams.size(); ++i)
590 {
591 const auto p20Width = 20;
592 const auto staP20Freq =
593 m_phyStas.at(i)->GetOperatingChannel().GetPrimaryChannelCenterFrequency(p20Width);
594 const auto staP20MinFreq = staP20Freq - (p20Width / 2);
595 const auto staP20MaxFreq = staP20Freq + (p20Width / 2);
596 bool expectRx = (staP20MinFreq >= apMinFreq && staP20MaxFreq <= apMaxFreq);
597 bool expectSuccess = true;
598 if (!m_per20MhzInterference.empty())
599 {
600 const auto index20MhzSubBand = ((staP20Freq - minApCenterFrequency) / 20);
601 expectSuccess = !m_per20MhzInterference.at(index20MhzSubBand);
602 }
603 Simulator::Schedule(Seconds(index + 0.5),
605 this,
606 i,
607 expectRx ? expectSuccess : 0,
608 expectRx ? !expectSuccess : 0);
609 }
610 Simulator::Schedule(Seconds(index + 0.5),
612 this);
613 }
614
617}
618
619/**
620 * \ingroup wifi-test
621 * \ingroup tests
622 *
623 * \brief test PHY reception of multiple CTS frames as a response to a MU-RTS frame.
624 * The test is checking whether the reception of multiple identical CTS frames as a response to a
625 * MU-RTS frame is successfully received by the AP PHY and that only a single CTS frame is forwarded
626 * up to the MAC. Since the test is focusing on the PHY reception of multiple CTS response, the
627 * transmission of the MU-RTS frame is faked. The test also checks the correct channel width is
628 * passed to the MAC layer through the TXVECTOR. The test also consider the case some STAs do not
629 * respond to verify the largest channel width of the successfully CTS responses is reported to the
630 * MAC.
631 */
633{
634 public:
635 /// Information about CTS responses to expect in the test
637 {
638 uint16_t bw{20}; ///< the width in MHz of the CTS response
639 bool discard{false}; ///< flag whether the CTS response shall be discarded
640 };
641
642 /**
643 * Constructor
644 * \param ctsTxInfosPerSta the information about CTS responses to generate
645 */
646 TestMultipleCtsResponsesFromMuRts(const std::vector<CtsTxInfos>& ctsTxInfosPerSta);
647
648 private:
649 void DoSetup() override;
650 void DoTeardown() override;
651 void DoRun() override;
652
653 /**
654 * Function called to fake the transmission of a MU-RTS.
655 */
656 void FakePreviousMuRts();
657
658 /**
659 * Function called to trigger a CTS frame sent by a STA using non-HT duplicate.
660 *
661 * \param phyIndex the index of the TX PHY
662 */
663 void TxNonHtDuplicateCts(std::size_t phyIndex);
664
665 /**
666 * CTS RX success function
667 * \param phyIndex the index of the PHY (0 for AP)
668 * \param psdu the PSDU
669 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
670 * \param txVector the transmit vector
671 * \param statusPerMpdu reception status per MPDU
672 */
673 void RxCtsSuccess(std::size_t phyIndex,
675 RxSignalInfo rxSignalInfo,
676 WifiTxVector txVector,
677 std::vector<bool> statusPerMpdu);
678
679 /**
680 * CTS RX failure function
681 * \param phyIndex the index of the PHY (0 for AP)
682 * \param psdu the PSDU
683 */
684 void RxCtsFailure(std::size_t phyIndex, Ptr<const WifiPsdu> psdu);
685
686 /**
687 * Check the results
688 */
689 void CheckResults();
690
692 std::vector<Ptr<MuRtsCtsSpectrumWifiPhy>> m_phyStas; ///< STAs PHYs
693
694 std::vector<CtsTxInfos> m_ctsTxInfosPerSta; ///< information about CTS responses
695
696 std::size_t
697 m_countApRxCtsSuccess; ///< count the number of successfully received CTS frames by the AP
698 std::size_t
699 m_countApRxCtsFailure; ///< count the number of unsuccessfully received CTS frames by the AP
700 std::size_t m_countStaRxCtsSuccess; ///< count the number of successfully received CTS frames by
701 ///< the non-participating STA
702 std::size_t m_countStaRxCtsFailure; ///< count the number of unsuccessfully received CTS frames
703 ///< by the non-participating STA
704
705 double m_stasTxPowerDbm; ///< TX power in dBm configured for the STAs
706};
707
709 const std::vector<CtsTxInfos>& ctsTxInfosPerSta)
710 : TestCase{"test PHY reception of multiple CTS frames following a MU-RTS frame"},
711 m_ctsTxInfosPerSta{ctsTxInfosPerSta},
712 m_countApRxCtsSuccess{0},
713 m_countApRxCtsFailure{0},
714 m_countStaRxCtsSuccess{0},
715 m_countStaRxCtsFailure{0},
716 m_stasTxPowerDbm(10.0)
717{
718}
719
720void
722{
723 NS_LOG_FUNCTION(this);
724
725 const auto bw =
726 std::max_element(m_ctsTxInfosPerSta.cbegin(),
727 m_ctsTxInfosPerSta.cend(),
728 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
729 ->bw;
730 WifiTxVector txVector;
731 txVector.SetChannelWidth(bw); // only the channel width matters for this test
732
733 // set the TXVECTOR and the UID of the previously transmitted MU-RTS in the AP PHY
734 m_phyAp->SetMuRtsTxVector(txVector);
736
737 // set the UID of the previously received MU-RTS in the STAs PHYs
738 for (auto& phySta : m_phyStas)
739 {
740 phySta->SetPpduUid(0);
741 }
742}
743
744void
746{
747 const auto bw = m_ctsTxInfosPerSta.at(phyIndex).bw;
748 const auto discarded = m_ctsTxInfosPerSta.at(phyIndex).discard;
749 NS_LOG_FUNCTION(this << phyIndex << bw << discarded);
750
751 if (discarded)
752 {
753 return;
754 }
755
756 WifiTxVector txVector =
757 WifiTxVector(OfdmPhy::GetOfdmRate54Mbps(), // use less robust modulation for test purpose
758 0,
760 800,
761 1,
762 1,
763 0,
764 bw,
765 false,
766 false);
767 txVector.SetTriggerResponding(true);
768
769 WifiMacHeader hdr;
771 hdr.SetDsNotFrom();
772 hdr.SetDsNotTo();
773 hdr.SetNoMoreFragments();
774 hdr.SetNoRetry();
775
776 auto pkt = Create<Packet>();
777 auto mpdu = Create<WifiMpdu>(pkt, hdr);
778 auto psdu = Create<WifiPsdu>(mpdu, false);
779
780 m_phyStas.at(phyIndex)->Send(psdu, txVector);
781}
782
783void
786 RxSignalInfo rxSignalInfo,
787 WifiTxVector txVector,
788 std::vector<bool> /*statusPerMpdu*/)
789{
790 NS_LOG_FUNCTION(this << phyIndex << *psdu << rxSignalInfo << txVector);
791 std::vector<CtsTxInfos> successfulCtsInfos{};
792 std::copy_if(m_ctsTxInfosPerSta.cbegin(),
793 m_ctsTxInfosPerSta.cend(),
794 std::back_inserter(successfulCtsInfos),
795 [](const auto& info) { return !info.discard; });
796 const auto isAp = (phyIndex == 0);
797 if (isAp)
798 {
799 NS_TEST_EXPECT_MSG_EQ_TOL(rxSignalInfo.rssi,
800 WToDbm(DbmToW(m_stasTxPowerDbm) * successfulCtsInfos.size()),
801 0.1,
802 "RX power is not correct!");
803 }
804 auto expectedWidth =
805 std::max_element(successfulCtsInfos.cbegin(),
806 successfulCtsInfos.cend(),
807 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
808 ->bw;
809 if (!isAp)
810 {
811 expectedWidth = std::min(m_ctsTxInfosPerSta.at(phyIndex - 1).bw, expectedWidth);
812 }
814 expectedWidth,
815 "Incorrect channel width in TXVECTOR");
816 if (isAp)
817 {
819 }
820 else
821 {
823 }
824}
825
826void
828{
829 NS_LOG_FUNCTION(this << phyIndex << *psdu);
830 const auto isAp = (phyIndex == 0);
831 if (isAp)
832 {
834 }
835 else
836 {
838 }
839}
840
841void
843{
845 1,
846 "The number of successfully received CTS frames by AP is not correct!");
849 m_ctsTxInfosPerSta.size(),
850 "The number of successfully received CTS frames by non-participating STAs is not correct!");
852 0,
853 "The number of unsuccessfully received CTS frames by AP is not correct!");
855 0,
856 "The number of unsuccessfully received CTS frames by non-participating "
857 "STAs is not correct!");
858}
859
860void
862{
865 int64_t streamNumber = 0;
866
867 auto spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
868 auto lossModel = CreateObject<FriisPropagationLossModel>();
869 lossModel->SetFrequency(DEFAULT_FREQUENCY * 1e6);
870 spectrumChannel->AddPropagationLossModel(lossModel);
871 auto delayModel = CreateObject<ConstantSpeedPropagationDelayModel>();
872 spectrumChannel->SetPropagationDelayModel(delayModel);
873
874 auto apNode = CreateObject<Node>();
875 auto apDev = CreateObject<WifiNetDevice>();
876 auto apMac = CreateObjectWithAttributes<ApWifiMac>(
877 "Txop",
878 PointerValue(CreateObjectWithAttributes<Txop>("AcIndex", StringValue("AC_BE_NQOS"))));
879 apMac->SetAttribute("BeaconGeneration", BooleanValue(false));
880 apDev->SetMac(apMac);
881 m_phyAp = CreateObject<MuRtsCtsSpectrumWifiPhy>();
882 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
883 auto apInterferenceHelper = CreateObject<InterferenceHelper>();
884 m_phyAp->SetInterferenceHelper(apInterferenceHelper);
885 auto apErrorModel = CreateObject<NistErrorRateModel>();
886 m_phyAp->SetErrorRateModel(apErrorModel);
887 m_phyAp->SetDevice(apDev);
888 m_phyAp->AddChannel(spectrumChannel);
890 m_phyAp->AssignStreams(streamNumber);
891
896
897 const auto apBw =
898 std::max_element(m_ctsTxInfosPerSta.cbegin(),
899 m_ctsTxInfosPerSta.cend(),
900 [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; })
901 ->bw;
902 auto apChannelNum = std::get<0>(
904
906
907 auto apMobility = CreateObject<ConstantPositionMobilityModel>();
908 m_phyAp->SetMobility(apMobility);
909 apDev->SetPhy(m_phyAp);
910 apDev->SetStandard(WIFI_STANDARD_80211ax);
911 apDev->SetHeConfiguration(CreateObject<HeConfiguration>());
912 apMac->SetWifiPhys({m_phyAp});
913 apNode->AggregateObject(apMobility);
914 apNode->AddDevice(apDev);
915
916 for (std::size_t i = 0; i < m_ctsTxInfosPerSta.size(); ++i)
917 {
918 auto staNode = CreateObject<Node>();
919 auto staDev = CreateObject<WifiNetDevice>();
920 auto phySta = CreateObject<MuRtsCtsSpectrumWifiPhy>();
921 auto staInterferenceHelper = CreateObject<InterferenceHelper>();
922 phySta->SetInterferenceHelper(staInterferenceHelper);
923 auto staErrorModel = CreateObject<NistErrorRateModel>();
924 phySta->SetErrorRateModel(staErrorModel);
925 phySta->SetDevice(staDev);
926 phySta->AddChannel(spectrumChannel);
927 phySta->ConfigureStandard(WIFI_STANDARD_80211ax);
928 phySta->AssignStreams(streamNumber);
929 phySta->SetTxPowerStart(m_stasTxPowerDbm);
930 phySta->SetTxPowerEnd(m_stasTxPowerDbm);
931
932 auto channelNum =
934 0,
935 m_ctsTxInfosPerSta.at(i).bw,
938
939 phySta->SetOperatingChannel(
941
942 auto staMobility = CreateObject<ConstantPositionMobilityModel>();
943 phySta->SetMobility(staMobility);
944 staDev->SetPhy(phySta);
945 staDev->SetStandard(WIFI_STANDARD_80211ax);
946 staDev->SetHeConfiguration(CreateObject<HeConfiguration>());
947 staNode->AggregateObject(staMobility);
948 staNode->AddDevice(staDev);
949 m_phyStas.push_back(phySta);
950
951 // non-participating HE STA
952 auto nonParticipatingHeStaNode = CreateObject<Node>();
953 auto nonParticipatingHeStaDev = CreateObject<WifiNetDevice>();
954 auto nonParticipatingHePhySta = CreateObject<SpectrumWifiPhy>();
955 auto nonParticipatingHeStaInterferenceHelper = CreateObject<InterferenceHelper>();
956 nonParticipatingHePhySta->SetInterferenceHelper(nonParticipatingHeStaInterferenceHelper);
957 auto nonParticipatingHeStaErrorModel = CreateObject<NistErrorRateModel>();
958 nonParticipatingHePhySta->SetErrorRateModel(nonParticipatingHeStaErrorModel);
959 nonParticipatingHePhySta->SetDevice(nonParticipatingHeStaDev);
960 nonParticipatingHePhySta->AddChannel(spectrumChannel);
961 nonParticipatingHePhySta->ConfigureStandard(WIFI_STANDARD_80211ax);
962
963 nonParticipatingHePhySta->SetOperatingChannel(
965
966 auto nonParticipatingHeStaMobility = CreateObject<ConstantPositionMobilityModel>();
967 nonParticipatingHePhySta->SetMobility(nonParticipatingHeStaMobility);
968 nonParticipatingHeStaDev->SetPhy(nonParticipatingHePhySta);
969 nonParticipatingHeStaDev->SetStandard(WIFI_STANDARD_80211ax);
970 nonParticipatingHeStaDev->SetHeConfiguration(CreateObject<HeConfiguration>());
971 nonParticipatingHePhySta->AssignStreams(streamNumber);
972 nonParticipatingHeStaNode->AggregateObject(nonParticipatingHeStaMobility);
973 nonParticipatingHeStaNode->AddDevice(nonParticipatingHeStaDev);
974
975 nonParticipatingHePhySta->SetReceiveOkCallback(
977 nonParticipatingHePhySta->SetReceiveErrorCallback(
979 }
980
981 // non-HE STA
982 auto nonHeStaNode = CreateObject<Node>();
983 auto nonHeStaDev = CreateObject<WifiNetDevice>();
984 auto nonHePhySta = CreateObject<SpectrumWifiPhy>();
985 auto nonHeStaInterferenceHelper = CreateObject<InterferenceHelper>();
986 nonHePhySta->SetInterferenceHelper(nonHeStaInterferenceHelper);
987 auto nonHeStaErrorModel = CreateObject<NistErrorRateModel>();
988 nonHePhySta->SetErrorRateModel(nonHeStaErrorModel);
989 nonHePhySta->SetDevice(nonHeStaDev);
990 nonHePhySta->AddChannel(spectrumChannel);
991 nonHePhySta->ConfigureStandard(WIFI_STANDARD_80211ac);
992 nonHePhySta->SetOperatingChannel(
993 WifiPhy::ChannelTuple{apChannelNum, apBw, WIFI_PHY_BAND_5GHZ, 0});
994 auto nonHeStaMobility = CreateObject<ConstantPositionMobilityModel>();
995 nonHePhySta->SetMobility(nonHeStaMobility);
996 nonHeStaDev->SetPhy(nonHePhySta);
997 nonHeStaDev->SetStandard(WIFI_STANDARD_80211ac);
998 nonHePhySta->AssignStreams(streamNumber);
999 nonHeStaNode->AggregateObject(nonHeStaMobility);
1000 nonHeStaNode->AddDevice(nonHeStaDev);
1001}
1002
1003void
1005{
1006 m_phyAp->Dispose();
1007 m_phyAp = nullptr;
1008 for (auto& phySta : m_phyStas)
1009 {
1010 phySta->Dispose();
1011 phySta = nullptr;
1012 }
1013 m_phyStas.clear();
1014}
1015
1016void
1018{
1019 // Fake transmission of a MU-RTS frame preceding the CTS responses
1021
1022 for (std::size_t index = 0; index < m_phyStas.size(); ++index)
1023 {
1024 // Transmit CTS responses over their operating bandwidth with 1 nanosecond delay between
1025 // each other
1026 const auto delay = (index + 1) * NanoSeconds(1.0);
1027 Simulator::Schedule(delay,
1029 this,
1030 index);
1031 }
1032
1033 // Verify successful reception of the CTS frames: since multiple copies are sent
1034 // simultaneously, a single CTS frame should be forwarded up to the MAC.
1036
1039}
1040
1041/**
1042 * \ingroup wifi-test
1043 * \ingroup tests
1044 *
1045 * \brief wifi non-HT duplicate Test Suite
1046 */
1048{
1049 public:
1051};
1052
1054 : TestSuite("wifi-non-ht-dup", Type::UNIT)
1055{
1056 /**
1057 * Channel map:
1058 *
1059 * | 20MHz | 20MHz | 20MHz | 20MHz |
1060 *
1061 * ┌────────┬────────┬────────┬────────┐
1062 * AP 802.11ax │CH 36(P)│ CH 40 │ CH 44 │ CH 48 │
1063 * └────────┴────────┴────────┴────────┘
1064 *
1065 * ┌────────┐
1066 * STA1 802.11a │ CH 36 │
1067 * └────────┘
1068 *
1069 * ┌────────┐
1070 * STA2 802.11n │ CH 40 │
1071 * └────────┘
1072 *
1073 * ┌────────┬────────┐
1074 * STA3 802.11ac │CH 44(P)│ CH 48 │
1075 * └────────┴────────┘
1076 *
1077 * Test scenario:
1078 * ┌────────┐ ┌──────────────────────┐
1079 * │ │ │RX non-HT PPDU @ STA 1│
1080 * │ 80 MHz │ └──────────────────────┘
1081 * │ non-HT │ ┌──────────────────────┐
1082 * │ PPDU │ │RX non-HT PPDU @ STA 2│
1083 * │ sent │ └──────────────────────┘
1084 * │ from │ ┌──────────────────────┐
1085 * │ AP │ │ │
1086 * │ │ │RX non-HT PPDU @ STA 3│
1087 * │ │ │ │
1088 * └────────┘ └──────────────────────┘
1089 */
1091 5210,
1092 0,
1093 {{WIFI_STANDARD_80211a, 5180, 0},
1094 {WIFI_STANDARD_80211n, 5200, 0},
1095 {WIFI_STANDARD_80211ac, 5230, 0}}),
1096 TestCase::Duration::QUICK);
1097 /* same channel map and test scenario as previously but inject interference on channel 40 */
1099 5210,
1100 0,
1101 {{WIFI_STANDARD_80211a, 5180, 0},
1102 {WIFI_STANDARD_80211n, 5200, 0},
1103 {WIFI_STANDARD_80211ac, 5230, 0}},
1104 {false, true, false, false}),
1105 TestCase::Duration::QUICK);
1106 /* test PHY reception of multiple CTS responses following a MU-RTS */
1107 /* 4 STAs operating on 20 MHz */
1108 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{20}, {20}, {20}, {20}}),
1109 TestCase::Duration::QUICK);
1110 /* 4 STAs operating on 40 MHz */
1111 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{40}, {40}, {40}, {40}}),
1112 TestCase::Duration::QUICK);
1113 /* 4 STAs operating on 80 MHz */
1114 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{80}, {80}, {80}, {80}}),
1115 TestCase::Duration::QUICK);
1116 /* 4 STAs operating on 160 MHz */
1117 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{160}, {160}, {160}, {160}}),
1118 TestCase::Duration::QUICK);
1119 /* 4 STAs operating on different bandwidths with PPDUs sent with decreasing BW: 160, 80, 40 and
1120 * 20 MHz */
1121 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{160}, {80}, {40}, {20}}),
1122 TestCase::Duration::QUICK);
1123 /* 4 STAs operating on different bandwidths with PPDUs sent with increasing BW: 20, 40, 80 and
1124 * 160 MHz */
1125 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{20}, {40}, {80}, {160}}),
1126 TestCase::Duration::QUICK);
1127 /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the first STA
1128 * does not respond */
1129 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{80, true}, {40, false}}),
1130 TestCase::Duration::QUICK);
1131 /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the second
1132 * STA does not respond */
1133 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{80, false}, {40, true}}),
1134 TestCase::Duration::QUICK);
1135 /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the first STA
1136 * does not respond */
1137 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{40, true}, {80, false}}),
1138 TestCase::Duration::QUICK);
1139 /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the second
1140 * STA does not respond */
1141 AddTestCase(new TestMultipleCtsResponsesFromMuRts({{40, false}, {80, true}}),
1142 TestCase::Duration::QUICK);
1143}
1144
HE PHY used for testing MU-RTS/CTS.
void SetPreviousTxPpduUid(uint64_t uid)
Set the previous TX PPDU UID counter.
void SetMuRtsTxVector(const WifiTxVector &muRtsTxVector)
Set the TXVECTOR of the previously transmitted MU-RTS.
~MuRtsCtsHePhy() override
Spectrum PHY used for testing MU-RTS/CTS.
void DoDispose() override
Destructor implementation.
Ptr< MuRtsCtsHePhy > m_muRtsCtsHePhy
Pointer to HE PHY instance used for MU-RTS/CTS PHY test.
void SetPpduUid(uint64_t uid)
Set the global PPDU UID counter.
void SetMuRtsTxVector(const WifiTxVector &muRtsTxVector)
Set the TXVECTOR of the previously transmitted MU-RTS.
void DoInitialize() override
Initialize() implementation.
static TypeId GetTypeId()
Get the type ID.
test PHY reception of multiple CTS frames as a response to a MU-RTS frame.
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
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.
double m_stasTxPowerDbm
TX power in dBm configured for the STAs.
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...
void GenerateInterference(Ptr< WaveformGenerator > interferer, Ptr< SpectrumValue > interferencePsd, Time duration)
Generate interference function.
std::vector< bool > m_per20MhzInterference
flags per 20 MHz subchannel whether an interference should be generated on that subchannel
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void ResetResults()
Reset the results.
std::vector< Ptr< SpectrumWifiPhy > > m_phyStas
PHYs of STAs.
void RxFailure(std::size_t index, Ptr< const WifiPsdu > psdu)
Receive failure function.
std::vector< uint32_t > m_countRxFailureStas
count RX failure for STAs
void SendNonHtDuplicatePpdu(uint16_t channelWidth)
Send non-HT duplicate PPDU function.
StasParams m_stasParams
the parameters of the STAs
std::vector< std::tuple< WifiStandard, uint16_t, uint8_t > > StasParams
A vector containing parameters per STA: the standard, the center frequency and the P20 index.
void CheckResults(std::size_t index, uint32_t expectedRxSuccess, uint32_t expectedRxFailure)
Check the results.
void StopInterference(Ptr< WaveformGenerator > interferer)
Stop interference function.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
TestNonHtDuplicatePhyReception(WifiStandard apStandard, uint16_t apFrequency, uint8_t apP20Index, StasParams stasParams, std::vector< bool > per20MhzInterference={})
Constructor.
void RxSuccess(std::size_t index, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive success function.
WifiStandard m_apStandard
the standard to use for the AP
Ptr< SpectrumWifiPhy > m_phyAp
PHY of AP.
uint8_t m_apP20Index
the index of the primary 20 MHz channel of the AP
void DoRun() override
Implementation to actually run this TestCase.
std::vector< uint32_t > m_countRxSuccessStas
count RX success for STAs
std::vector< Ptr< WaveformGenerator > > m_phyInterferers
PHYs of interferers (1 interferer per 20 MHz subchannel)
uint16_t m_apFrequency
the center frequency of the AP (in MHz)
wifi non-HT duplicate Test Suite
PHY entity for HE (11ax)
Definition: he-phy.h:68
std::optional< WifiTxVector > m_currentTxVector
If the STA is an AP STA, this holds the TXVECTOR of the PPDU that has been sent.
Definition: he-phy.h: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
void Dispose()
Dispose of this Object.
Definition: object.cc:258
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:92
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
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:56
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:302
A suite of tests to run.
Definition: test.h:1273
Type
Type of test.
Definition: test.h:1280
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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:662
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument.
Definition: wifi-phy.cc:1759
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:671
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1083
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1071
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:473
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:993
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1539
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1358
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:1130
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1053
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1338
std::tuple< uint8_t, uint16_t, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:926
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:637
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:467
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1065
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:2298
static ConstIterator FindFirst(uint8_t number, uint16_t frequency, uint16_t width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first channel matching the specified parameters.
uint16_t GetPrimaryChannelCenterFrequency(uint16_t primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetTriggerResponding(bool triggerResponding)
Set the Trigger Responding parameter to the given value.
uint16_t 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:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:145
#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:511
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1355
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_PREAMBLE_LONG
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:48
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:700
std::vector< BandInfo > Bands
Container of BandInfo.
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:42
@ WIFI_MAC_CTL_CTS
@ WIFI_MAC_QOSDATA
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
Information about CTS responses to expect in the test.
uint16_t bw
the width in MHz of the CTS response
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: phy-entity.h:69
double rssi
RSSI in dBm.
Definition: phy-entity.h:71
static WifiNonHtDuplicateTestSuite wifiNonHtDuplicateTestSuite
the test suite
constexpr uint32_t DEFAULT_FREQUENCY