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