A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-operating-channel-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7 */
8
9#include "ns3/he-phy.h"
10#include "ns3/he-ppdu.h"
11#include "ns3/interference-helper.h"
12#include "ns3/log.h"
13#include "ns3/multi-model-spectrum-channel.h"
14#include "ns3/nist-error-rate-model.h"
15#include "ns3/node.h"
16#include "ns3/spectrum-wifi-phy.h"
17#include "ns3/string.h"
18#include "ns3/test.h"
19#include "ns3/wifi-net-device.h"
20#include "ns3/wifi-phy-operating-channel.h"
21#include "ns3/wifi-psdu.h"
22#include "ns3/wifi-utils.h"
23
24using namespace ns3;
25
26NS_LOG_COMPONENT_DEFINE("WifiOperatingChannelTest");
27
28/**
29 * @ingroup wifi-test
30 * @ingroup tests
31 *
32 * @brief Test the WifiPhyOperatingChannel::Set() method.
33 */
35{
36 public:
37 /**
38 * Constructor
39 */
41 ~SetWifiOperatingChannelTest() override = default;
42
43 private:
44 void DoRun() override;
45
46 /**
47 * Run one function.
48 * @param runInfo the string that indicates info about the test case to run
49 * @param segments the info about each frequency segment to set for the operating channel
50 * @param standard the 802.11 standard to consider for the test
51 * @param band the PHY band to consider for the test
52 * @param expectExceptionThrown flag to indicate whether an exception is expected to be thrown
53 * @param expectedWidth the expected width type of the operating channel
54 * @param expectedSegments the info about the expected frequency segments of the operating
55 * channel
56 */
57 void RunOne(const std::string& runInfo,
58 const std::vector<FrequencyChannelInfo>& segments,
59 WifiStandard standard,
60 WifiPhyBand band,
62 WifiChannelWidthType expectedWidth = WifiChannelWidthType::UNKNOWN,
63 const std::vector<FrequencyChannelInfo>& expectedSegments = {});
64
65 WifiPhyOperatingChannel m_channel; //!< operating channel
66};
67
69 : TestCase("Check configuration of the operating channel")
70{
71}
72
73void
75 const std::vector<FrequencyChannelInfo>& segments,
76 WifiStandard standard,
77 WifiPhyBand band,
80 const std::vector<FrequencyChannelInfo>& expectedSegments)
81{
82 NS_LOG_FUNCTION(this << runInfo);
83
84 bool exceptionThrown = false;
85 try
86 {
87 m_channel.Set(segments, standard);
88 }
89 catch (const std::runtime_error&)
90 {
91 exceptionThrown = true;
92 }
95 "Exception thrown mismatch for run: " << runInfo);
96 if (!exceptionThrown)
97 {
101 "Operating channel has an incorrect channel width type for run: " << runInfo);
103 expectedSegments.size(),
104 "Incorrect number of frequency segments for run: " << runInfo);
105 for (std::size_t i = 0; i < m_channel.GetNSegments(); ++i)
106 {
107 const auto& frequencyChannelInfo = expectedSegments.at(i);
110 "Operating channel has an incorrect channel number at segment "
111 << i << " for run: " << runInfo);
113 frequencyChannelInfo.frequency,
114 "Operating channel has an incorrect center frequency at segment "
115 << i << " for run: " << runInfo);
118 "Operating channel has an incorrect channel width at segment "
119 << i << " for run: " << runInfo);
122 "Operating channel has an incorrect band for run: " << runInfo);
123 }
124 }
125}
126
127void
129{
130 RunOne("dummy channel with all inputs unset",
131 {{}},
134 true);
135
136 RunOne("default 20 MHz OFDM channel operating on channel 36",
137 {{36, MHz_u{0}, MHz_u{20}, WIFI_PHY_BAND_5GHZ}},
140 false,
141 WifiChannelWidthType::CW_20MHZ,
142 {{36, MHz_u{5180}, MHz_u{20}, WIFI_PHY_BAND_5GHZ, FrequencyChannelType::OFDM}});
143
144 RunOne("default 40 MHz OFDM channel operating on channel 38",
145 {{38, MHz_u{0}, MHz_u{40}, WIFI_PHY_BAND_5GHZ}},
148 false,
149 WifiChannelWidthType::CW_40MHZ,
150 {{38, MHz_u{5190}, MHz_u{40}, WIFI_PHY_BAND_5GHZ, FrequencyChannelType::OFDM}});
151
152 RunOne("default 80 MHz OFDM channel operating on channel 42",
153 {{42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
156 false,
157 WifiChannelWidthType::CW_80MHZ,
158 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ, FrequencyChannelType::OFDM}});
159
160 RunOne("default 160 MHz (contiguous) OFDM channel operating on channel 50",
161 {{50, MHz_u{0}, MHz_u{160}, WIFI_PHY_BAND_5GHZ}},
164 false,
165 WifiChannelWidthType::CW_160MHZ,
166 {{50, MHz_u{5250}, MHz_u{160}, WIFI_PHY_BAND_5GHZ, FrequencyChannelType::OFDM}});
167
168 RunOne("valid 80+80 MHz (non-contiguous) OFDM channel operating on channels 42 and 106",
169 {{42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
170 {106, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
173 false,
174 WifiChannelWidthType::CW_80_PLUS_80MHZ,
175 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ, FrequencyChannelType::OFDM},
176 {106, MHz_u{5530}, MHz_u{80}, WIFI_PHY_BAND_5GHZ, FrequencyChannelType::OFDM}});
177
178 RunOne("invalid 80+80 MHz (non-contiguous) OFDM channel higher channel not being 80 MHz",
179 {{42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
180 {102, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
183 true);
184
185 RunOne("invalid 80+80 MHz (non-contiguous) OFDM channel lower channel not being 80 MHz",
186 {{36, MHz_u{0}, MHz_u{20}, WIFI_PHY_BAND_5GHZ},
187 {106, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
190 true);
191
192 RunOne("invalid 80+80 MHz (non-contiguous) OFDM channel with both segments configured on the "
193 "same channel",
194 {{42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
195 {42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
198 true);
199
200 RunOne("invalid 80+80 MHz (non-contiguous) OFDM channel with segments configured to be "
201 "contiguous (lower before higher)",
202 {{42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
203 {58, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
206 true);
207
208 RunOne("invalid 80+80 MHz (non-contiguous) OFDM channel with segments configured to be "
209 "contiguous (higher before lower)",
210 {{58, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
211 {42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
214 true);
215
216 RunOne("invalid 80+80 MHz (non-contiguous) OFDM channel with each segments configured on a "
217 "different band",
218 {{42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
219 {215, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_6GHZ}},
222 true);
223}
224
225/**
226 * @ingroup wifi-test
227 * @ingroup tests
228 *
229 * @brief Test the conversion from PHY ChannelSettings attribute to WifiPhyOperatingChannel.
230 */
232{
233 public:
234 /**
235 * Constructor
236 */
239
240 private:
241 void DoSetup() override;
242 void DoTeardown() override;
243 void DoRun() override;
244
245 /**
246 * Run one function.
247 * @param channelSettings the string to set the ChannelSettings attribute
248 * @param expectedWidthType the expected width type of the operating channel
249 * @param expectedSegments the info about each expected segment of the operating channel
250 * @param expectedP20Index the expected index of the P20
251 */
252 void RunOne(const std::string& channelSettings,
254 const std::vector<FrequencyChannelInfo>& expectedSegments,
255 uint8_t expectedP20Index);
256
258};
259
261 : TestCase("Check conversion from attribute to the operating channel")
262{
263}
264
265void
267{
269 auto node = CreateObject<Node>();
270 auto dev = CreateObject<WifiNetDevice>();
273 m_phy->SetInterferenceHelper(interferenceHelper);
275 m_phy->SetErrorRateModel(error);
276 m_phy->SetDevice(dev);
277 m_phy->AddChannel(spectrumChannel);
278 m_phy->ConfigureStandard(WIFI_STANDARD_80211ax);
279 dev->SetPhy(m_phy);
280 node->AddDevice(dev);
281}
282
283void
285{
286 m_phy->Dispose();
287 m_phy = nullptr;
288}
289
290void
292 const std::string& channelSettings,
294 const std::vector<FrequencyChannelInfo>& expectedSegments,
295 uint8_t expectedP20Index)
296{
298
299 bool exceptionThrown = false;
300 try
301 {
302 m_phy->SetAttribute("ChannelSettings", StringValue(channelSettings));
303 }
304 catch (const std::runtime_error&)
305 {
306 exceptionThrown = true;
307 }
309 expectedSegments.empty(),
310 "Exception thrown mismatch for channel settings " << channelSettings);
311
312 if (exceptionThrown)
313 {
314 return;
315 }
316
318 m_phy->GetOperatingChannel().GetWidthType(),
320 "Operating channel has an incorrect channel width type for channel settings "
321 << channelSettings);
322
323 const auto numSegments = m_phy->GetOperatingChannel().GetNSegments();
326 expectedSegments.size(),
327 "Operating channel has an incorrect number of segments for channel settings "
328 << channelSettings);
329
330 for (std::size_t i = 0; i < numSegments; ++i)
331 {
332 NS_TEST_ASSERT_MSG_EQ(m_phy->GetOperatingChannel().GetNumber(i),
333 expectedSegments.at(i).number,
334 "Operating channel has an incorrect channel number at segment "
335 << i << " for channel settings " << channelSettings);
336 NS_TEST_ASSERT_MSG_EQ(m_phy->GetOperatingChannel().GetFrequency(i),
337 expectedSegments.at(i).frequency,
338 "Operating channel has an incorrect center frequency at segment "
339 << i << " for channel settings " << channelSettings);
340 NS_TEST_ASSERT_MSG_EQ(m_phy->GetOperatingChannel().GetWidth(i),
341 expectedSegments.at(i).width,
342 "Operating channel has an incorrect channel width at segment "
343 << i << " for channel settings " << channelSettings);
344 NS_TEST_ASSERT_MSG_EQ(m_phy->GetOperatingChannel().GetPhyBand(),
345 expectedSegments.at(i).band,
346 "Operating channel has an incorrect band for channel settings "
347 << channelSettings);
348 }
349
350 NS_TEST_ASSERT_MSG_EQ(m_phy->GetOperatingChannel().GetPrimaryChannelIndex(MHz_u{20}),
352 "Operating channel has an incorrect P20 index for channel settings "
353 << channelSettings);
354}
355
356void
358{
359 // Test invalid combination
360 RunOne("{36, 40, BAND_UNSPECIFIED, 0}", WifiChannelWidthType::UNKNOWN, {}, 0);
361
362 // Test default with a single frequency segment
363 RunOne("{0, 0, BAND_UNSPECIFIED, 0}",
364 WifiChannelWidthType::CW_80MHZ,
365 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
366 0);
367
368 // Test default with two frequency segments unspecified
369 RunOne("{0, 0, BAND_UNSPECIFIED, 0};{0, 0, BAND_UNSPECIFIED, 0}",
370 WifiChannelWidthType::CW_80_PLUS_80MHZ,
371 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
372 {106, MHz_u{5530}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
373 0);
374
375 // Test default with two frequency segments and first is specified (but equals default)
376 RunOne("{42, 0, BAND_UNSPECIFIED, 0};{0, 0, BAND_UNSPECIFIED, 0}",
377 WifiChannelWidthType::CW_80_PLUS_80MHZ,
378 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
379 {106, MHz_u{5530}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
380 0);
381
382 // Test default with second segment specified to be at the first available 80 MHz segment
383 RunOne("{0, 0, BAND_UNSPECIFIED, 0};{42, 0, BAND_UNSPECIFIED, 0}",
384 WifiChannelWidthType::UNKNOWN,
385 {},
386 0);
387
388 // Test default with two frequency segments and first is specified (and differs from default)
389 RunOne("{106, 0, BAND_UNSPECIFIED, 0};{0, 0, BAND_UNSPECIFIED, 0}",
390 WifiChannelWidthType::CW_80_PLUS_80MHZ,
391 {{106, MHz_u{5530}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
392 {138, MHz_u{5690}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
393 0);
394
395 // Test unique channel 36 (20 MHz)
396 RunOne("{36, 0, BAND_UNSPECIFIED, 0}",
397 WifiChannelWidthType::CW_20MHZ,
398 {{36, MHz_u{5180}, MHz_u{20}, WIFI_PHY_BAND_5GHZ}},
399 0);
400
401 // Test unique channel 38 (40 MHz)
402 RunOne("{38, 0, BAND_UNSPECIFIED, 0}",
403 WifiChannelWidthType::CW_40MHZ,
404 {{38, MHz_u{5190}, MHz_u{40}, WIFI_PHY_BAND_5GHZ}},
405 0);
406
407 // Test unique channel 42 (80 MHz)
408 RunOne("{42, 0, BAND_UNSPECIFIED, 0}",
409 WifiChannelWidthType::CW_80MHZ,
410 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
411 0);
412
413 // Test unique channel 50 (160 MHz)
414 RunOne("{50, 0, BAND_UNSPECIFIED, 0}",
415 WifiChannelWidthType::CW_160MHZ,
416 {{50, MHz_u{5250}, MHz_u{160}, WIFI_PHY_BAND_5GHZ}},
417 0);
418
419 // Test 80+80 MHz
420 RunOne("{42, 0, BAND_UNSPECIFIED, 0};{106, 0, BAND_UNSPECIFIED, 0}",
421 WifiChannelWidthType::CW_80_PLUS_80MHZ,
422 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
423 {106, MHz_u{5530}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
424 0);
425
426 // Test P20 for 80+80 MHz: second value shall be ignored
427 RunOne("{42, 0, BAND_UNSPECIFIED, 1};{106, 0, BAND_UNSPECIFIED, 2}",
428 WifiChannelWidthType::CW_80_PLUS_80MHZ,
429 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
430 {106, MHz_u{5530}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
431 1);
432
433 // Test default 20 MHz channel
434 RunOne("{0, 20, BAND_UNSPECIFIED, 0}",
435 WifiChannelWidthType::CW_20MHZ,
436 {{36, MHz_u{5180}, MHz_u{20}, WIFI_PHY_BAND_5GHZ}},
437 0);
438
439 // Test default 40 MHz channel
440 RunOne("{0, 40, BAND_UNSPECIFIED, 0}",
441 WifiChannelWidthType::CW_40MHZ,
442 {{38, MHz_u{5190}, MHz_u{40}, WIFI_PHY_BAND_5GHZ}},
443 0);
444
445 // Test default 80 MHz channel
446 RunOne("{0, 80, BAND_UNSPECIFIED, 0}",
447 WifiChannelWidthType::CW_80MHZ,
448 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
449 0);
450
451 // Test default 160 MHz channel
452 RunOne("{0, 160, BAND_UNSPECIFIED, 0}",
453 WifiChannelWidthType::CW_160MHZ,
454 {{50, MHz_u{5250}, MHz_u{160}, WIFI_PHY_BAND_5GHZ}},
455 0);
456
457 // Test default 80+80 MHz channel
458 RunOne("{0, 80, BAND_UNSPECIFIED, 0};{0, 80, BAND_UNSPECIFIED, 0}",
459 WifiChannelWidthType::CW_80_PLUS_80MHZ,
460 {{42, MHz_u{5210}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
461 {106, MHz_u{5530}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
462 0);
463}
464
465/**
466 * @ingroup wifi-test
467 * @ingroup tests
468 *
469 * @brief Test the operating channel functions for 80+80MHz.
470 */
472{
473 public:
474 /**
475 * Constructor
476 */
478 ~WifiPhyChannel80Plus80Test() override = default;
479
480 private:
481 void DoRun() override;
482
483 /**
484 * Create a dummy PSDU whose payload is 1000 bytes
485 * @return a dummy PSDU whose payload is 1000 bytes
486 */
488
489 /**
490 * Create a HE PPDU
491 * @param bandwidth the bandwidth used for the transmission the PPDU
492 * @param channel the operating channel of the PHY used for the transmission
493 * @return a HE PPDU
494 */
496
497 WifiPhyOperatingChannel m_channel; //!< operating channel
498};
499
501 : TestCase("Check operating channel functions for 80+80MHz")
502{
503}
504
514
517 const WifiPhyOperatingChannel& channel)
518{
520 0,
522 NanoSeconds(800),
523 1,
524 1,
525 0,
526 bandwidth,
527 false);
529 return Create<HePpdu>(psdu, txVector, channel, MicroSeconds(100), 0);
530}
531
532void
534{
535 // P20 is in first segment and segments are provided in increasing frequency order
536 {
538 {106, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
541
543 NS_TEST_ASSERT_MSG_EQ(indexPrimary160Mhz, 0, "Primary 160 MHz channel shall have index 0");
545 NS_TEST_ASSERT_MSG_EQ(indexPrimary80Mhz, 0, "Primary 80 MHz channel shall have index 0");
547 NS_TEST_ASSERT_MSG_EQ(indexPrimary40Mhz, 1, "Primary 40 MHz channel shall have index 1");
549 NS_TEST_ASSERT_MSG_EQ(indexPrimary20Mhz, 3, "Primary 20 MHz channel shall have index 3");
550
553 1,
554 "Secondary 80 MHz channel shall have index 1");
557 0,
558 "Secondary 40 MHz channel shall have index 0");
561 2,
562 "Secondary 20 MHz channel shall have index 2");
563
564 const auto primary80MhzCenterFrequency =
567 MHz_u{5210},
568 "Primary 80 MHz channel center frequency shall be 5210 MHz");
569 const auto primary40MhzCenterFrequency =
572 MHz_u{5230},
573 "Primary 40 MHz channel center frequency shall be 5230 MHz");
574 const auto primary20MhzCenterFrequency =
577 MHz_u{5240},
578 "Primary 20 MHz channel center frequency shall be 5240 MHz");
579
583 MHz_u{5530},
584 "Secondary 80 MHz channel center frequency shall be 5530 MHz");
588 MHz_u{5190},
589 "Secondary 40 MHz channel center frequency shall be 5190 MHz");
593 MHz_u{5220},
594 "Secondary 20 MHz channel center frequency shall be 5220 MHz");
595
596 const auto primary80MhzChannelNumber =
599 42,
600 "Primary 80 MHz channel number shall be 42");
601 const auto primary40MhzChannelNumber =
604 46,
605 "Primary 40 MHz channel number shall be 46");
606 const auto primary20MhzChannelNumber =
609 48,
610 "Primary 20 MHz channel number shall be 48");
611
613 auto txCenterFreqs160MHz = ppdu160MHz->GetTxCenterFreqs();
614 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs160MHz.size(), 2, "2 segments are covered by 160 MHz");
616 MHz_u{5210},
617 "Center frequency of first segment shall be 5210 MHz");
619 MHz_u{5530},
620 "Center frequency of second segment shall be 5530 MHz");
622 auto txCenterFreqs80MHz = ppdu80MHz->GetTxCenterFreqs();
623 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs80MHz.size(), 1, "1 segment is covered by 80 MHz");
625 MHz_u{5210},
626 "Center frequency for 80 MHz shall be 5210 MHz");
628 auto txCenterFreqs40MHz = ppdu40MHz->GetTxCenterFreqs();
629 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs40MHz.size(), 1, "1 segment is covered by 40 MHz");
631 MHz_u{5230},
632 "Center frequency for 40 MHz shall be 5230 MHz");
634 auto txCenterFreqs20MHz = ppdu20MHz->GetTxCenterFreqs();
635 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs20MHz.size(), 1, "1 segment is covered by 20 MHz");
637 MHz_u{5240},
638 "Center frequency for 20 MHz shall be 5240 MHz");
639 }
640
641 // P20 is in second segment and segments are provided in increasing frequency order
642 {
644 {106, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
647
649 NS_TEST_ASSERT_MSG_EQ(indexPrimary160Mhz, 0, "Primary 160 MHz channel shall have index 0");
651 NS_TEST_ASSERT_MSG_EQ(indexPrimary80Mhz, 1, "Primary 80 MHz channel shall have index 1");
653 NS_TEST_ASSERT_MSG_EQ(indexPrimary40Mhz, 2, "Primary 40 MHz channel shall have index 2");
655 NS_TEST_ASSERT_MSG_EQ(indexPrimary20Mhz, 4, "Primary 20 MHz channel shall have index 4");
656
659 0,
660 "Secondary 80 MHz channel shall have index 0");
663 3,
664 "Secondary 40 MHz channel shall have index 3");
667 5,
668 "Secondary 20 MHz channel shall have index 5");
669
670 const auto primary80MhzCenterFrequency =
673 MHz_u{5530},
674 "Primary 80 MHz channel center frequency shall be 5530 MHz");
675 const auto primary40MhzCenterFrequency =
678 MHz_u{5510},
679 "Primary 40 MHz channel center frequency shall be 5510 MHz");
680 const auto primary20MhzCenterFrequency =
683 MHz_u{5500},
684 "Primary 20 MHz channel center frequency shall be 5500 MHz");
685
689 MHz_u{5210},
690 "Secondary 80 MHz channel center frequency shall be 5210 MHz");
694 MHz_u{5550},
695 "Secondary 40 MHz channel center frequency shall be 5550 MHz");
699 MHz_u{5520},
700 "Secondary 20 MHz channel center frequency shall be 5520 MHz");
701
702 const auto primary80MhzChannelNumber =
705 106,
706 "Primary 80 MHz channel number shall be 106");
707 const auto primary40MhzChannelNumber =
710 102,
711 "Primary 40 MHz channel number shall be 102");
712 const auto primary20MhzChannelNumber =
715 100,
716 "Primary 20 MHz channel number shall be 100");
717
719 auto txCenterFreqs160MHz = ppdu160MHz->GetTxCenterFreqs();
720 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs160MHz.size(), 2, "2 segments are covered by 160 MHz");
722 MHz_u{5530},
723 "Center frequency of first segment shall be 5530 MHz");
725 MHz_u{5210},
726 "Center frequency of second segment shall be 5210 MHz");
728 auto txCenterFreqs80MHz = ppdu80MHz->GetTxCenterFreqs();
729 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs80MHz.size(), 1, "1 segment is covered by 80 MHz");
731 MHz_u{5530},
732 "Center frequency for 80 MHz shall be 5530 MHz");
734 auto txCenterFreqs40MHz = ppdu40MHz->GetTxCenterFreqs();
735 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs40MHz.size(), 1, "1 segment is covered by 40 MHz");
737 MHz_u{5510},
738 "Center frequency for 40 MHz shall be 5510 MHz");
740 auto txCenterFreqs20MHz = ppdu20MHz->GetTxCenterFreqs();
741 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs20MHz.size(), 1, "1 segment is covered by 20 MHz");
743 MHz_u{5500},
744 "Center frequency for 20 MHz shall be 5500 MHz");
745 }
746
747 // P20 is in first segment and segments are provided in decreasing frequency order
748 {
749 m_channel.Set({{106, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
750 {42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
753
755 NS_TEST_ASSERT_MSG_EQ(indexPrimary160Mhz, 0, "Primary 160 MHz channel shall have index 0");
757 NS_TEST_ASSERT_MSG_EQ(indexPrimary80Mhz, 0, "Primary 80 MHz channel shall have index 0");
759 NS_TEST_ASSERT_MSG_EQ(indexPrimary40Mhz, 1, "Primary 40 MHz channel shall have index 1");
761 NS_TEST_ASSERT_MSG_EQ(indexPrimary20Mhz, 3, "Primary 20 MHz channel shall have index 3");
762
765 1,
766 "Secondary 80 MHz channel shall have index 1");
769 0,
770 "Secondary 40 MHz channel shall have index 0");
773 2,
774 "Secondary 20 MHz channel shall have index 2");
775
776 const auto primary80MhzCenterFrequency =
779 MHz_u{5210},
780 "Primary 80 MHz channel center frequency shall be 5210 MHz");
781 const auto primary40MhzCenterFrequency =
784 MHz_u{5230},
785 "Primary 40 MHz channel center frequency shall be 5230 MHz");
786 const auto primary20MhzCenterFrequency =
789 MHz_u{5240},
790 "Primary 20 MHz channel center frequency shall be 5240 MHz");
791
795 MHz_u{5530},
796 "Secondary 80 MHz channel center frequency shall be 5530 MHz");
800 MHz_u{5190},
801 "Secondary 40 MHz channel center frequency shall be 5190 MHz");
805 MHz_u{5220},
806 "Secondary 20 MHz channel center frequency shall be 5220 MHz");
807
808 const auto primary80MhzChannelNumber =
811 42,
812 "Primary 80 MHz channel number shall be 42");
813 const auto primary40MhzChannelNumber =
816 46,
817 "Primary 40 MHz channel number shall be 46");
818 const auto primary20MhzChannelNumber =
821 48,
822 "Primary 20 MHz channel number shall be 48");
823
825 auto txCenterFreqs160MHz = ppdu160MHz->GetTxCenterFreqs();
826 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs160MHz.size(), 2, "2 segments are covered by 160 MHz");
828 MHz_u{5210},
829 "Center frequency of first segment shall be 5210 MHz");
831 MHz_u{5530},
832 "Center frequency of second segment shall be 5530 MHz");
834 auto txCenterFreqs80MHz = ppdu80MHz->GetTxCenterFreqs();
835 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs80MHz.size(), 1, "1 segment is covered by 80 MHz");
837 MHz_u{5210},
838 "Center frequency for 80 MHz shall be 5210 MHz");
840 auto txCenterFreqs40MHz = ppdu40MHz->GetTxCenterFreqs();
841 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs40MHz.size(), 1, "1 segment is covered by 40 MHz");
843 MHz_u{5230},
844 "Center frequency for 40 MHz shall be 5230 MHz");
846 auto txCenterFreqs20MHz = ppdu20MHz->GetTxCenterFreqs();
847 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs20MHz.size(), 1, "1 segment is covered by 20 MHz");
849 MHz_u{5240},
850 "Center frequency for 20 MHz shall be 5240 MHz");
851 }
852
853 // P20 is in second segment and segments are provided in decreasing frequency order
854 {
855 m_channel.Set({{106, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ},
856 {42, MHz_u{0}, MHz_u{80}, WIFI_PHY_BAND_5GHZ}},
859
861 NS_TEST_ASSERT_MSG_EQ(indexPrimary160Mhz, 0, "Primary 160 MHz channel shall have index 0");
863 NS_TEST_ASSERT_MSG_EQ(indexPrimary80Mhz, 1, "Primary 80 MHz channel shall have index 1");
865 NS_TEST_ASSERT_MSG_EQ(indexPrimary40Mhz, 2, "Primary 40 MHz channel shall have index 2");
867 NS_TEST_ASSERT_MSG_EQ(indexPrimary20Mhz, 4, "Primary 20 MHz channel shall have index 4");
868
871 0,
872 "Secondary 80 MHz channel shall have index 0");
875 3,
876 "Secondary 40 MHz channel shall have index 3");
879 5,
880 "Secondary 20 MHz channel shall have index 5");
881
882 const auto primary80MhzCenterFrequency =
885 MHz_u{5530},
886 "Primary 80 MHz channel center frequency shall be 5530 MHz");
887 const auto primary40MhzCenterFrequency =
890 MHz_u{5510},
891 "Primary 40 MHz channel center frequency shall be 5510 MHz");
892 const auto primary20MhzCenterFrequency =
895 MHz_u{5500},
896 "Primary 20 MHz channel center frequency shall be 5500 MHz");
897
901 MHz_u{5210},
902 "Secondary 80 MHz channel center frequency shall be 5210 MHz");
906 MHz_u{5550},
907 "Secondary 40 MHz channel center frequency shall be 5550 MHz");
911 MHz_u{5520},
912 "Secondary 20 MHz channel center frequency shall be 5520 MHz");
913
914 const auto primary80MhzChannelNumber =
917 106,
918 "Primary 80 MHz channel number shall be 106");
919 const auto primary40MhzChannelNumber =
922 102,
923 "Primary 40 MHz channel number shall be 102");
924 const auto primary20MhzChannelNumber =
927 100,
928 "Primary 20 MHz channel number shall be 100");
929
931 auto txCenterFreqs160MHz = ppdu160MHz->GetTxCenterFreqs();
932 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs160MHz.size(), 2, "2 segments are covered by 160 MHz");
934 MHz_u{5530},
935 "Center frequency of first segment shall be 5530 MHz");
937 MHz_u{5210},
938 "Center frequency of second segment shall be 5210 MHz");
940 auto txCenterFreqs80MHz = ppdu80MHz->GetTxCenterFreqs();
941 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs80MHz.size(), 1, "1 segment is covered by 80 MHz");
943 MHz_u{5530},
944 "Center frequency for 80 MHz shall be 5530 MHz");
946 auto txCenterFreqs40MHz = ppdu40MHz->GetTxCenterFreqs();
947 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs40MHz.size(), 1, "1 segment is covered by 40 MHz");
949 MHz_u{5510},
950 "Center frequency for 40 MHz shall be 5510 MHz");
952 auto txCenterFreqs20MHz = ppdu20MHz->GetTxCenterFreqs();
953 NS_TEST_ASSERT_MSG_EQ(txCenterFreqs20MHz.size(), 1, "1 segment is covered by 20 MHz");
955 MHz_u{5500},
956 "Center frequency for 20 MHz shall be 5500 MHz");
957 }
958
960}
961
962/**
963 * @ingroup wifi-test
964 * @ingroup tests
965 *
966 * @brief wifi operating channel test suite
967 */
969{
970 public:
972};
973
975 : TestSuite("wifi-operating-channel", Type::UNIT)
976{
977 AddTestCase(new SetWifiOperatingChannelTest(), TestCase::Duration::QUICK);
978 AddTestCase(new PhyChannelSettingsToOperatingChannelTest(), TestCase::Duration::QUICK);
979 AddTestCase(new WifiPhyChannel80Plus80Test(), TestCase::Duration::QUICK);
980}
981
Test the conversion from PHY ChannelSettings attribute to WifiPhyOperatingChannel.
~PhyChannelSettingsToOperatingChannelTest() override=default
void DoRun() override
Implementation to actually run this TestCase.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void RunOne(const std::string &channelSettings, WifiChannelWidthType expectedWidthType, const std::vector< FrequencyChannelInfo > &expectedSegments, uint8_t expectedP20Index)
Run one function.
Test the WifiPhyOperatingChannel::Set() method.
WifiPhyOperatingChannel m_channel
operating channel
~SetWifiOperatingChannelTest() override=default
void DoRun() override
Implementation to actually run this TestCase.
void RunOne(const std::string &runInfo, const std::vector< FrequencyChannelInfo > &segments, WifiStandard standard, WifiPhyBand band, bool expectExceptionThrown, WifiChannelWidthType expectedWidth=WifiChannelWidthType::UNKNOWN, const std::vector< FrequencyChannelInfo > &expectedSegments={})
Run one function.
wifi operating channel test suite
Test the operating channel functions for 80+80MHz.
Ptr< HePpdu > CreateDummyHePpdu(MHz_u bandwidth, const WifiPhyOperatingChannel &channel)
Create a HE PPDU.
Ptr< WifiPsdu > CreateDummyPsdu()
Create a dummy PSDU whose payload is 1000 bytes.
WifiPhyOperatingChannel m_channel
operating channel
~WifiPhyChannel80Plus80Test() override=default
void DoRun() override
Implementation to actually run this TestCase.
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Implements the IEEE 802.11 MAC header.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
Class that keeps track of all information about the current PHY operating channel.
uint8_t GetNumber(std::size_t segment=0) const
Return the channel number for a given frequency segment.
WifiChannelWidthType GetWidthType() const
Return the width type of the operating channel.
MHz_u GetSecondaryChannelCenterFrequency(MHz_u secondaryChannelWidth) const
Get the center frequency of the secondary channel of the given width.
void SetPrimary20Index(uint8_t index)
Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel with the lowest center...
uint8_t GetSecondaryChannelIndex(MHz_u secondaryChannelWidth) const
If the operating channel width is made of a multiple of 20 MHz, return the index of the secondary cha...
std::size_t GetNSegments() const
Get the number of frequency segments in the operating channel.
void Set(const std::vector< FrequencyChannelInfo > &segments, WifiStandard standard)
Set the channel according to the specified parameters if a unique frequency channel matches the speci...
MHz_u GetWidth(std::size_t segment=0) const
Return the channel width for a given frequency segment.
uint8_t GetPrimaryChannelIndex(MHz_u primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
MHz_u GetPrimaryChannelCenterFrequency(MHz_u primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
MHz_u GetFrequency(std::size_t segment=0) const
Return the center frequency for a given frequency segment.
WifiPhyBand GetPhyBand() const
Return the PHY band of the operating channel.
uint8_t GetPrimaryChannelNumber(MHz_u primaryChannelWidth, WifiStandard standard) const
Get channel number of the primary channel.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#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 > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1368
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1380
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyBand
Identifies the PHY band.
WifiChannelWidthType
Enumeration of the possible channel widths.
Definition wifi-types.h:22
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ WIFI_MAC_QOSDATA
static WifiOperatingChannelTestSuite g_wifiOperatingChannelTestSuite
the test suite