A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-transmit-mask-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 Orange Labs
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Rediet <getachew.redieteab@orange.com>
7 */
8
9#include "ns3/fatal-error.h"
10#include "ns3/log.h"
11#include "ns3/test.h"
12#include "ns3/wifi-phy-band.h"
13#include "ns3/wifi-phy-common.h"
14#include "ns3/wifi-spectrum-value-helper.h"
15#include "ns3/wifi-standards.h"
16
17#include <cmath>
18#include <vector>
19
20using namespace ns3;
21
22NS_LOG_COMPONENT_DEFINE("WifiTransmitMaskTest");
23
24/**
25 * @ingroup wifi-test
26 * @ingroup tests
27 *
28 * @brief Test checks if Wifi spectrum values for OFDM are generated properly.
29 * Different test cases are configured by defining different standards and bandwidth.
30 */
32{
33 public:
34 /**
35 * typedef for a pair of sub-band index and relative power value
36 */
37 typedef std::pair<uint32_t, dBr_u> IndexPowerPair;
38
39 /**
40 * typedef for a vector of pairs of sub-band index and relative power value
41 */
42 typedef std::vector<IndexPowerPair> IndexPowerVect;
43
44 /**
45 * Constructor
46 *
47 * @param name test reference name
48 * @param standard selected standard
49 * @param band selected PHY band
50 * @param channelWidth total channel width
51 * @param centerFrequencies the center frequency per contiguous segment
52 * @param maskRefs vector of expected power values and corresponding indexes of generated PSD
53 * (only start and stop indexes/values given)
54 * @param tolerance tolerance
55 * @param precision precision (in decimals)
56 * @param puncturedSubchannels bitmap indicating whether a 20 MHz subchannel is punctured or not
57 * (only for 802.11ax and later)
58 */
59 WifiOfdmMaskSlopesTestCase(const std::string& name,
60 WifiStandard standard,
61 WifiPhyBand band,
62 MHz_u channelWidth,
63 const std::vector<MHz_u>& centerFrequencies,
64 const IndexPowerVect& maskRefs,
65 dB_u tolerance,
66 std::size_t precision,
67 const std::vector<bool>& puncturedSubchannels = std::vector<bool>{});
68 ~WifiOfdmMaskSlopesTestCase() override = default;
69
70 private:
71 void DoSetup() override;
72 void DoRun() override;
73
74 /**
75 * Interpolate PSD values for indexes between provided start and stop and append to provided
76 * vector.
77 *
78 * @param vect vector of sub-band index and relative power value pairs to which interpolated
79 values should be appended
80 * @param start pair of sub-band index and relative power value for interval start
81 * @param stop pair of sub-band index and relative power value for interval stop
82 */
84 IndexPowerPair start,
85 IndexPowerPair stop) const;
86
87 WifiStandard m_standard; ///< the wifi standard to test
88 WifiPhyBand m_band; ///< the wifi PHY band to test
89 MHz_u m_channelWidth; ///< the total channel width to test
90 std::vector<MHz_u> m_centerFreqs; ///< the center frequency per contiguous segment to test
91 std::vector<bool>
92 m_puncturedSubchannels; ///< bitmap indicating whether a 20 MHz subchannel is punctured or
93 ///< not (only used for 802.11ax and later)
94 Ptr<SpectrumValue> m_actualSpectrum; ///< actual spectrum value
95 IndexPowerVect m_expectedPsd; ///< expected power values
96 dB_u m_tolerance; ///< tolerance
97 std::size_t m_precision; ///< precision for double calculations (in decimals)
98};
99
101 const std::string& name,
102 WifiStandard standard,
103 WifiPhyBand band,
104 MHz_u channelWidth,
105 const std::vector<MHz_u>& centerFrequencies,
106 const IndexPowerVect& maskRefs,
107 dB_u tolerance,
108 std::size_t precision,
109 const std::vector<bool>& puncturedSubchannels)
110 : TestCase(std::string("SpectrumValue ") + name),
111 m_standard{standard},
112 m_band{band},
113 m_channelWidth{channelWidth},
114 m_centerFreqs{centerFrequencies},
115 m_puncturedSubchannels{puncturedSubchannels},
116 m_actualSpectrum{},
117 m_expectedPsd{maskRefs},
118 m_tolerance{tolerance},
119 m_precision{precision}
120{
121 NS_LOG_FUNCTION(this << name << standard << band << channelWidth << tolerance << precision
122 << puncturedSubchannels.size());
123}
124
125void
127{
128 NS_LOG_FUNCTION(this);
129 NS_ASSERT(!m_centerFreqs.empty());
130 NS_ASSERT(m_expectedPsd.size() % 2 == 0); // start/stop pairs expected
131
132 dBr_u outerBandMaximumRejection{0.0};
133 switch (m_band)
134 {
135 default:
137 outerBandMaximumRejection = dBr_u{-40};
138 break;
140 outerBandMaximumRejection = (m_standard >= WIFI_STANDARD_80211n) ? dBr_u{-45} : dBr_u{-40};
141 break;
143 outerBandMaximumRejection = dBr_u{-40};
144 break;
145 }
146
147 Watt_u refTxPower{1}; // have to work in dBr when comparing though
148 switch (m_standard)
149 {
156 refTxPower,
158 dBr_u{-20.0},
159 dBr_u{-28.0},
160 outerBandMaximumRejection);
161 break;
162
169 refTxPower,
171 dBr_u{-20.0},
172 dBr_u{-28.0},
173 outerBandMaximumRejection);
174 break;
175
182 refTxPower,
184 dBr_u{-20.0},
185 dBr_u{-28.0},
186 outerBandMaximumRejection);
187 break;
188
194 refTxPower,
196 dBr_u{-20.0},
197 dBr_u{-28.0},
198 outerBandMaximumRejection);
199 break;
200
204 m_channelWidth == MHz_u{80} || m_channelWidth == MHz_u{160});
208 refTxPower,
210 dBr_u{-20.0},
211 dBr_u{-28.0},
212 outerBandMaximumRejection);
213 break;
214
217 (m_channelWidth < MHz_u{80})); // not enough space in 2.4 GHz bands
219 m_channelWidth == MHz_u{80} || m_channelWidth == MHz_u{160});
223 refTxPower,
225 dBr_u{-20.0},
226 dBr_u{-28.0},
227 outerBandMaximumRejection,
229 break;
230
231 default:
232 NS_FATAL_ERROR("Standard unknown or non-OFDM");
233 break;
234 }
235
236 NS_LOG_INFO("Build expected PSD");
237 IndexPowerVect builtPsd;
238 for (uint32_t i = 0; i < m_expectedPsd.size(); i += 2)
239 {
241 }
242 m_expectedPsd = builtPsd;
243}
244
245void
247 IndexPowerPair start,
248 IndexPowerPair stop) const
249{
250 NS_LOG_FUNCTION(start.first << start.second << stop.first << stop.second);
251 NS_ASSERT(start.first <= stop.first);
252
253 if (start.first == stop.first) // only one point, no need to interpolate
254 {
255 NS_ASSERT(start.second == stop.second);
256 vect.push_back(start);
257 NS_LOG_LOGIC("Append (" << start.first << ", " << stop.second << ")");
258 return;
259 }
260
261 const auto slope = (stop.second - start.second) / (stop.first - start.first);
262 for (uint32_t i = start.first; i <= stop.first; i++)
263 {
264 const auto delta{i - start.first};
265 dB_u val{start.second + slope * delta};
266 const auto multiplier = std::round(std::pow(10.0, static_cast<double>(m_precision)));
267 val = dB_u{std::floor(val * multiplier + 0.5) / multiplier};
268 vect.emplace_back(i, val);
269 NS_LOG_LOGIC("Append (" << i << ", " << val << ")");
270 }
271
272 NS_ASSERT(vect.back().first == stop.first &&
273 TestDoubleIsEqual(vect.back().second, stop.second, m_tolerance));
274}
275
276void
278{
279 NS_LOG_FUNCTION(this);
280 dBr_u currentPower{0.0}; // have to work in dBr so as to compare with expected slopes
281 Watt_u maxPower{(*m_actualSpectrum)[0]};
282 for (auto&& vit = m_actualSpectrum->ConstValuesBegin();
283 vit != m_actualSpectrum->ConstValuesEnd();
284 ++vit)
285 {
286 maxPower = std::max(maxPower, Watt_u{*vit});
287 }
288
289 NS_LOG_INFO("Compare expected PSD");
290 for (const auto& [subcarrier, expectedValue] : m_expectedPsd)
291 {
292 currentPower = dBr_u{10.0 * std::log10((*m_actualSpectrum)[subcarrier] / maxPower)};
293 NS_LOG_LOGIC("For " << subcarrier << ", expected: " << expectedValue
294 << " vs obtained: " << currentPower);
295 NS_TEST_EXPECT_MSG_EQ_TOL(currentPower,
296 expectedValue,
298 "Spectrum value mismatch for subcarrier " << subcarrier);
299 }
300}
301
302/**
303 * @ingroup wifi-test
304 * @ingroup tests
305 *
306 * @brief Test suite for checking the consistency of different OFDM-based transmit masks.
307 */
309{
310 public:
312};
313
315
317 : TestSuite("wifi-transmit-mask", Type::UNIT)
318{
319 // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
320 // LogComponentEnable ("WifiTransmitMaskTest", logLevel);
321 // LogComponentEnable ("WifiSpectrumValueHelper", logLevel);
322
323 NS_LOG_INFO("Creating WifiTransmitMaskTestSuite");
324
326 dB_u tol{10e-2};
327 double prec = 10; // in decimals
328
329 // ============================================================================================
330 // 11p 5MHz
331 NS_LOG_FUNCTION("Check slopes for 11p 5MHz");
332 maskSlopes = {
333 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
334 std::make_pair(31, dBr_u{-28.375}), // Outer band left (stop)
335 std::make_pair(32, dBr_u{-28.000}), // Middle band left (start)
336 std::make_pair(60, dBr_u{-20.276}), // Middle band left (stop)
337 std::make_pair(61, dBr_u{-20.0}), // Flat junction band left (start)
338 std::make_pair(63, dBr_u{-20.0}), // Flat junction band left (stop)
339 std::make_pair(64, dBr_u{-20.0}), // Inner band left (start)
340 std::make_pair(69, dBr_u{-3.333}), // Inner band left (stop)
341 std::make_pair(123, dBr_u{-3.333}), // Inner band right (start)
342 std::make_pair(128, dBr_u{-20.0}), // Inner band right (stop)
343 std::make_pair(129, dBr_u{-20.0}), // Flat junction band right (start)
344 std::make_pair(131, dBr_u{-20.0}), // Flat junction band right (stop)
345 std::make_pair(132, dBr_u{-20.276}), // Middle band right (start)
346 std::make_pair(160, dBr_u{-28.000}), // Middle band right (stop)
347 std::make_pair(161, dBr_u{-28.375}), // Outer band right (start)
348 std::make_pair(192, dBr_u{-40.0}), // Outer band right (stop)
349 };
350
354 MHz_u{5},
355 {MHz_u{5860}},
356 maskSlopes,
357 tol,
358 prec),
359 TestCase::Duration::QUICK);
360
361 // ============================================================================================
362 // 11p 10MHz
363 NS_LOG_FUNCTION("Check slopes for 11p 10MHz");
364 maskSlopes = {
365 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
366 std::make_pair(31, dBr_u{-28.375}), // Outer band left (stop)
367 std::make_pair(32, dBr_u{-28.000}), // Middle band left (start)
368 std::make_pair(60, dBr_u{-20.276}), // Middle band left (stop)
369 std::make_pair(61, dBr_u{-20.0}), // Flat junction band left (start)
370 std::make_pair(63, dBr_u{-20.0}), // Flat junction band left (stop)
371 std::make_pair(64, dBr_u{-20.0}), // Inner band left (start)
372 std::make_pair(69, dBr_u{-3.333}), // Inner band left (stop)
373 std::make_pair(123, dBr_u{-3.333}), // Inner band right (start)
374 std::make_pair(128, dBr_u{-20.0}), // Inner band right (stop)
375 std::make_pair(129, dBr_u{-20.0}), // Flat junction band right (start)
376 std::make_pair(131, dBr_u{-20.0}), // Flat junction band right (stop)
377 std::make_pair(132, dBr_u{-20.276}), // Middle band right (start)
378 std::make_pair(160, dBr_u{-28.000}), // Middle band right (stop)
379 std::make_pair(161, dBr_u{-28.375}), // Outer band right (start)
380 std::make_pair(192, dBr_u{-40.0}), // Outer band right (stop)
381 };
382
386 MHz_u{10},
387 {MHz_u{5860}},
388 maskSlopes,
389 tol,
390 prec),
391 TestCase::Duration::QUICK);
392
393 // ============================================================================================
394 // 11a
395 NS_LOG_FUNCTION("Check slopes for 11a");
396 maskSlopes = {
397 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
398 std::make_pair(31, dBr_u{-28.375}), // Outer band left (stop)
399 std::make_pair(32, dBr_u{-28.000}), // Middle band left (start)
400 std::make_pair(60, dBr_u{-20.276}), // Middle band left (stop)
401 std::make_pair(61, dBr_u{-20.0}), // Flat junction band left (start)
402 std::make_pair(63, dBr_u{-20.0}), // Flat junction band left (stop)
403 std::make_pair(64, dBr_u{-20.0}), // Inner band left (start)
404 std::make_pair(69, dBr_u{-3.333}), // Inner band left (stop)
405 std::make_pair(123, dBr_u{-3.333}), // Inner band right (start)
406 std::make_pair(128, dBr_u{-20.0}), // Inner band right (stop)
407 std::make_pair(129, dBr_u{-20.0}), // Flat junction band right (start)
408 std::make_pair(131, dBr_u{-20.0}), // Flat junction band right (stop)
409 std::make_pair(132, dBr_u{-20.276}), // Middle band right (start)
410 std::make_pair(160, dBr_u{-28.000}), // Middle band right (stop)
411 std::make_pair(161, dBr_u{-28.375}), // Outer band right (start)
412 std::make_pair(192, dBr_u{-40.0}), // Outer band right (stop)
413 };
414
418 MHz_u{20},
419 {MHz_u{5180}},
420 maskSlopes,
421 tol,
422 prec),
423 TestCase::Duration::QUICK);
424
425 // ============================================================================================
426 // 11g
427 NS_LOG_FUNCTION("Check slopes for 11g");
428 // same slopes as 11a
432 MHz_u{20},
433 {MHz_u{2412}},
434 maskSlopes,
435 tol,
436 prec),
437 TestCase::Duration::QUICK);
438
439 // ============================================================================================
440 // 11n 20MHz @ 2.4GHz
441 NS_LOG_FUNCTION("Check slopes for 11n 20MHz @ 2.4GHz");
442 maskSlopes = {
443 std::make_pair(0, dBr_u{-45.000}), // Outer band left (start)
444 std::make_pair(31, dBr_u{-28.531}), // Outer band left (stop)
445 std::make_pair(32, dBr_u{-28.000}), // Middle band left (start)
446 std::make_pair(60, dBr_u{-20.276}), // Middle band left (stop)
447 std::make_pair(61, dBr_u{-20.0}), // Flat junction band left (start)
448 std::make_pair(61, dBr_u{-20.0}), // Flat junction band left (stop)
449 std::make_pair(62, dBr_u{-20.0}), // Inner band left (start)
450 std::make_pair(67, dBr_u{-3.333}), // Inner band left (stop)
451 std::make_pair(125, dBr_u{-3.333}), // Inner band right (start)
452 std::make_pair(130, dBr_u{-20.0}), // Inner band right (stop)
453 std::make_pair(131, dBr_u{-20.0}), // Flat junction band right (start)
454 std::make_pair(131, dBr_u{-20.0}), // Flat junction band right (stop)
455 std::make_pair(132, dBr_u{-20.276}), // Middle band right (start)
456 std::make_pair(160, dBr_u{-28.000}), // Middle band right (stop)
457 std::make_pair(161, dBr_u{-28.531}), // Outer band right (start)
458 std::make_pair(192, dBr_u{-45.000}), // Outer band right (stop)
459 };
460
461 AddTestCase(new WifiOfdmMaskSlopesTestCase("11n_2.4GHz 20MHz",
464 MHz_u{20},
465 {MHz_u{2412}},
466 maskSlopes,
467 tol,
468 prec),
469 TestCase::Duration::QUICK);
470
471 // ============================================================================================
472 // 11n 20MHz @ 5GHz
473 NS_LOG_FUNCTION("Check slopes for 11n 20MHz @ 5GHz");
474 maskSlopes = {
475 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
476 std::make_pair(31, dBr_u{-28.375}), // Outer band left (stop)
477 std::make_pair(32, dBr_u{-28.000}), // Middle band left (start)
478 std::make_pair(60, dBr_u{-20.276}), // Middle band left (stop)
479 std::make_pair(61, dBr_u{-20.0}), // Flat junction band left (start)
480 std::make_pair(61, dBr_u{-20.0}), // Flat junction band left (stop)
481 std::make_pair(62, dBr_u{-20.0}), // Inner band left (start)
482 std::make_pair(67, dBr_u{-3.333}), // Inner band left (stop)
483 std::make_pair(125, dBr_u{-3.333}), // Inner band right (start)
484 std::make_pair(130, dBr_u{-20.0}), // Inner band right (stop)
485 std::make_pair(131, dBr_u{-20.0}), // Flat junction band right (start)
486 std::make_pair(131, dBr_u{-20.0}), // Flat junction band right (stop)
487 std::make_pair(132, dBr_u{-20.276}), // Middle band right (start)
488 std::make_pair(160, dBr_u{-28.000}), // Middle band right (stop)
489 std::make_pair(161, dBr_u{-28.375}), // Outer band right (start)
490 std::make_pair(192, dBr_u{-40.0}), // Outer band right (stop)
491 };
492
493 AddTestCase(new WifiOfdmMaskSlopesTestCase("11n_5GHz 20MHz",
496 MHz_u{20},
497 {MHz_u{5180}},
498 maskSlopes,
499 tol,
500 prec),
501 TestCase::Duration::QUICK);
502
503 // ============================================================================================
504 // 11n 40MHz @ 2.4GHz
505 NS_LOG_FUNCTION("Check slopes for 11n 40MHz @ 2.4GHz");
506 maskSlopes = {
507 std::make_pair(0, dBr_u{-45.000}), // Outer band left (start)
508 std::make_pair(63, dBr_u{-28.266}), // Outer band left (stop)
509 std::make_pair(64, dBr_u{-28.000}), // Middle band left (start)
510 std::make_pair(124, dBr_u{-20.131}), // Middle band left (stop)
511 std::make_pair(125, dBr_u{-20.0}), // Flat junction band left (start)
512 std::make_pair(125, dBr_u{-20.0}), // Flat junction band left (stop)
513 std::make_pair(126, dBr_u{-20.0}), // Inner band left (start)
514 std::make_pair(131, dBr_u{-3.333}), // Inner band left (stop)
515 std::make_pair(253, dBr_u{-3.333}), // Inner band right (start)
516 std::make_pair(258, dBr_u{-20.0}), // Inner band right (stop)
517 std::make_pair(259, dBr_u{-20.0}), // Flat junction band right (start)
518 std::make_pair(259, dBr_u{-20.0}), // Flat junction band right (stop)
519 std::make_pair(260, dBr_u{-20.131}), // Middle band right (start)
520 std::make_pair(320, dBr_u{-28.000}), // Middle band right (stop)
521 std::make_pair(321, dBr_u{-28.266}), // Outer band right (start)
522 std::make_pair(384, dBr_u{-45.000}), // Outer band right (stop)
523 };
524
525 AddTestCase(new WifiOfdmMaskSlopesTestCase("11n_2.4GHz 40MHz",
528 MHz_u{40},
529 {MHz_u{2422}},
530 maskSlopes,
531 tol,
532 prec),
533 TestCase::Duration::QUICK);
534
535 // ============================================================================================
536 // 11n 20MHz @ 5GHz
537 NS_LOG_FUNCTION("Check slopes for 11n 40MHz @ 5GHz");
538 maskSlopes = {
539 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
540 std::make_pair(63, dBr_u{-28.188}), // Outer band left (stop)
541 std::make_pair(64, dBr_u{-28.000}), // Middle band left (start)
542 std::make_pair(124, dBr_u{-20.131}), // Middle band left (stop)
543 std::make_pair(125, dBr_u{-20.0}), // Flat junction band left (start)
544 std::make_pair(125, dBr_u{-20.0}), // Flat junction band left (stop)
545 std::make_pair(126, dBr_u{-20.0}), // Inner band left (start)
546 std::make_pair(131, dBr_u{-3.333}), // Inner band left (stop)
547 std::make_pair(253, dBr_u{-3.333}), // Inner band right (start)
548 std::make_pair(258, dBr_u{-20.0}), // Inner band right (stop)
549 std::make_pair(259, dBr_u{-20.0}), // Flat junction band right (start)
550 std::make_pair(259, dBr_u{-20.0}), // Flat junction band right (stop)
551 std::make_pair(260, dBr_u{-20.131}), // Middle band right (start)
552 std::make_pair(320, dBr_u{-28.000}), // Middle band right (stop)
553 std::make_pair(321, dBr_u{-28.188}), // Outer band right (start)
554 std::make_pair(384, dBr_u{-40.0}), // Outer band right (stop)
555 };
556
557 AddTestCase(new WifiOfdmMaskSlopesTestCase("11n_5GHz 40MHz",
560 MHz_u{40},
561 {MHz_u{5190}},
562 maskSlopes,
563 tol,
564 prec),
565 TestCase::Duration::QUICK);
566
567 // ============================================================================================
568 // 11ac 20MHz
569 NS_LOG_FUNCTION("Check slopes for 11ac 20MHz");
570 maskSlopes = {
571 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
572 std::make_pair(31, dBr_u{-28.375}), // Outer band left (stop)
573 std::make_pair(32, dBr_u{-28.000}), // Middle band left (start)
574 std::make_pair(60, dBr_u{-20.276}), // Middle band left (stop)
575 std::make_pair(61, dBr_u{-20.0}), // Flat junction band left (start)
576 std::make_pair(61, dBr_u{-20.0}), // Flat junction band left (stop)
577 std::make_pair(62, dBr_u{-20.0}), // Inner band left (start)
578 std::make_pair(67, dBr_u{-3.333}), // Inner band left (stop)
579 std::make_pair(125, dBr_u{-3.333}), // Inner band right (start)
580 std::make_pair(130, dBr_u{-20.0}), // Inner band right (stop)
581 std::make_pair(131, dBr_u{-20.0}), // Flat junction band right (start)
582 std::make_pair(131, dBr_u{-20.0}), // Flat junction band right (stop)
583 std::make_pair(132, dBr_u{-20.276}), // Middle band right (start)
584 std::make_pair(160, dBr_u{-28.000}), // Middle band right (stop)
585 std::make_pair(161, dBr_u{-28.375}), // Outer band right (start)
586 std::make_pair(192, dBr_u{-40.0}), // Outer band right (stop)
587 };
588
592 MHz_u{20},
593 {MHz_u{5180}},
594 maskSlopes,
595 tol,
596 prec),
597 TestCase::Duration::QUICK);
598
599 // ============================================================================================
600 // 11ac 20MHz
601 NS_LOG_FUNCTION("Check slopes for 11ac 40MHz");
602 maskSlopes = {
603 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
604 std::make_pair(63, dBr_u{-28.188}), // Outer band left (stop)
605 std::make_pair(64, dBr_u{-28.000}), // Middle band left (start)
606 std::make_pair(124, dBr_u{-20.131}), // Middle band left (stop)
607 std::make_pair(125, dBr_u{-20.0}), // Flat junction band left (start)
608 std::make_pair(125, dBr_u{-20.0}), // Flat junction band left (stop)
609 std::make_pair(126, dBr_u{-20.0}), // Inner band left (start)
610 std::make_pair(131, dBr_u{-3.333}), // Inner band left (stop)
611 std::make_pair(253, dBr_u{-3.333}), // Inner band right (start)
612 std::make_pair(258, dBr_u{-20.0}), // Inner band right (stop)
613 std::make_pair(259, dBr_u{-20.0}), // Flat junction band right (start)
614 std::make_pair(259, dBr_u{-20.0}), // Flat junction band right (stop)
615 std::make_pair(260, dBr_u{-20.131}), // Middle band right (start)
616 std::make_pair(320, dBr_u{-28.000}), // Middle band right (stop)
617 std::make_pair(321, dBr_u{-28.188}), // Outer band right (start)
618 std::make_pair(384, dBr_u{-40.0}), // Outer band right (stop)
619 };
620
624 MHz_u{40},
625 {MHz_u{5190}},
626 maskSlopes,
627 tol,
628 prec),
629 TestCase::Duration::QUICK);
630
631 // ============================================================================================
632 // 11ac 80MHz
633 NS_LOG_FUNCTION("Check slopes for 11ac 80MHz");
634 maskSlopes = {
635 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
636 std::make_pair(127, dBr_u{-28.094}), // Outer band left (stop)
637 std::make_pair(128, dBr_u{-28.000}), // Middle band left (start)
638 std::make_pair(252, dBr_u{-20.064}), // Middle band left (stop)
639 std::make_pair(253, dBr_u{-20.0}), // Flat junction band left (start)
640 std::make_pair(253, dBr_u{-20.0}), // Flat junction band left (stop)
641 std::make_pair(254, dBr_u{-20.0}), // Inner band left (start)
642 std::make_pair(259, dBr_u{-3.333}), // Inner band left (stop)
643 std::make_pair(509, dBr_u{-3.333}), // Inner band right (start)
644 std::make_pair(514, dBr_u{-20.0}), // Inner band right (stop)
645 std::make_pair(515, dBr_u{-20.0}), // Flat junction band right (start)
646 std::make_pair(515, dBr_u{-20.0}), // Flat junction band right (stop)
647 std::make_pair(516, dBr_u{-20.064}), // Middle band right (start)
648 std::make_pair(640, dBr_u{-28.000}), // Middle band right (stop)
649 std::make_pair(641, dBr_u{-28.094}), // Outer band right (start)
650 std::make_pair(768, dBr_u{-40.0}), // Outer band right (stop)
651 };
652
656 MHz_u{80},
657 {MHz_u{5210}},
658 maskSlopes,
659 tol,
660 prec),
661 TestCase::Duration::QUICK);
662
663 // ============================================================================================
664 // 11ac 20MHz
665 NS_LOG_FUNCTION("Check slopes for 11ac 160MHz");
666 maskSlopes = {
667 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
668 std::make_pair(255, dBr_u{-28.047}), // Outer band left (stop)
669 std::make_pair(256, dBr_u{-28.000}), // Middle band left (start)
670 std::make_pair(508, dBr_u{-20.032}), // Middle band left (stop)
671 std::make_pair(509, dBr_u{-20.0}), // Flat junction band left (start)
672 std::make_pair(509, dBr_u{-20.0}), // Flat junction band left (stop)
673 std::make_pair(510, dBr_u{-20.0}), // Inner band left (start)
674 std::make_pair(515, dBr_u{-3.333}), // Inner band left (stop)
675 std::make_pair(1021, dBr_u{-3.333}), // Inner band right (start)
676 std::make_pair(1026, dBr_u{-20.0}), // Inner band right (stop)
677 std::make_pair(1027, dBr_u{-20.0}), // Flat junction band right (start)
678 std::make_pair(1027, dBr_u{-20.0}), // Flat junction band right (stop)
679 std::make_pair(1028, dBr_u{-20.032}), // Middle band right (start)
680 std::make_pair(1280, dBr_u{-28.000}), // Middle band right (stop)
681 std::make_pair(1281, dBr_u{-28.047}), // Outer band right (start)
682 std::make_pair(1536, dBr_u{-40.0}), // Outer band right (stop)
683 };
684
685 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ac 160MHz",
688 MHz_u{160},
689 {MHz_u{5250}},
690 maskSlopes,
691 tol,
692 prec),
693 TestCase::Duration::QUICK);
694
695 // ============================================================================================
696 // 11ac 80+80MHz
697 NS_LOG_FUNCTION("Check slopes for 11ac 80+80MHz");
698 maskSlopes = {
699 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
700 std::make_pair(127, dBr_u{-28.094}), // Outer band left (stop)
701 std::make_pair(128, dBr_u{-28.000}), // Middle band left (start)
702 std::make_pair(252, dBr_u{-20.064}), // Middle band left (stop)
703 std::make_pair(253, dBr_u{-20.0}), // Flat junction band left (start)
704 std::make_pair(253, dBr_u{-20.0}), // Flat junction band left (stop)
705 std::make_pair(254, dBr_u{-20.0}), // Inner band left for first segment (start)
706 std::make_pair(259, dBr_u{-3.333}), // Inner band left for first segment (stop)
707 std::make_pair(509, dBr_u{-3.333}), // Inner band right for first segment (start)
708 std::make_pair(514, dBr_u{-20.0}), // Inner band right for first segment (stop)
709 std::make_pair(515, dBr_u{-20.0}), // Flat junction band right for first segment (start)
710 std::make_pair(515, dBr_u{-20.0}), // Flat junction band right for first segment (stop)
711 std::make_pair(516, dBr_u{-20.01}), // start linear sum region left (no interpolation
712 // possible, so provide 2 times the same point)
713 std::make_pair(516, dBr_u{-20.01}), // start linear sum region left (no interpolation
714 // possible, so provide 2 times the same point)
715 std::make_pair(639, dBr_u{-24.99}), // stop linear sum region left (no interpolation
716 // possible, so provide 2 times the same point)
717 std::make_pair(639, dBr_u{-24.99}), // stop linear sum region left (no interpolation
718 // possible, so provide 2 times the same point)
719 std::make_pair(640, dBr_u{-25.0}), // middle linear sum region (no interpolation possible,
720 // so provide 2 times the same point)
721 std::make_pair(640, dBr_u{-25.0}), // middle linear sum region (no interpolation possible,
722 // so provide 2 times the same point)
723 std::make_pair(641, dBr_u{-24.99}), // start linear sum region right (no interpolation
724 // possible, so provide 2 times the same point)
725 std::make_pair(641, dBr_u{-24.99}), // start linear sum region right (no interpolation
726 // possible, so provide 2 times the same point)
727 std::make_pair(764, dBr_u{-20.01}), // stop linear sum region right (no interpolation
728 // possible, so provide 2 times the same point)
729 std::make_pair(764, dBr_u{-20.01}), // stop linear sum region right (no interpolation
730 // possible, so provide 2 times the same point)
731 std::make_pair(765, dBr_u{-20.0}), // Flat junction band left (start)
732 std::make_pair(765, dBr_u{-20.0}), // Flat junction band left (stop)
733 std::make_pair(766, dBr_u{-20.0}), // Inner band left for second segment (start)
734 std::make_pair(771, dBr_u{-3.333}), // Inner band left for second segment (stop)
735 std::make_pair(1021, dBr_u{-3.333}), // Inner band right for second segment (start)
736 std::make_pair(1026, dBr_u{-20.0}), // Inner band right for second segment (stop)
737 std::make_pair(1027, dBr_u{-20.0}), // Flat junction band right (start)
738 std::make_pair(1027, dBr_u{-20.0}), // Flat junction band right (stop)
739 std::make_pair(1028, dBr_u{-20.016}), // Middle band right (start)
740 std::make_pair(1152, dBr_u{-28.000}), // Middle band right (stop)
741 std::make_pair(1153, dBr_u{-28.023}), // Outer band right (start)
742 std::make_pair(1280, dBr_u{-40.0}), // Outer band right (stop)
743 };
744
745 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ac 80+80MHz",
748 MHz_u{160},
749 {MHz_u{5530}, MHz_u{5690}},
750 maskSlopes,
751 tol,
752 prec),
753 TestCase::Duration::QUICK);
754
755 // ============================================================================================
756 // 11ax 20MHz @ 2.4GHz
757 NS_LOG_FUNCTION("Check slopes for 11ax 20MHz @ 2.4GHz");
758 maskSlopes = {
759 std::make_pair(0, dBr_u{-45.000}), // Outer band left (start)
760 std::make_pair(127, dBr_u{-28.133}), // Outer band left (stop)
761 std::make_pair(128, dBr_u{-28.000}), // Middle band left (start)
762 std::make_pair(252, dBr_u{-20.064}), // Middle band left (stop)
763 std::make_pair(253, dBr_u{-20.0}), // Flat junction band left (start)
764 std::make_pair(255, dBr_u{-20.0}), // Flat junction band left (stop)
765 std::make_pair(256, dBr_u{-20.0}), // Inner band left (start)
766 std::make_pair(261, dBr_u{-3.333}), // Inner band left (stop)
767 std::make_pair(262, dBr_u{0.0}), // allocated band left (start)
768 std::make_pair(382, dBr_u{0.0}), // allocated band left (stop)
769 std::make_pair(383, dBr_u{-20.0}), // DC band (start)
770 std::make_pair(385, dBr_u{-20.0}), // DC band (stop)
771 std::make_pair(386, dBr_u{0.0}), // allocated band right (start)
772 std::make_pair(506, dBr_u{0.0}), // allocated band right (stop)
773 std::make_pair(507, dBr_u{-3.333}), // Inner band right (start)
774 std::make_pair(512, dBr_u{-20.0}), // Inner band right (stop)
775 std::make_pair(513, dBr_u{-20.0}), // Flat junction band right (start)
776 std::make_pair(515, dBr_u{-20.0}), // Flat junction band right (stop)
777 std::make_pair(516, dBr_u{-20.064}), // Middle band right (start)
778 std::make_pair(640, dBr_u{-28.000}), // Middle band right (stop)
779 std::make_pair(641, dBr_u{-28.133}), // Outer band right (start)
780 std::make_pair(768, dBr_u{-45.000}), // Outer band right (stop)
781 };
782
783 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_2.4GHz 20MHz",
786 MHz_u{20},
787 {MHz_u{2412}},
788 maskSlopes,
789 tol,
790 prec),
791 TestCase::Duration::QUICK);
792
793 // ============================================================================================
794 // 11ax 20MHz @ 5GHz
795 NS_LOG_FUNCTION("Check slopes for 11ax 20MHz @ 5GHz");
796 maskSlopes = {
797 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
798 std::make_pair(127, dBr_u{-28.094}), // Outer band left (stop)
799 std::make_pair(128, dBr_u{-28.000}), // Middle band left (start)
800 std::make_pair(252, dBr_u{-20.064}), // Middle band left (stop)
801 std::make_pair(253, dBr_u{-20.0}), // Flat junction band left (start)
802 std::make_pair(255, dBr_u{-20.0}), // Flat junction band left (stop)
803 std::make_pair(256, dBr_u{-20.0}), // Inner band left (start)
804 std::make_pair(261, dBr_u{-3.333}), // Inner band left (stop)
805 std::make_pair(262, dBr_u{0.0}), // allocated band left (start)
806 std::make_pair(382, dBr_u{0.0}), // allocated band left (stop)
807 std::make_pair(383, dBr_u{-20.0}), // DC band (start)
808 std::make_pair(385, dBr_u{-20.0}), // DC band (stop)
809 std::make_pair(386, dBr_u{0.0}), // allocated band right (start)
810 std::make_pair(506, dBr_u{0.0}), // allocated band right (stop)
811 std::make_pair(507, dBr_u{-3.333}), // Inner band right (start)
812 std::make_pair(512, dBr_u{-20.0}), // Inner band right (stop)
813 std::make_pair(513, dBr_u{-20.0}), // Flat junction band right (start)
814 std::make_pair(515, dBr_u{-20.0}), // Flat junction band right (stop)
815 std::make_pair(516, dBr_u{-20.064}), // Middle band right (start)
816 std::make_pair(640, dBr_u{-28.000}), // Middle band right (stop)
817 std::make_pair(641, dBr_u{-28.094}), // Outer band right (start)
818 std::make_pair(768, dBr_u{-40.0}), // Outer band right (stop)
819 };
820
821 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 20MHz",
824 MHz_u{20},
825 {MHz_u{5180}},
826 maskSlopes,
827 tol,
828 prec),
829 TestCase::Duration::QUICK);
830
831 // ============================================================================================
832 // 11ax 40MHz @ 2.4GHz
833 NS_LOG_FUNCTION("Check slopes for 11ax 40MHz @ 2.4GHz");
834 maskSlopes = {
835 std::make_pair(0, dBr_u{-45.000}), // Outer band left (start)
836 std::make_pair(255, dBr_u{-28.066}), // Outer band left (stop)
837 std::make_pair(256, dBr_u{-28.000}), // Middle band left (start)
838 std::make_pair(505, dBr_u{-20.032}), // Middle band left (stop)
839 std::make_pair(506, dBr_u{-20.0}), // Flat junction band left (start)
840 std::make_pair(510, dBr_u{-20.0}), // Flat junction band left (stop)
841 std::make_pair(511, dBr_u{-20.0}), // Inner band left (start)
842 std::make_pair(523, dBr_u{-1.538}), // Inner band left (stop)
843 std::make_pair(524, dBr_u{0.0}), // allocated band left (start)
844 std::make_pair(765, dBr_u{0.0}), // allocated band left (stop)
845 std::make_pair(766, dBr_u{-20.0}), // DC band (start)
846 std::make_pair(770, dBr_u{-20.0}), // DC band (stop)
847 std::make_pair(771, dBr_u{0.0}), // allocated band right (start)
848 std::make_pair(1012, dBr_u{0.0}), // allocated band right (stop)
849 std::make_pair(1013, dBr_u{-1.538}), // Inner band right (start)
850 std::make_pair(1025, dBr_u{-20.0}), // Inner band right (stop)
851 std::make_pair(1026, dBr_u{-20.0}), // Flat junction band right (start)
852 std::make_pair(1030, dBr_u{-20.0}), // Flat junction band right (stop)
853 std::make_pair(1031, dBr_u{-20.032}), // Middle band right (start)
854 std::make_pair(1280, dBr_u{-28.000}), // Middle band right (stop)
855 std::make_pair(1281, dBr_u{-28.066}), // Outer band right (start)
856 std::make_pair(1536, dBr_u{-45.000}), // Outer band right (stop)
857 };
858
859 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_2.4GHz 40MHz",
862 MHz_u{40},
863 {MHz_u{2422}},
864 maskSlopes,
865 tol,
866 prec),
867 TestCase::Duration::QUICK);
868
869 // ============================================================================================
870 // 11ax 40MHz @ 5GHz
871 NS_LOG_FUNCTION("Check slopes for 11ax 40MHz @ 5GHz");
872 maskSlopes = {
873 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
874 std::make_pair(255, dBr_u{-28.047}), // Outer band left (stop)
875 std::make_pair(256, dBr_u{-28.000}), // Middle band left (start)
876 std::make_pair(505, dBr_u{-20.032}), // Middle band left (stop)
877 std::make_pair(506, dBr_u{-20.0}), // Flat junction band left (start)
878 std::make_pair(510, dBr_u{-20.0}), // Flat junction band left (stop)
879 std::make_pair(511, dBr_u{-20.0}), // Inner band left (start)
880 std::make_pair(523, dBr_u{-1.538}), // Inner band left (stop)
881 std::make_pair(524, dBr_u{0.0}), // allocated band left (start)
882 std::make_pair(765, dBr_u{0.0}), // allocated band left (stop)
883 std::make_pair(766, dBr_u{-20.0}), // DC band (start)
884 std::make_pair(770, dBr_u{-20.0}), // DC band (stop)
885 std::make_pair(771, dBr_u{0.0}), // allocated band right (start)
886 std::make_pair(1012, dBr_u{0.0}), // allocated band right (stop)
887 std::make_pair(1013, dBr_u{-1.538}), // Inner band right (start)
888 std::make_pair(1025, dBr_u{-20.0}), // Inner band right (stop)
889 std::make_pair(1026, dBr_u{-20.0}), // Flat junction band right (start)
890 std::make_pair(1030, dBr_u{-20.0}), // Flat junction band right (stop)
891 std::make_pair(1031, dBr_u{-20.032}), // Middle band right (start)
892 std::make_pair(1280, dBr_u{-28.000}), // Middle band right (stop)
893 std::make_pair(1281, dBr_u{-28.047}), // Outer band right (start)
894 std::make_pair(1536, dBr_u{-40.0}), // Outer band right (stop)
895 };
896
897 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 40MHz",
900 MHz_u{40},
901 {MHz_u{5190}},
902 maskSlopes,
903 tol,
904 prec),
905 TestCase::Duration::QUICK);
906
907 // ============================================================================================
908 // 11ax 80MHz @ 5GHz
909 NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz");
910 maskSlopes = {
911 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
912 std::make_pair(511, dBr_u{-28.023}), // Outer band left (stop)
913 std::make_pair(512, dBr_u{-28.000}), // Middle band left (start)
914 std::make_pair(1017, dBr_u{-20.016}), // Middle band left (stop)
915 std::make_pair(1018, dBr_u{-20.0}), // Flat junction band left (start)
916 std::make_pair(1022, dBr_u{-20.0}), // Flat junction band left (stop)
917 std::make_pair(1023, dBr_u{-20.0}), // Inner band left (start)
918 std::make_pair(1035, dBr_u{-1.538}), // Inner band left (stop)
919 std::make_pair(1036, dBr_u{0.0}), // allocated band left (start)
920 std::make_pair(1533, dBr_u{0.0}), // allocated band left (stop)
921 std::make_pair(1534, dBr_u{-20.0}), // DC band (start)
922 std::make_pair(1538, dBr_u{-20.0}), // DC band (stop)
923 std::make_pair(1539, dBr_u{0.0}), // allocated band right (start)
924 std::make_pair(2036, dBr_u{0.0}), // allocated band right (stop)
925 std::make_pair(2037, dBr_u{-1.538}), // Inner band right (start)
926 std::make_pair(2049, dBr_u{-20.0}), // Inner band right (stop)
927 std::make_pair(2050, dBr_u{-20.0}), // Flat junction band right (start)
928 std::make_pair(2054, dBr_u{-20.0}), // Flat junction band right (stop)
929 std::make_pair(2055, dBr_u{-20.016}), // Middle band right (start)
930 std::make_pair(2560, dBr_u{-28.000}), // Middle band right (stop)
931 std::make_pair(2561, dBr_u{-28.023}), // Outer band right (start)
932 std::make_pair(3072, dBr_u{-40.0}), // Outer band right (stop)
933 };
934
935 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz",
938 MHz_u{80},
939 {MHz_u{5210}},
940 maskSlopes,
941 tol,
942 prec),
943 TestCase::Duration::QUICK);
944
945 // ============================================================================================
946 // 11ax 160MHz @ 5GHz
947 NS_LOG_FUNCTION("Check slopes for 11ax 160MHz @ 5GHz");
948 maskSlopes = {
949 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
950 std::make_pair(1023, dBr_u{-28.012}), // Outer band left (stop)
951 std::make_pair(1024, dBr_u{-28.000}), // Middle band left (start)
952 std::make_pair(2041, dBr_u{-20.008}), // Middle band left (stop)
953 std::make_pair(2042, dBr_u{-20.0}), // Flat junction band left (start)
954 std::make_pair(2046, dBr_u{-20.0}), // Flat junction band left (stop)
955 std::make_pair(2047, dBr_u{-20.0}), // Inner band left (start)
956 std::make_pair(2059, dBr_u{-1.538}), // Inner band left (stop)
957 std::make_pair(2060, dBr_u{0.0}), // first 80 MHz allocated band left (start)
958 std::make_pair(2557, dBr_u{0.0}), // first 80 MHz allocated band left (stop)
959 std::make_pair(2558, dBr_u{-20.0}), // first 80 MHz DC band (start)
960 std::make_pair(2562, dBr_u{-20.0}), // first 80 MHz DC band (stop)
961 std::make_pair(2563, dBr_u{0.0}), // first 80 MHz allocated band right (start)
962 std::make_pair(3060, dBr_u{0.0}), // first 80 MHz allocated band right (stop)
963 std::make_pair(3061, dBr_u{-20.0}), // gap between 80 MHz bands (start)
964 std::make_pair(3083, dBr_u{-20.0}), // gap between 80 MHz bands (start)
965 std::make_pair(3084, dBr_u{0.0}), // second 80 MHz allocated band left (start)
966 std::make_pair(3581, dBr_u{0.0}), // second 80 MHz allocated band left (stop)
967 std::make_pair(3582, dBr_u{-20.0}), // second 80 MHz DC band (start)
968 std::make_pair(3586, dBr_u{-20.0}), // second 80 MHz DC band (stop)
969 std::make_pair(3587, dBr_u{0.0}), // second 80 MHz allocated band right (start)
970 std::make_pair(4084, dBr_u{0.0}), // second 80 MHz allocated band right (stop)
971 std::make_pair(4085, dBr_u{-1.538}), // Inner band right (start)
972 std::make_pair(4097, dBr_u{-20.0}), // Inner band right (stop)
973 std::make_pair(4098, dBr_u{-20.0}), // Flat junction band right (start)
974 std::make_pair(4102, dBr_u{-20.0}), // Flat junction band right (stop)
975 std::make_pair(4103, dBr_u{-20.008}), // Middle band right (start)
976 std::make_pair(5120, dBr_u{-28.000}), // Middle band right (stop)
977 std::make_pair(5121, dBr_u{-28.012}), // Outer band right (start)
978 std::make_pair(6144, dBr_u{-40.0}), // Outer band right (stop)
979 };
980
981 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz",
984 MHz_u{160},
985 {MHz_u{5250}},
986 maskSlopes,
987 tol,
988 prec),
989 TestCase::Duration::QUICK);
990
991 // ============================================================================================
992 // 11ax 80+80MHz @ 5GHz
993 NS_LOG_FUNCTION("Check slopes for 11ax 80+80MHz @ 5GHz");
994 maskSlopes = {
995 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
996 std::make_pair(511, dBr_u{-28.023}), // Outer band left (stop)
997 std::make_pair(512, dBr_u{-28.000}), // Middle band left (start)
998 std::make_pair(1017, dBr_u{-20.016}), // Middle band left (stop)
999 std::make_pair(1018, dBr_u{-20.0}), // Flat junction band left (start)
1000 std::make_pair(1022, dBr_u{-20.0}), // Flat junction band left (stop)
1001 std::make_pair(1023, dBr_u{-20.0}), // Inner band left for first segment (start)
1002 std::make_pair(1035, dBr_u{-1.538}), // Inner band left for first segment (stop)
1003 std::make_pair(1036, dBr_u{0.0}), // allocated band left for first segment (start)
1004 std::make_pair(1533, dBr_u{0.0}), // allocated band left for first segment (stop)
1005 std::make_pair(1534, dBr_u{-20.0}), // DC band for first segment (start)
1006 std::make_pair(1538, dBr_u{-20.0}), // DC band for first segment (stop)
1007 std::make_pair(1539, dBr_u{0.0}), // allocated band right for first segment (start)
1008 std::make_pair(2036, dBr_u{0.0}), // allocated band right for first segment (stop)
1009 std::make_pair(2037, dBr_u{-1.538}), // Inner band right for first segment (start)
1010 std::make_pair(2049, dBr_u{-20.0}), // Inner band right for first segment (stop)
1011 std::make_pair(2050, dBr_u{-20.0}), // Flat junction band right for first segment (start)
1012 std::make_pair(2054, dBr_u{-20.0}), // Flat junction band right for first segment (stop)
1013 std::make_pair(2055, dBr_u{-20.01}), // start linear sum region left (no interpolation
1014 // possible, so provide 2 times the same point)
1015 std::make_pair(2055, dBr_u{-20.01}), // start linear sum region left (no interpolation
1016 // possible, so provide 2 times the same point)
1017 std::make_pair(2559, dBr_u{-24.99}), // stop linear sum region left (no interpolation
1018 // possible, so provide 2 times the same point)
1019 std::make_pair(2559, dBr_u{-24.99}), // stop linear sum region left (no interpolation
1020 // possible, so provide 2 times the same point)
1021 std::make_pair(2560, dBr_u{-25.0}), // middle linear sum region (no interpolation possible,
1022 // so provide 2 times the same point)
1023 std::make_pair(2560, dBr_u{-25.0}), // middle linear sum region (no interpolation possible,
1024 // so provide 2 times the same point)
1025 std::make_pair(2561, dBr_u{-24.99}), // start linear sum region right (no interpolation
1026 // possible, so provide 2 times the same point)
1027 std::make_pair(2561, dBr_u{-24.99}), // start linear sum region right (no interpolation
1028 // possible, so provide 2 times the same point)
1029 std::make_pair(3065, dBr_u{-20.01}), // stop linear sum region right (no interpolation
1030 // possible, so provide 2 times the same point)
1031 std::make_pair(3065, dBr_u{-20.01}), // stop linear sum region right (no interpolation
1032 // possible, so provide 2 times the same point)
1033 std::make_pair(3066, dBr_u{-20.0}), // Flat junction band left (start)
1034 std::make_pair(3070, dBr_u{-20.0}), // Flat junction band left (stop)
1035 std::make_pair(3071, dBr_u{-20.0}), // Inner band left for second segment (start)
1036 std::make_pair(3083, dBr_u{-1.538}), // Inner band left for second segment (stop)
1037 std::make_pair(3084, dBr_u{0.0}), // allocated band left for second segment (start)
1038 std::make_pair(3581, dBr_u{0.0}), // allocated band left for second segment (stop)
1039 std::make_pair(3582, dBr_u{-20.0}), // DC band for second segment (start)
1040 std::make_pair(3586, dBr_u{-20.0}), // DC band for second segment (stop)
1041 std::make_pair(3587, dBr_u{0.0}), // allocated band right for second segment (start)
1042 std::make_pair(4084, dBr_u{0.0}), // allocated band right for second segment (stop)
1043 std::make_pair(4085, dBr_u{-1.538}), // Inner band right for second segment (start)
1044 std::make_pair(4097, dBr_u{-20.0}), // Inner band right for second segment (stop)
1045 std::make_pair(4098, dBr_u{-20.0}), // Flat junction band right (start)
1046 std::make_pair(4102, dBr_u{-20.0}), // Flat junction band right (stop)
1047 std::make_pair(4103, dBr_u{-20.016}), // Middle band right (start)
1048 std::make_pair(4608, dBr_u{-28.000}), // Middle band right (stop)
1049 std::make_pair(4609, dBr_u{-28.023}), // Outer band right (start)
1050 std::make_pair(5120, dBr_u{-40.0}), // Outer band right (stop)
1051 };
1052
1053 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80+80MHz",
1056 MHz_u{160},
1057 {MHz_u{5530}, MHz_u{5690}},
1058 maskSlopes,
1059 tol,
1060 prec),
1061 TestCase::Duration::QUICK);
1062
1063 // ============================================================================================
1064 // 11ax 80+80MHz @ 5GHz
1065 NS_LOG_FUNCTION("Check slopes for 11ax 80+80MHz @ 5GHz with larger frequency separation "
1066 "between the two PSDs");
1067 maskSlopes = {
1068 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
1069 std::make_pair(511, dBr_u{-28.023}), // Outer band left (stop)
1070 std::make_pair(512, dBr_u{-28.000}), // Middle band left (start)
1071 std::make_pair(1017, dBr_u{-20.016}), // Middle band left (stop)
1072 std::make_pair(1018, dBr_u{-20.0}), // Flat junction band left (start)
1073 std::make_pair(1022, dBr_u{-20.0}), // Flat junction band left (stop)
1074 std::make_pair(1023, dBr_u{-20.0}), // Inner band left for first segment (start)
1075 std::make_pair(1035, dBr_u{-1.538}), // Inner band left for first segment (stop)
1076 std::make_pair(1036, dBr_u{0.0}), // allocated band left for first segment (start)
1077 std::make_pair(1533, dBr_u{0.0}), // allocated band left for first segment (stop)
1078 std::make_pair(1534, dBr_u{-20.0}), // DC band for first segment (start)
1079 std::make_pair(1538, dBr_u{-20.0}), // DC band for first segment (stop)
1080 std::make_pair(1539, dBr_u{0.0}), // allocated band right for first segment (start)
1081 std::make_pair(2036, dBr_u{0.0}), // allocated band right for first segment (stop)
1082 std::make_pair(2037, dBr_u{-1.538}), // Inner band right for first segment (start)
1083 std::make_pair(2049, dBr_u{-20.0}), // Inner band right for first segment (stop)
1084 std::make_pair(2050, dBr_u{-20.0}), // Flat junction band right for first segment (start)
1085 std::make_pair(2054, dBr_u{-20.0}), // Flat junction band right for first segment (stop)
1086 std::make_pair(2055, dBr_u{-20.01}), // start linear sum region left (no interpolation
1087 // possible, so provide 2 times the same point)
1088 std::make_pair(2055, dBr_u{-20.01}), // start linear sum region left (no interpolation
1089 // possible, so provide 2 times the same point)
1090 std::make_pair(3583, dBr_u{-24.99}), // stop linear sum region left (no interpolation
1091 // possible, so provide 2 times the same point)
1092 std::make_pair(3583, dBr_u{-24.99}), // stop linear sum region left (no interpolation
1093 // possible, so provide 2 times the same point)
1094 std::make_pair(3584, dBr_u{-25.0}), // middle linear sum region (no interpolation possible,
1095 // so provide 2 times the same point)
1096 std::make_pair(3584, dBr_u{-25.0}), // middle linear sum region (no interpolation possible,
1097 // so provide 2 times the same point)
1098 std::make_pair(3585, dBr_u{-24.99}), // start linear sum region right (no interpolation
1099 // possible, so provide 2 times the same point)
1100 std::make_pair(3585, dBr_u{-24.99}), // start linear sum region right (no interpolation
1101 // possible, so provide 2 times the same point)
1102 std::make_pair(5113, dBr_u{-20.01}), // stop linear sum region right (no interpolation
1103 // possible, so provide 2 times the same point)
1104 std::make_pair(5113, dBr_u{-20.01}), // stop linear sum region right (no interpolation
1105 // possible, so provide 2 times the same point)
1106 std::make_pair(5114, dBr_u{-20.0}), // Flat junction band left (start)
1107 std::make_pair(5118, dBr_u{-20.0}), // Flat junction band left (stop)
1108 std::make_pair(5119, dBr_u{-20.0}), // Inner band left for second segment (start)
1109 std::make_pair(5131, dBr_u{-1.538}), // Inner band left for second segment (stop)
1110 std::make_pair(5132, dBr_u{0.0}), // allocated band left for second segment (start)
1111 std::make_pair(5629, dBr_u{0.0}), // allocated band left for second segment (stop)
1112 std::make_pair(5630, dBr_u{-20.0}), // DC band for second segment (start)
1113 std::make_pair(5634, dBr_u{-20.0}), // DC band for second segment (stop)
1114 std::make_pair(5635, dBr_u{0.0}), // allocated band right for second segment (start)
1115 std::make_pair(6132, dBr_u{0.0}), // allocated band right for second segment (stop)
1116 std::make_pair(6133, dBr_u{-1.538}), // Inner band right for second segment (start)
1117 std::make_pair(6145, dBr_u{-20.0}), // Inner band right for second segment (stop)
1118 std::make_pair(6146, dBr_u{-20.0}), // Flat junction band right (start)
1119 std::make_pair(6150, dBr_u{-20.0}), // Flat junction band right (stop)
1120 std::make_pair(6151, dBr_u{-20.016}), // Middle band right (start)
1121 std::make_pair(6656, dBr_u{-28.000}), // Middle band right (stop)
1122 std::make_pair(6657, dBr_u{-28.023}), // Outer band right (start)
1123 std::make_pair(7168, dBr_u{-40.0}), // Outer band right (stop)
1124 };
1125
1126 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80+80MHz large separation",
1129 MHz_u{160},
1130 {MHz_u{5210}, MHz_u{5530}},
1131 maskSlopes,
1132 tol,
1133 prec),
1134 TestCase::Duration::QUICK);
1135
1136 // ============================================================================================
1137 // 11ax 80MHz @ 5GHz - first 20 MHz subchannel punctured
1138 NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz with first 20 MHz subchannel punctured");
1139 maskSlopes = {
1140 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
1141 std::make_pair(511, dBr_u{-28.023}), // Outer band left (stop)
1142 std::make_pair(512, dBr_u{-28.000}), // Middle band left (start)
1143 std::make_pair(1017, dBr_u{-20.016}), // Middle band left (stop)
1144 std::make_pair(1018, dBr_u{-20.0}), // Flat junction band left (start)
1145 std::make_pair(1022, dBr_u{-20.0}), // Flat junction band left (stop)
1146 std::make_pair(1023, dBr_u{-20.0}), // punctured band (start)
1147 std::make_pair(1272, dBr_u{-20.0}), // punctured band (stop)
1148 std::make_pair(1273, dBr_u{-20.0}), // punctured band increasing slope (start)
1149 std::make_pair(1279, dBr_u{0.0}), // punctured band increasing slope (stop)
1150 std::make_pair(1280, dBr_u{0.0}), // allocated band left (start)
1151 std::make_pair(1533, dBr_u{0.0}), // allocated band left (stop)
1152 std::make_pair(1534, dBr_u{-20.0}), // DC band (start)
1153 std::make_pair(1538, dBr_u{-20.0}), // DC band (stop)
1154 std::make_pair(1539, dBr_u{0.0}), // allocated band right (start)
1155 std::make_pair(2036, dBr_u{0.0}), // allocated band right (stop)
1156 std::make_pair(2037, dBr_u{-1.538}), // Inner band right (start)
1157 std::make_pair(2049, dBr_u{-20.0}), // Inner band right (stop)
1158 std::make_pair(2050, dBr_u{-20.0}), // Flat junction band right (start)
1159 std::make_pair(2054, dBr_u{-20.0}), // Flat junction band right (stop)
1160 std::make_pair(2055, dBr_u{-20.016}), // Middle band right (start)
1161 std::make_pair(2560, dBr_u{-28.000}), // Middle band right (stop)
1162 std::make_pair(2561, dBr_u{-28.023}), // Outer band right (start)
1163 std::make_pair(3072, dBr_u{-40.0}), // Outer band right (stop)
1164 };
1165
1166 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz first subchannel punctured",
1169 MHz_u{80},
1170 {MHz_u{5210}},
1171 maskSlopes,
1172 tol,
1173 prec,
1174 {true, false, false, false}),
1175 TestCase::Duration::QUICK);
1176
1177 // ============================================================================================
1178 // 11ax 80MHz @ 5GHz - second 20 MHz subchannel punctured
1179 NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz with second 20 MHz subchannel punctured");
1180 maskSlopes = {
1181 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
1182 std::make_pair(511, dBr_u{-28.023}), // Outer band left (stop)
1183 std::make_pair(512, dBr_u{-28.000}), // Middle band left (start)
1184 std::make_pair(1017, dBr_u{-20.016}), // Middle band left (stop)
1185 std::make_pair(1018, dBr_u{-20.0}), // Flat junction band left (start)
1186 std::make_pair(1022, dBr_u{-20.0}), // Flat junction band left (stop)
1187 std::make_pair(1023, dBr_u{-20.0}), // Inner band left (start)
1188 std::make_pair(1035, dBr_u{-1.538}), // Inner band left (stop)
1189 std::make_pair(1036, dBr_u{0.0}), // allocated band left (start)
1190 std::make_pair(1279, dBr_u{0.0}), // allocated band left (stop)
1191 std::make_pair(1280, dBr_u{0.0}), // punctured band decreasing slope (start)
1192 std::make_pair(1286, dBr_u{-20.0}), // punctured band decreasing slope (stop)
1193 std::make_pair(1287, dBr_u{-20.0}), // punctured band (start)
1194 std::make_pair(1528, dBr_u{-20.0}), // punctured band (stop)
1195 std::make_pair(1529, dBr_u{-20.0}), // punctured band increasing slope (start)
1196 std::make_pair(1533, dBr_u{-6.667}), // punctured band increasing slope (stop)
1197 std::make_pair(1534, dBr_u{-20.0}), // DC band (start)
1198 std::make_pair(1538, dBr_u{-20.0}), // DC band (stop)
1199 std::make_pair(1539, dBr_u{0.0}), // allocated band right (start)
1200 std::make_pair(2036, dBr_u{0.0}), // allocated band right (stop)
1201 std::make_pair(2037, dBr_u{-1.538}), // Inner band right (start)
1202 std::make_pair(2049, dBr_u{-20.0}), // Inner band right (stop)
1203 std::make_pair(2050, dBr_u{-20.0}), // Flat junction band right (start)
1204 std::make_pair(2054, dBr_u{-20.0}), // Flat junction band right (stop)
1205 std::make_pair(2055, dBr_u{-20.016}), // Middle band right (start)
1206 std::make_pair(2560, dBr_u{-28.000}), // Middle band right (stop)
1207 std::make_pair(2561, dBr_u{-28.023}), // Outer band right (start)
1208 std::make_pair(3072, dBr_u{-40.0}), // Outer band right (stop)
1209 };
1210
1211 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz second subchannel punctured",
1214 MHz_u{80},
1215 {MHz_u{5210}},
1216 maskSlopes,
1217 tol,
1218 prec,
1219 {false, true, false, false}),
1220 TestCase::Duration::QUICK);
1221
1222 // ============================================================================================
1223 // 11ax 80MHz @ 5GHz - third 20 MHz subchannel punctured
1224 NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz with third 20 MHz subchannel punctured");
1225 maskSlopes = {
1226 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
1227 std::make_pair(511, dBr_u{-28.023}), // Outer band left (stop)
1228 std::make_pair(512, dBr_u{-28.000}), // Middle band left (start)
1229 std::make_pair(1017, dBr_u{-20.016}), // Middle band left (stop)
1230 std::make_pair(1018, dBr_u{-20.0}), // Flat junction band left (start)
1231 std::make_pair(1022, dBr_u{-20.0}), // Flat junction band left (stop)
1232 std::make_pair(1023, dBr_u{-20.0}), // Inner band left (start)
1233 std::make_pair(1035, dBr_u{-1.538}), // Inner band left (stop)
1234 std::make_pair(1036, dBr_u{0.0}), // allocated band left (start)
1235 std::make_pair(1533, dBr_u{0.0}), // allocated band left (stop)
1236 std::make_pair(1534, dBr_u{-20.0}), // DC band (start)
1237 std::make_pair(1535, dBr_u{-20.0}), // DC band (stop)
1238 std::make_pair(1539, dBr_u{-10.0}), // punctured band decreasing slope (start)
1239 std::make_pair(1542, dBr_u{-20.0}), // punctured band decreasing slope (stop)
1240 std::make_pair(1543, dBr_u{-20.0}), // punctured band (start)
1241 std::make_pair(1784, dBr_u{-20.0}), // punctured band (stop)
1242 std::make_pair(1785, dBr_u{-20.0}), // punctured band increasing slope (start)
1243 std::make_pair(1791, dBr_u{0.0}), // punctured band increasing slope (stop)
1244 std::make_pair(1792, dBr_u{0.0}), // allocated band right (start)
1245 std::make_pair(2036, dBr_u{0.0}), // allocated band right (stop)
1246 std::make_pair(2037, dBr_u{-1.538}), // Inner band right (start)
1247 std::make_pair(2049, dBr_u{-20.0}), // Inner band right (stop)
1248 std::make_pair(2050, dBr_u{-20.0}), // Flat junction band right (start)
1249 std::make_pair(2054, dBr_u{-20.0}), // Flat junction band right (stop)
1250 std::make_pair(2055, dBr_u{-20.016}), // Middle band right (start)
1251 std::make_pair(2560, dBr_u{-28.000}), // Middle band right (stop)
1252 std::make_pair(2561, dBr_u{-28.023}), // Outer band right (start)
1253 std::make_pair(3072, dBr_u{-40.0}), // Outer band right (stop)
1254 };
1255
1256 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz third subchannel punctured",
1259 MHz_u{80},
1260 {MHz_u{5210}},
1261 maskSlopes,
1262 tol,
1263 prec,
1264 {false, false, true, false}),
1265 TestCase::Duration::QUICK);
1266
1267 // ============================================================================================
1268 // 11ax 80MHz @ 5GHz - last 20 MHz subchannel punctured
1269 NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz with last 20 MHz subchannel punctured");
1270 maskSlopes = {
1271 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
1272 std::make_pair(511, dBr_u{-28.023}), // Outer band left (stop)
1273 std::make_pair(512, dBr_u{-28.000}), // Middle band left (start)
1274 std::make_pair(1017, dBr_u{-20.016}), // Middle band left (stop)
1275 std::make_pair(1018, dBr_u{-20.0}), // Flat junction band left (start)
1276 std::make_pair(1022, dBr_u{-20.0}), // Flat junction band left (stop)
1277 std::make_pair(1023, dBr_u{-20.0}), // Inner band left (start)
1278 std::make_pair(1035, dBr_u{-1.538}), // Inner band left (stop)
1279 std::make_pair(1036, dBr_u{0.0}), // allocated band left (start)
1280 std::make_pair(1533, dBr_u{0.0}), // allocated band left (stop)
1281 std::make_pair(1534, dBr_u{-20.0}), // DC band (start)
1282 std::make_pair(1538, dBr_u{-20.0}), // DC band (stop)
1283 std::make_pair(1539, dBr_u{0.0}), // allocated band right (start)
1284 std::make_pair(1791, dBr_u{0.0}), // allocated band right (stop)
1285 std::make_pair(1792, dBr_u{0.0}), // punctured band decreasing slope (start)
1286 std::make_pair(1798, dBr_u{-20.0}), // punctured band decreasing slope (stop)
1287 std::make_pair(1799, dBr_u{-20.0}), // punctured band (start)
1288 std::make_pair(2049, dBr_u{-20.0}), // punctured band (stop)
1289 std::make_pair(2050, dBr_u{-20.0}), // Flat junction band right (start)
1290 std::make_pair(2054, dBr_u{-20.0}), // Flat junction band right (stop)
1291 std::make_pair(2055, dBr_u{-20.016}), // Middle band right (start)
1292 std::make_pair(2560, dBr_u{-28.000}), // Middle band right (stop)
1293 std::make_pair(2561, dBr_u{-28.023}), // Outer band right (start)
1294 std::make_pair(3072, dBr_u{-40.0}), // Outer band right (stop)
1295 };
1296
1297 AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz last subchannel punctured",
1300 MHz_u{80},
1301 {MHz_u{5210}},
1302 maskSlopes,
1303 tol,
1304 prec,
1305 {false, false, false, true}),
1306 TestCase::Duration::QUICK);
1307
1308 // ============================================================================================
1309 // 11ax 160MHz @ 5GHz - first two 20 MHz subchannels punctured
1311 "Check slopes for 11ax 160MHz @ 5GHz with two first 20 MHz subchannels punctured");
1312 maskSlopes = {
1313 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
1314 std::make_pair(1023, dBr_u{-28.012}), // Outer band left (stop)
1315 std::make_pair(1024, dBr_u{-28.000}), // Middle band left (start)
1316 std::make_pair(2041, dBr_u{-20.008}), // Middle band left (stop)
1317 std::make_pair(2042, dBr_u{-20.0}), // Flat junction band left (start)
1318 std::make_pair(2046, dBr_u{-20.0}), // Flat junction band left (stop)
1319 std::make_pair(2047, dBr_u{-20.0}), // punctured band (start)
1320 std::make_pair(2552, dBr_u{-20.0}), // punctured band (stop)
1321 std::make_pair(2553, dBr_u{-20.0}), // punctured band increasing slope (start)
1322 std::make_pair(2557, dBr_u{-6.66667}), // punctured band increasing slope (stop)
1323 std::make_pair(2558, dBr_u{-20.0}), // first 80 MHz DC band (start)
1324 std::make_pair(2562, dBr_u{-20.0}), // first 80 MHz DC band (stop)
1325 std::make_pair(2563, dBr_u{0.0}), // first 80 MHz allocated band right (start)
1326 std::make_pair(3060, dBr_u{0.0}), // first 80 MHz allocated band right (stop)
1327 std::make_pair(3061, dBr_u{-20.0}), // gap between 80 MHz bands (start)
1328 std::make_pair(3083, dBr_u{-20.0}), // gap between 80 MHz bands (start)
1329 std::make_pair(3084, dBr_u{0.0}), // second 80 MHz allocated band left (start)
1330 std::make_pair(3581, dBr_u{0.0}), // second 80 MHz allocated band left (stop)
1331 std::make_pair(3582, dBr_u{-20.0}), // second 80 MHz DC band (start)
1332 std::make_pair(3586, dBr_u{-20.0}), // second 80 MHz DC band (stop)
1333 std::make_pair(3587, dBr_u{0.0}), // second 80 MHz allocated band right (start)
1334 std::make_pair(4084, dBr_u{0.0}), // second 80 MHz allocated band right (stop)
1335 std::make_pair(4085, dBr_u{-1.538}), // Inner band right (start)
1336 std::make_pair(4097, dBr_u{-20.0}), // Inner band right (stop)
1337 std::make_pair(4098, dBr_u{-20.0}), // Flat junction band right (start)
1338 std::make_pair(4102, dBr_u{-20.0}), // Flat junction band right (stop)
1339 std::make_pair(4103, dBr_u{-20.008}), // Middle band right (start)
1340 std::make_pair(5120, dBr_u{-28.000}), // Middle band right (stop)
1341 std::make_pair(5121, dBr_u{-28.012}), // Outer band right (start)
1342 std::make_pair(6144, dBr_u{-40.0}), // Outer band right (stop)
1343 };
1344
1346 new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz first subchannels punctured",
1349 MHz_u{160},
1350 {MHz_u{5250}},
1351 maskSlopes,
1352 tol,
1353 prec,
1354 {true, true, false, false, false, false, false, false}),
1355 TestCase::Duration::QUICK);
1356
1357 // ============================================================================================
1358 // 11ax 160MHz @ 5GHz - third and fourth 20 MHz subchannels punctured
1360 "Check slopes for 11ax 160MHz @ 5GHz with third and fourth 20 MHz subchannels punctured");
1361 maskSlopes = {
1362 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
1363 std::make_pair(1023, dBr_u{-28.012}), // Outer band left (stop)
1364 std::make_pair(1024, dBr_u{-28.000}), // Middle band left (start)
1365 std::make_pair(2041, dBr_u{-20.008}), // Middle band left (stop)
1366 std::make_pair(2042, dBr_u{-20.0}), // Flat junction band left (start)
1367 std::make_pair(2046, dBr_u{-20.0}), // Flat junction band left (stop)
1368 std::make_pair(2047, dBr_u{-20.0}), // Inner band left (start)
1369 std::make_pair(2059, dBr_u{-1.538}), // Inner band left (stop)
1370 std::make_pair(2060, dBr_u{0.0}), // first 80 MHz allocated band left (start)
1371 std::make_pair(2557, dBr_u{0.0}), // first 80 MHz allocated band left (stop)
1372 std::make_pair(2558, dBr_u{-20.0}), // first 80 MHz DC band (start)
1373 std::make_pair(2562, dBr_u{-20.0}), // first 80 MHz DC band (stop)
1374 std::make_pair(2563, dBr_u{-10.0}), // punctured band decreasing slope (start)
1375 std::make_pair(2566, dBr_u{-20.0}), // punctured band decreasing slope (stop)
1376 std::make_pair(2567, dBr_u{-20.0}), // punctured band (start)
1377 std::make_pair(3060, dBr_u{-20.0}), // punctured band (stop)
1378 std::make_pair(3061, dBr_u{-20.0}), // gap between 80 MHz bands (start)
1379 std::make_pair(3083, dBr_u{-20.0}), // gap between 80 MHz bands (start)
1380 std::make_pair(3084, dBr_u{0.0}), // second 80 MHz allocated band left (start)
1381 std::make_pair(3581, dBr_u{0.0}), // second 80 MHz allocated band left (stop)
1382 std::make_pair(3582, dBr_u{-20.0}), // second 80 MHz DC band (start)
1383 std::make_pair(3586, dBr_u{-20.0}), // second 80 MHz DC band (stop)
1384 std::make_pair(3587, dBr_u{0.0}), // second 80 MHz allocated band right (start)
1385 std::make_pair(4084, dBr_u{0.0}), // second 80 MHz allocated band right (stop)
1386 std::make_pair(4085, dBr_u{-1.538}), // Inner band right (start)
1387 std::make_pair(4097, dBr_u{-20.0}), // Inner band right (stop)
1388 std::make_pair(4098, dBr_u{-20.0}), // Flat junction band right (start)
1389 std::make_pair(4102, dBr_u{-20.0}), // Flat junction band right (stop)
1390 std::make_pair(4103, dBr_u{-20.008}), // Middle band right (start)
1391 std::make_pair(5120, dBr_u{-28.000}), // Middle band right (stop)
1392 std::make_pair(5121, dBr_u{-28.012}), // Outer band right (start)
1393 std::make_pair(6144, dBr_u{-40.0}), // Outer band right (stop)
1394 };
1395
1397 new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz third and fourth subchannels punctured",
1400 MHz_u{160},
1401 {MHz_u{5250}},
1402 maskSlopes,
1403 tol,
1404 prec,
1405 {false, false, true, true, false, false, false, false}),
1406 TestCase::Duration::QUICK);
1407
1408 // ============================================================================================
1409 // 11ax 160MHz @ 5GHz - fifth and sixth 20 MHz subchannels punctured
1411 "Check slopes for 11ax 160MHz @ 5GHz with fifth and sixth 20 MHz subchannels punctured");
1412 maskSlopes = {
1413 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
1414 std::make_pair(1023, dBr_u{-28.012}), // Outer band left (stop)
1415 std::make_pair(1024, dBr_u{-28.000}), // Middle band left (start)
1416 std::make_pair(2041, dBr_u{-20.008}), // Middle band left (stop)
1417 std::make_pair(2042, dBr_u{-20.0}), // Flat junction band left (start)
1418 std::make_pair(2046, dBr_u{-20.0}), // Flat junction band left (stop)
1419 std::make_pair(2047, dBr_u{-20.0}), // Inner band left (start)
1420 std::make_pair(2059, dBr_u{-1.538}), // Inner band left (stop)
1421 std::make_pair(2060, dBr_u{0.0}), // first 80 MHz allocated band left (start)
1422 std::make_pair(2557, dBr_u{0.0}), // first 80 MHz allocated band left (stop)
1423 std::make_pair(2558, dBr_u{-20.0}), // first 80 MHz DC band (start)
1424 std::make_pair(2562, dBr_u{-20.0}), // first 80 MHz DC band (stop)
1425 std::make_pair(2563, dBr_u{0.0}), // first 80 MHz allocated band right (start)
1426 std::make_pair(3060, dBr_u{0.0}), // first 80 MHz allocated band right (stop)
1427 std::make_pair(3061, dBr_u{-20.0}), // gap between 80 MHz bands (start)
1428 std::make_pair(3083, dBr_u{-20.0}), // gap between 80 MHz bands (start)
1429 std::make_pair(3084, dBr_u{-20.0}), // punctured band (start)
1430 std::make_pair(3576, dBr_u{-20.0}), // punctured band (stop)
1431 std::make_pair(3577, dBr_u{-20.0}), // punctured band increasing slope (start)
1432 std::make_pair(3581, dBr_u{-6.667}), // punctured band increasing slope (stop)
1433 std::make_pair(3582, dBr_u{-20.0}), // second 80 MHz DC band (start)
1434 std::make_pair(3586, dBr_u{-20.0}), // second 80 MHz DC band (stop)
1435 std::make_pair(3587, dBr_u{0.0}), // second 80 MHz allocated band right (start)
1436 std::make_pair(4084, dBr_u{0.0}), // second 80 MHz allocated band right (stop)
1437 std::make_pair(4085, dBr_u{-1.538}), // Inner band right (start)
1438 std::make_pair(4097, dBr_u{-20.0}), // Inner band right (stop)
1439 std::make_pair(4098, dBr_u{-20.0}), // Flat junction band right (start)
1440 std::make_pair(4102, dBr_u{-20.0}), // Flat junction band right (stop)
1441 std::make_pair(4103, dBr_u{-20.008}), // Middle band right (start)
1442 std::make_pair(5120, dBr_u{-28.000}), // Middle band right (stop)
1443 std::make_pair(5121, dBr_u{-28.012}), // Outer band right (start)
1444 std::make_pair(6144, dBr_u{-40.0}), // Outer band right (stop)
1445 };
1446
1448 new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz fifth and sixth subchannels punctured",
1451 MHz_u{160},
1452 {MHz_u{5250}},
1453 maskSlopes,
1454 tol,
1455 prec,
1456 {false, false, false, false, true, true, false, false}),
1457 TestCase::Duration::QUICK);
1458
1459 // ============================================================================================
1460 // 11ax 160MHz @ 5GHz - last two 20 MHz subchannels punctured
1462 "Check slopes for 11ax 160MHz @ 5GHz with two last 20 MHz subchannels punctured");
1463 maskSlopes = {
1464 std::make_pair(0, dBr_u{-40.0}), // Outer band left (start)
1465 std::make_pair(1023, dBr_u{-28.012}), // Outer band left (stop)
1466 std::make_pair(1024, dBr_u{-28.000}), // Middle band left (start)
1467 std::make_pair(2041, dBr_u{-20.008}), // Middle band left (stop)
1468 std::make_pair(2042, dBr_u{-20.0}), // Flat junction band left (start)
1469 std::make_pair(2046, dBr_u{-20.0}), // Flat junction band left (stop)
1470 std::make_pair(2047, dBr_u{-20.0}), // Inner band left (start)
1471 std::make_pair(2059, dBr_u{-1.538}), // Inner band left (stop)
1472 std::make_pair(2060, dBr_u{0.0}), // first 80 MHz allocated band left (start)
1473 std::make_pair(2557, dBr_u{0.0}), // first 80 MHz allocated band left (stop)
1474 std::make_pair(2558, dBr_u{-20.0}), // first 80 MHz DC band (start)
1475 std::make_pair(2562, dBr_u{-20.0}), // first 80 MHz DC band (stop)
1476 std::make_pair(2563, dBr_u{0.0}), // first 80 MHz allocated band right (start)
1477 std::make_pair(3060, dBr_u{0.0}), // first 80 MHz allocated band right (stop)
1478 std::make_pair(3061, dBr_u{-20.0}), // gap between 80 MHz bands (start)
1479 std::make_pair(3083, dBr_u{-20.0}), // gap between 80 MHz bands (start)
1480 std::make_pair(3084, dBr_u{0.0}), // second 80 MHz allocated band left (start)
1481 std::make_pair(3581, dBr_u{0.0}), // second 80 MHz allocated band left (stop)
1482 std::make_pair(3582, dBr_u{-20.0}), // second 80 MHz DC band (start)
1483 std::make_pair(3586, dBr_u{-20.0}), // second 80 MHz DC band (stop)
1484 std::make_pair(3587, dBr_u{-10.0}), // punctured band decreasing slope (start)
1485 std::make_pair(3590, dBr_u{-20.0}), // punctured band decreasing slope (stop)
1486 std::make_pair(3591, dBr_u{-20.0}), // punctured band (start)
1487 std::make_pair(4097, dBr_u{-20.0}), // punctured band (stop)
1488 std::make_pair(4098, dBr_u{-20.0}), // Flat junction band right (start)
1489 std::make_pair(4102, dBr_u{-20.0}), // Flat junction band right (stop)
1490 std::make_pair(4103, dBr_u{-20.008}), // Middle band right (start)
1491 std::make_pair(5120, dBr_u{-28.000}), // Middle band right (stop)
1492 std::make_pair(5121, dBr_u{-28.012}), // Outer band right (start)
1493 std::make_pair(6144, dBr_u{-40.0}), // Outer band right (stop)
1494 };
1495
1497 new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz last subchannels punctured",
1500 MHz_u{160},
1501 {MHz_u{5250}},
1502 maskSlopes,
1503 tol,
1504 prec,
1505 {false, false, false, false, false, false, true, true}),
1506 TestCase::Duration::QUICK);
1507}
Test checks if Wifi spectrum values for OFDM are generated properly.
std::vector< IndexPowerPair > IndexPowerVect
typedef for a vector of pairs of sub-band index and relative power value
~WifiOfdmMaskSlopesTestCase() override=default
std::vector< bool > m_puncturedSubchannels
bitmap indicating whether a 20 MHz subchannel is punctured or not (only used for 802....
void DoSetup() override
Implementation to do any local setup required for this TestCase.
WifiPhyBand m_band
the wifi PHY band to test
std::vector< MHz_u > m_centerFreqs
the center frequency per contiguous segment to test
Ptr< SpectrumValue > m_actualSpectrum
actual spectrum value
MHz_u m_channelWidth
the total channel width to test
WifiOfdmMaskSlopesTestCase(const std::string &name, WifiStandard standard, WifiPhyBand band, MHz_u channelWidth, const std::vector< MHz_u > &centerFrequencies, const IndexPowerVect &maskRefs, dB_u tolerance, std::size_t precision, const std::vector< bool > &puncturedSubchannels=std::vector< bool >{})
Constructor.
void InterpolateAndAppendValues(IndexPowerVect &vect, IndexPowerPair start, IndexPowerPair stop) const
Interpolate PSD values for indexes between provided start and stop and append to provided vector.
void DoRun() override
Implementation to actually run this TestCase.
std::pair< uint32_t, dBr_u > IndexPowerPair
typedef for a pair of sub-band index and relative power value
IndexPowerVect m_expectedPsd
expected power values
std::size_t m_precision
precision for double calculations (in decimals)
WifiStandard m_standard
the wifi standard to test
Test suite for checking the consistency of different OFDM-based transmit masks.
Smart pointer class similar to boost::intrusive_ptr.
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
static Ptr< SpectrumValue > CreateHtOfdmTxPowerSpectralDensity(const std::vector< MHz_u > &centerFrequencies, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=dBr_u{-20}, dBr_u minOuterband=dBr_u{-28}, dBr_u lowestPoint=dBr_u{-40})
Create a transmit power spectral density corresponding to OFDM High Throughput (HT) (802....
static Ptr< SpectrumValue > CreateOfdmTxPowerSpectralDensity(MHz_u centerFrequency, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=dBr_u{-20}, dBr_u minOuterband=dBr_u{-28}, dBr_u lowestPoint=dBr_u{-40})
Create a transmit power spectral density corresponding to OFDM (802.11a/g).
static Ptr< SpectrumValue > CreateHeOfdmTxPowerSpectralDensity(MHz_u centerFrequency, MHz_u channelWidth, Watt_u txPower, MHz_u guardBandwidth, dBr_u minInnerBand=dBr_u{-20}, dBr_u minOuterband=dBr_u{-28}, dBr_u lowestPoint=dBr_u{-40}, const std::vector< bool > &puncturedSubchannels={})
Create a transmit power spectral density corresponding to OFDM High Efficiency (HE) (802....
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
bool TestDoubleIsEqual(const double x1, const double x2, const double epsilon)
Compare two double precision floating point numbers and declare them equal if they are within some ep...
Definition test.cc:36
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition test.h:500
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyBand
Identifies the PHY band.
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
STL namespace.
static WifiTransmitMaskTestSuite g_WifiTransmitMaskTestSuite