A Discrete-Event Network Simulator
API
wifi-transmit-mask-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Orange Labs
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Rediet <getachew.redieteab@orange.com>
18  */
19 
20 #include "ns3/fatal-error.h"
21 #include "ns3/log.h"
22 #include "ns3/test.h"
23 #include "ns3/wifi-phy-band.h"
24 #include "ns3/wifi-spectrum-value-helper.h"
25 #include "ns3/wifi-standards.h"
26 
27 #include <cmath>
28 
29 using namespace ns3;
30 
31 NS_LOG_COMPONENT_DEFINE("WifiTransmitMaskTest");
32 
41 {
42  public:
46  typedef std::pair<uint32_t, double> IndexPowerPair;
47 
51  typedef std::vector<IndexPowerPair> IndexPowerVect;
52 
67  WifiOfdmMaskSlopesTestCase(const std::string& name,
68  WifiStandard standard,
69  WifiPhyBand band,
70  uint16_t channelWidth,
71  const IndexPowerVect& maskRefs,
72  double tolerance,
73  std::size_t precision,
74  const std::vector<bool>& puncturedSubchannels = std::vector<bool>{});
75  ~WifiOfdmMaskSlopesTestCase() override = default;
76 
77  private:
78  void DoSetup() override;
79  void DoRun() override;
80 
90  void InterpolateAndAppendValues(IndexPowerVect& vect,
92  IndexPowerPair stop) const;
93 
96  uint16_t m_channelWidth;
97  std::vector<bool>
102  double m_tolerance;
103  std::size_t m_precision;
104 };
105 
107  const std::string& name,
108  WifiStandard standard,
109  WifiPhyBand band,
110  uint16_t channelWidth,
111  const IndexPowerVect& maskRefs,
112  double tolerance,
113  std::size_t precision,
114  const std::vector<bool>& puncturedSubchannels)
115  : TestCase(std::string("SpectrumValue ") + name),
116  m_standard{standard},
117  m_band{band},
118  m_channelWidth{channelWidth},
119  m_puncturedSubchannels{puncturedSubchannels},
120  m_actualSpectrum{},
121  m_expectedPsd{maskRefs},
122  m_tolerance{tolerance},
123  m_precision{precision}
124 {
125  NS_LOG_FUNCTION(this << name << standard << band << channelWidth << tolerance << precision
126  << puncturedSubchannels.size());
127 }
128 
129 void
131 {
132  NS_LOG_FUNCTION(this);
133  NS_ASSERT(m_expectedPsd.size() % 2 == 0); // start/stop pairs expected
134 
135  uint16_t freq = 0;
136  double outerBandMaximumRejection = 0.0;
137  switch (m_band)
138  {
139  default:
140  case WIFI_PHY_BAND_5GHZ:
141  freq = 5170 + (m_channelWidth / 2); // so as to have 5180/5190/5210/5250 for 20/40/80/160
142  outerBandMaximumRejection = -40; // in dBr
143  break;
145  freq = 2402 + (m_channelWidth / 2); // so as to have 2412/2422 for 20/40
146  outerBandMaximumRejection = (m_standard >= WIFI_STANDARD_80211n) ? -45 : -40; // in dBr
147  break;
148  case WIFI_PHY_BAND_6GHZ:
149  freq = 5945 + (m_channelWidth / 2); // so as to have 5945/5955/5975/6015 for 20/40/80/160
150  outerBandMaximumRejection = -40; // in dBr
151  break;
152  }
153 
154  double refTxPowerW = 1; // have to work in dBr when comparing though
155  switch (m_standard)
156  {
159  NS_ASSERT((m_channelWidth == 5) || (m_channelWidth == 10));
160  freq = 5860;
162  WifiSpectrumValueHelper::CreateOfdmTxPowerSpectralDensity(freq,
164  refTxPowerW,
166  -20.0,
167  -28.0,
168  outerBandMaximumRejection);
169  break;
170 
173  NS_ASSERT(m_channelWidth == 20);
175  WifiSpectrumValueHelper::CreateOfdmTxPowerSpectralDensity(freq,
177  refTxPowerW,
179  -20.0,
180  -28.0,
181  outerBandMaximumRejection);
182  break;
183 
186  NS_ASSERT(m_channelWidth == 20);
188  WifiSpectrumValueHelper::CreateOfdmTxPowerSpectralDensity(freq,
190  refTxPowerW,
192  -20.0,
193  -28.0,
194  outerBandMaximumRejection);
195  break;
196 
198  NS_ASSERT(m_channelWidth == 20 || m_channelWidth == 40);
200  WifiSpectrumValueHelper::CreateHtOfdmTxPowerSpectralDensity(freq,
202  refTxPowerW,
204  -20.0,
205  -28.0,
206  outerBandMaximumRejection);
207  break;
208 
211  NS_ASSERT(m_channelWidth == 20 || m_channelWidth == 40 || m_channelWidth == 80 ||
212  m_channelWidth == 160);
214  WifiSpectrumValueHelper::CreateHtOfdmTxPowerSpectralDensity(freq,
216  refTxPowerW,
218  -20.0,
219  -28.0,
220  outerBandMaximumRejection);
221  break;
222 
225  (m_channelWidth != 160)); // not enough space in 2.4 GHz bands
226  NS_ASSERT(m_channelWidth == 20 || m_channelWidth == 40 || m_channelWidth == 80 ||
227  m_channelWidth == 160);
229  WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity(freq,
231  refTxPowerW,
233  -20.0,
234  -28.0,
235  outerBandMaximumRejection,
237  break;
238 
239  default:
240  NS_FATAL_ERROR("Standard unknown or non-OFDM");
241  break;
242  }
243 
244  NS_LOG_INFO("Build expected PSD");
245  IndexPowerVect builtPsd;
246  for (uint32_t i = 0; i < m_expectedPsd.size(); i += 2)
247  {
249  }
250  m_expectedPsd = builtPsd;
251 }
252 
253 void
256  IndexPowerPair stop) const
257 {
258  NS_LOG_FUNCTION(start.first << start.second << stop.first << stop.second);
259  NS_ASSERT(start.first <= stop.first);
260 
261  if (start.first == stop.first) // only one point, no need to interpolate
262  {
263  NS_ASSERT(start.second == stop.second);
264  vect.push_back(start);
265  NS_LOG_LOGIC("Append (" << start.first << ", " << stop.second << ")");
266  return;
267  }
268 
269  double slope = (stop.second - start.second) / (stop.first - start.first);
270  for (uint32_t i = start.first; i <= stop.first; i++)
271  {
272  double val = start.second + slope * (i - start.first);
273  double multiplier = std::round(std::pow(10.0, static_cast<double>(m_precision)));
274  val = std::floor(val * multiplier + 0.5) / multiplier;
275  vect.emplace_back(i, val);
276  NS_LOG_LOGIC("Append (" << i << ", " << val << ")");
277  }
278 
279  NS_ASSERT(vect.back().first == stop.first &&
280  TestDoubleIsEqual(vect.back().second, stop.second, m_tolerance));
281 }
282 
283 void
285 {
286  NS_LOG_FUNCTION(this);
287  double currentPowerDbr = 0.0; // have to work in dBr so as to compare with expected slopes
288  double maxPowerW = (*m_actualSpectrum)[0];
289  for (auto&& vit = m_actualSpectrum->ConstValuesBegin();
291  ++vit)
292  {
293  maxPowerW = std::max(maxPowerW, *vit);
294  }
295 
296  NS_LOG_INFO("Compare expected PSD");
297  for (const auto& [subcarrier, expectedValue] : m_expectedPsd)
298  {
299  currentPowerDbr = 10.0 * std::log10((*m_actualSpectrum)[subcarrier] / maxPowerW);
300  NS_LOG_LOGIC("For " << subcarrier << ", expected: " << expectedValue
301  << " vs obtained: " << currentPowerDbr);
302  NS_TEST_EXPECT_MSG_EQ_TOL(currentPowerDbr,
303  expectedValue,
304  m_tolerance,
305  "Spectrum value mismatch for subcarrier " << subcarrier);
306  }
307 }
308 
316 {
317  public:
319 };
320 
322 
324  : TestSuite("wifi-transmit-mask", UNIT)
325 {
326  // LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
327  // LogComponentEnable ("WifiTransmitMaskTest", logLevel);
328  // LogComponentEnable ("WifiSpectrumValueHelper", logLevel);
329 
330  NS_LOG_INFO("Creating WifiTransmitMaskTestSuite");
331 
333  double tol = 10e-2; // in dB
334  double prec = 10; // in decimals
335 
336  // ============================================================================================
337  // 11p 5MHz
338  NS_LOG_FUNCTION("Check slopes for 11p 5MHz");
339  maskSlopes = {
340  std::make_pair(0, -40.0), // Outer band left (start)
341  std::make_pair(31, -28.375), // Outer band left (stop)
342  std::make_pair(32, -28.000), // Middle band left (start)
343  std::make_pair(60, -20.276), // Middle band left (stop)
344  std::make_pair(61, -20.0), // Flat junction band left (start)
345  std::make_pair(63, -20.0), // Flat junction band left (stop)
346  std::make_pair(64, -20.0), // Inner band left (start)
347  std::make_pair(69, -3.333), // Inner band left (stop)
348  std::make_pair(123, -3.333), // Inner band right (start)
349  std::make_pair(128, -20.0), // Inner band right (stop)
350  std::make_pair(129, -20.0), // Flat junction band right (start)
351  std::make_pair(131, -20.0), // Flat junction band right (stop)
352  std::make_pair(132, -20.276), // Middle band right (start)
353  std::make_pair(160, -28.000), // Middle band right (stop)
354  std::make_pair(161, -28.375), // Outer band right (start)
355  std::make_pair(192, -40.0), // Outer band right (stop)
356  };
357 
361  5,
362  maskSlopes,
363  tol,
364  prec),
365  TestCase::QUICK);
366 
367  // ============================================================================================
368  // 11p 10MHz
369  NS_LOG_FUNCTION("Check slopes for 11p 10MHz");
370  maskSlopes = {
371  std::make_pair(0, -40.0), // Outer band left (start)
372  std::make_pair(31, -28.375), // Outer band left (stop)
373  std::make_pair(32, -28.000), // Middle band left (start)
374  std::make_pair(60, -20.276), // Middle band left (stop)
375  std::make_pair(61, -20.0), // Flat junction band left (start)
376  std::make_pair(63, -20.0), // Flat junction band left (stop)
377  std::make_pair(64, -20.0), // Inner band left (start)
378  std::make_pair(69, -3.333), // Inner band left (stop)
379  std::make_pair(123, -3.333), // Inner band right (start)
380  std::make_pair(128, -20.0), // Inner band right (stop)
381  std::make_pair(129, -20.0), // Flat junction band right (start)
382  std::make_pair(131, -20.0), // Flat junction band right (stop)
383  std::make_pair(132, -20.276), // Middle band right (start)
384  std::make_pair(160, -28.000), // Middle band right (stop)
385  std::make_pair(161, -28.375), // Outer band right (start)
386  std::make_pair(192, -40.0), // Outer band right (stop)
387  };
388 
389  AddTestCase(new WifiOfdmMaskSlopesTestCase("11p 10MHz",
392  10,
393  maskSlopes,
394  tol,
395  prec),
396  TestCase::QUICK);
397 
398  // ============================================================================================
399  // 11a
400  NS_LOG_FUNCTION("Check slopes for 11a");
401  maskSlopes = {
402  std::make_pair(0, -40.0), // Outer band left (start)
403  std::make_pair(31, -28.375), // Outer band left (stop)
404  std::make_pair(32, -28.000), // Middle band left (start)
405  std::make_pair(60, -20.276), // Middle band left (stop)
406  std::make_pair(61, -20.0), // Flat junction band left (start)
407  std::make_pair(63, -20.0), // Flat junction band left (stop)
408  std::make_pair(64, -20.0), // Inner band left (start)
409  std::make_pair(69, -3.333), // Inner band left (stop)
410  std::make_pair(123, -3.333), // Inner band right (start)
411  std::make_pair(128, -20.0), // Inner band right (stop)
412  std::make_pair(129, -20.0), // Flat junction band right (start)
413  std::make_pair(131, -20.0), // Flat junction band right (stop)
414  std::make_pair(132, -20.276), // Middle band right (start)
415  std::make_pair(160, -28.000), // Middle band right (stop)
416  std::make_pair(161, -28.375), // Outer band right (start)
417  std::make_pair(192, -40.0), // Outer band right (stop)
418  };
419 
423  20,
424  maskSlopes,
425  tol,
426  prec),
427  TestCase::QUICK);
428 
429  // ============================================================================================
430  // 11g
431  NS_LOG_FUNCTION("Check slopes for 11g");
432  // same slopes as 11a
436  20,
437  maskSlopes,
438  tol,
439  prec),
440  TestCase::QUICK);
441 
442  // ============================================================================================
443  // 11n 20MHz @ 2.4GHz
444  NS_LOG_FUNCTION("Check slopes for 11n 20MHz @ 2.4GHz");
445  maskSlopes = {
446  std::make_pair(0, -45.000), // Outer band left (start)
447  std::make_pair(31, -28.531), // Outer band left (stop)
448  std::make_pair(32, -28.000), // Middle band left (start)
449  std::make_pair(60, -20.276), // Middle band left (stop)
450  std::make_pair(61, -20.0), // Flat junction band left (start)
451  std::make_pair(61, -20.0), // Flat junction band left (stop)
452  std::make_pair(62, -20.0), // Inner band left (start)
453  std::make_pair(67, -3.333), // Inner band left (stop)
454  std::make_pair(125, -3.333), // Inner band right (start)
455  std::make_pair(130, -20.0), // Inner band right (stop)
456  std::make_pair(131, -20.0), // Flat junction band right (start)
457  std::make_pair(131, -20.0), // Flat junction band right (stop)
458  std::make_pair(132, -20.276), // Middle band right (start)
459  std::make_pair(160, -28.000), // Middle band right (stop)
460  std::make_pair(161, -28.531), // Outer band right (start)
461  std::make_pair(192, -45.000), // Outer band right (stop)
462  };
463 
464  AddTestCase(new WifiOfdmMaskSlopesTestCase("11n_2.4GHz 20MHz",
467  20,
468  maskSlopes,
469  tol,
470  prec),
471  TestCase::QUICK);
472 
473  // ============================================================================================
474  // 11n 20MHz @ 5GHz
475  NS_LOG_FUNCTION("Check slopes for 11n 20MHz @ 5GHz");
476  maskSlopes = {
477  std::make_pair(0, -40.0), // Outer band left (start)
478  std::make_pair(31, -28.375), // Outer band left (stop)
479  std::make_pair(32, -28.000), // Middle band left (start)
480  std::make_pair(60, -20.276), // Middle band left (stop)
481  std::make_pair(61, -20.0), // Flat junction band left (start)
482  std::make_pair(61, -20.0), // Flat junction band left (stop)
483  std::make_pair(62, -20.0), // Inner band left (start)
484  std::make_pair(67, -3.333), // Inner band left (stop)
485  std::make_pair(125, -3.333), // Inner band right (start)
486  std::make_pair(130, -20.0), // Inner band right (stop)
487  std::make_pair(131, -20.0), // Flat junction band right (start)
488  std::make_pair(131, -20.0), // Flat junction band right (stop)
489  std::make_pair(132, -20.276), // Middle band right (start)
490  std::make_pair(160, -28.000), // Middle band right (stop)
491  std::make_pair(161, -28.375), // Outer band right (start)
492  std::make_pair(192, -40.0), // Outer band right (stop)
493  };
494 
495  AddTestCase(new WifiOfdmMaskSlopesTestCase("11n_5GHz 20MHz",
498  20,
499  maskSlopes,
500  tol,
501  prec),
502  TestCase::QUICK);
503 
504  // ============================================================================================
505  // 11n 40MHz @ 2.4GHz
506  NS_LOG_FUNCTION("Check slopes for 11n 40MHz @ 2.4GHz");
507  maskSlopes = {
508  std::make_pair(0, -45.000), // Outer band left (start)
509  std::make_pair(63, -28.266), // Outer band left (stop)
510  std::make_pair(64, -28.000), // Middle band left (start)
511  std::make_pair(124, -20.131), // Middle band left (stop)
512  std::make_pair(125, -20.0), // Flat junction band left (start)
513  std::make_pair(125, -20.0), // Flat junction band left (stop)
514  std::make_pair(126, -20.0), // Inner band left (start)
515  std::make_pair(131, -3.333), // Inner band left (stop)
516  std::make_pair(253, -3.333), // Inner band right (start)
517  std::make_pair(258, -20.0), // Inner band right (stop)
518  std::make_pair(259, -20.0), // Flat junction band right (start)
519  std::make_pair(259, -20.0), // Flat junction band right (stop)
520  std::make_pair(260, -20.131), // Middle band right (start)
521  std::make_pair(320, -28.000), // Middle band right (stop)
522  std::make_pair(321, -28.266), // Outer band right (start)
523  std::make_pair(384, -45.000), // Outer band right (stop)
524  };
525 
526  AddTestCase(new WifiOfdmMaskSlopesTestCase("11n_2.4GHz 40MHz",
529  40,
530  maskSlopes,
531  tol,
532  prec),
533  TestCase::QUICK);
534 
535  // ============================================================================================
536  // 11n 20MHz @ 5GHz
537  NS_LOG_FUNCTION("Check slopes for 11n 40MHz @ 5GHz");
538  maskSlopes = {
539  std::make_pair(0, -40.0), // Outer band left (start)
540  std::make_pair(63, -28.188), // Outer band left (stop)
541  std::make_pair(64, -28.000), // Middle band left (start)
542  std::make_pair(124, -20.131), // Middle band left (stop)
543  std::make_pair(125, -20.0), // Flat junction band left (start)
544  std::make_pair(125, -20.0), // Flat junction band left (stop)
545  std::make_pair(126, -20.0), // Inner band left (start)
546  std::make_pair(131, -3.333), // Inner band left (stop)
547  std::make_pair(253, -3.333), // Inner band right (start)
548  std::make_pair(258, -20.0), // Inner band right (stop)
549  std::make_pair(259, -20.0), // Flat junction band right (start)
550  std::make_pair(259, -20.0), // Flat junction band right (stop)
551  std::make_pair(260, -20.131), // Middle band right (start)
552  std::make_pair(320, -28.000), // Middle band right (stop)
553  std::make_pair(321, -28.188), // Outer band right (start)
554  std::make_pair(384, -40.0), // Outer band right (stop)
555  };
556 
557  AddTestCase(new WifiOfdmMaskSlopesTestCase("11n_5GHz 40MHz",
560  40,
561  maskSlopes,
562  tol,
563  prec),
564  TestCase::QUICK);
565 
566  // ============================================================================================
567  // 11ac 20MHz
568  NS_LOG_FUNCTION("Check slopes for 11ac 20MHz");
569  maskSlopes = {
570  std::make_pair(0, -40.0), // Outer band left (start)
571  std::make_pair(31, -28.375), // Outer band left (stop)
572  std::make_pair(32, -28.000), // Middle band left (start)
573  std::make_pair(60, -20.276), // Middle band left (stop)
574  std::make_pair(61, -20.0), // Flat junction band left (start)
575  std::make_pair(61, -20.0), // Flat junction band left (stop)
576  std::make_pair(62, -20.0), // Inner band left (start)
577  std::make_pair(67, -3.333), // Inner band left (stop)
578  std::make_pair(125, -3.333), // Inner band right (start)
579  std::make_pair(130, -20.0), // Inner band right (stop)
580  std::make_pair(131, -20.0), // Flat junction band right (start)
581  std::make_pair(131, -20.0), // Flat junction band right (stop)
582  std::make_pair(132, -20.276), // Middle band right (start)
583  std::make_pair(160, -28.000), // Middle band right (stop)
584  std::make_pair(161, -28.375), // Outer band right (start)
585  std::make_pair(192, -40.0), // Outer band right (stop)
586  };
587 
588  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ac 20MHz",
591  20,
592  maskSlopes,
593  tol,
594  prec),
595  TestCase::QUICK);
596 
597  // ============================================================================================
598  // 11ac 20MHz
599  NS_LOG_FUNCTION("Check slopes for 11ac 40MHz");
600  maskSlopes = {
601  std::make_pair(0, -40.0), // Outer band left (start)
602  std::make_pair(63, -28.188), // Outer band left (stop)
603  std::make_pair(64, -28.000), // Middle band left (start)
604  std::make_pair(124, -20.131), // Middle band left (stop)
605  std::make_pair(125, -20.0), // Flat junction band left (start)
606  std::make_pair(125, -20.0), // Flat junction band left (stop)
607  std::make_pair(126, -20.0), // Inner band left (start)
608  std::make_pair(131, -3.333), // Inner band left (stop)
609  std::make_pair(253, -3.333), // Inner band right (start)
610  std::make_pair(258, -20.0), // Inner band right (stop)
611  std::make_pair(259, -20.0), // Flat junction band right (start)
612  std::make_pair(259, -20.0), // Flat junction band right (stop)
613  std::make_pair(260, -20.131), // Middle band right (start)
614  std::make_pair(320, -28.000), // Middle band right (stop)
615  std::make_pair(321, -28.188), // Outer band right (start)
616  std::make_pair(384, -40.0), // Outer band right (stop)
617  };
618 
619  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ac 40MHz",
622  40,
623  maskSlopes,
624  tol,
625  prec),
626  TestCase::QUICK);
627 
628  // ============================================================================================
629  // 11ac 80MHz
630  NS_LOG_FUNCTION("Check slopes for 11ac 80MHz");
631  maskSlopes = {
632  std::make_pair(0, -40.0), // Outer band left (start)
633  std::make_pair(127, -28.094), // Outer band left (stop)
634  std::make_pair(128, -28.000), // Middle band left (start)
635  std::make_pair(252, -20.064), // Middle band left (stop)
636  std::make_pair(253, -20.0), // Flat junction band left (start)
637  std::make_pair(253, -20.0), // Flat junction band left (stop)
638  std::make_pair(254, -20.0), // Inner band left (start)
639  std::make_pair(259, -3.333), // Inner band left (stop)
640  std::make_pair(509, -3.333), // Inner band right (start)
641  std::make_pair(514, -20.0), // Inner band right (stop)
642  std::make_pair(515, -20.0), // Flat junction band right (start)
643  std::make_pair(515, -20.0), // Flat junction band right (stop)
644  std::make_pair(516, -20.064), // Middle band right (start)
645  std::make_pair(640, -28.000), // Middle band right (stop)
646  std::make_pair(641, -28.094), // Outer band right (start)
647  std::make_pair(768, -40.0), // Outer band right (stop)
648  };
649 
650  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ac 80MHz",
653  80,
654  maskSlopes,
655  tol,
656  prec),
657  TestCase::QUICK);
658 
659  // ============================================================================================
660  // 11ac 20MHz
661  NS_LOG_FUNCTION("Check slopes for 11ac 160MHz");
662  maskSlopes = {
663  std::make_pair(0, -40.0), // Outer band left (start)
664  std::make_pair(255, -28.047), // Outer band left (stop)
665  std::make_pair(256, -28.000), // Middle band left (start)
666  std::make_pair(508, -20.032), // Middle band left (stop)
667  std::make_pair(509, -20.0), // Flat junction band left (start)
668  std::make_pair(509, -20.0), // Flat junction band left (stop)
669  std::make_pair(510, -20.0), // Inner band left (start)
670  std::make_pair(515, -3.333), // Inner band left (stop)
671  std::make_pair(1021, -3.333), // Inner band right (start)
672  std::make_pair(1026, -20.0), // Inner band right (stop)
673  std::make_pair(1027, -20.0), // Flat junction band right (start)
674  std::make_pair(1027, -20.0), // Flat junction band right (stop)
675  std::make_pair(1028, -20.032), // Middle band right (start)
676  std::make_pair(1280, -28.000), // Middle band right (stop)
677  std::make_pair(1281, -28.047), // Outer band right (start)
678  std::make_pair(1536, -40.0), // Outer band right (stop)
679  };
680 
681  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ac 160MHz",
684  160,
685  maskSlopes,
686  tol,
687  prec),
688  TestCase::QUICK);
689 
690  // ============================================================================================
691  // 11ax 20MHz @ 2.4GHz
692  NS_LOG_FUNCTION("Check slopes for 11ax 20MHz @ 2.4GHz");
693  maskSlopes = {
694  std::make_pair(0, -45.000), // Outer band left (start)
695  std::make_pair(127, -28.133), // Outer band left (stop)
696  std::make_pair(128, -28.000), // Middle band left (start)
697  std::make_pair(252, -20.064), // Middle band left (stop)
698  std::make_pair(253, -20.0), // Flat junction band left (start)
699  std::make_pair(255, -20.0), // Flat junction band left (stop)
700  std::make_pair(256, -20.0), // Inner band left (start)
701  std::make_pair(261, -3.333), // Inner band left (stop)
702  std::make_pair(262, 0.0), // allocated band left (start)
703  std::make_pair(382, 0.0), // allocated band left (stop)
704  std::make_pair(383, -20.0), // DC band (start)
705  std::make_pair(385, -20.0), // DC band (stop)
706  std::make_pair(386, 0.0), // allocated band right (start)
707  std::make_pair(506, 0.0), // allocated band right (stop)
708  std::make_pair(507, -3.333), // Inner band right (start)
709  std::make_pair(512, -20.0), // Inner band right (stop)
710  std::make_pair(513, -20.0), // Flat junction band right (start)
711  std::make_pair(515, -20.0), // Flat junction band right (stop)
712  std::make_pair(516, -20.064), // Middle band right (start)
713  std::make_pair(640, -28.000), // Middle band right (stop)
714  std::make_pair(641, -28.133), // Outer band right (start)
715  std::make_pair(768, -45.000), // Outer band right (stop)
716  };
717 
718  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_2.4GHz 20MHz",
721  20,
722  maskSlopes,
723  tol,
724  prec),
725  TestCase::QUICK);
726 
727  // ============================================================================================
728  // 11ax 20MHz @ 5GHz
729  NS_LOG_FUNCTION("Check slopes for 11ax 20MHz @ 5GHz");
730  maskSlopes = {
731  std::make_pair(0, -40.0), // Outer band left (start)
732  std::make_pair(127, -28.094), // Outer band left (stop)
733  std::make_pair(128, -28.000), // Middle band left (start)
734  std::make_pair(252, -20.064), // Middle band left (stop)
735  std::make_pair(253, -20.0), // Flat junction band left (start)
736  std::make_pair(255, -20.0), // Flat junction band left (stop)
737  std::make_pair(256, -20.0), // Inner band left (start)
738  std::make_pair(261, -3.333), // Inner band left (stop)
739  std::make_pair(262, 0.0), // allocated band left (start)
740  std::make_pair(382, 0.0), // allocated band left (stop)
741  std::make_pair(383, -20.0), // DC band (start)
742  std::make_pair(385, -20.0), // DC band (stop)
743  std::make_pair(386, 0.0), // allocated band right (start)
744  std::make_pair(506, 0.0), // allocated band right (stop)
745  std::make_pair(507, -3.333), // Inner band right (start)
746  std::make_pair(512, -20.0), // Inner band right (stop)
747  std::make_pair(513, -20.0), // Flat junction band right (start)
748  std::make_pair(515, -20.0), // Flat junction band right (stop)
749  std::make_pair(516, -20.064), // Middle band right (start)
750  std::make_pair(640, -28.000), // Middle band right (stop)
751  std::make_pair(641, -28.094), // Outer band right (start)
752  std::make_pair(768, -40.0), // Outer band right (stop)
753  };
754 
755  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 20MHz",
758  20,
759  maskSlopes,
760  tol,
761  prec),
762  TestCase::QUICK);
763 
764  // ============================================================================================
765  // 11ax 40MHz @ 2.4GHz
766  NS_LOG_FUNCTION("Check slopes for 11ax 40MHz @ 2.4GHz");
767  maskSlopes = {
768  std::make_pair(0, -45.000), // Outer band left (start)
769  std::make_pair(255, -28.066), // Outer band left (stop)
770  std::make_pair(256, -28.000), // Middle band left (start)
771  std::make_pair(505, -20.032), // Middle band left (stop)
772  std::make_pair(506, -20.0), // Flat junction band left (start)
773  std::make_pair(510, -20.0), // Flat junction band left (stop)
774  std::make_pair(511, -20.0), // Inner band left (start)
775  std::make_pair(523, -1.538), // Inner band left (stop)
776  std::make_pair(524, 0.0), // allocated band left (start)
777  std::make_pair(765, 0.0), // allocated band left (stop)
778  std::make_pair(766, -20.0), // DC band (start)
779  std::make_pair(770, -20.0), // DC band (stop)
780  std::make_pair(771, 0.0), // allocated band right (start)
781  std::make_pair(1012, 0.0), // allocated band right (stop)
782  std::make_pair(1013, -1.538), // Inner band right (start)
783  std::make_pair(1025, -20.0), // Inner band right (stop)
784  std::make_pair(1026, -20.0), // Flat junction band right (start)
785  std::make_pair(1030, -20.0), // Flat junction band right (stop)
786  std::make_pair(1031, -20.032), // Middle band right (start)
787  std::make_pair(1280, -28.000), // Middle band right (stop)
788  std::make_pair(1281, -28.066), // Outer band right (start)
789  std::make_pair(1536, -45.000), // Outer band right (stop)
790  };
791 
792  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_2.4GHz 40MHz",
795  40,
796  maskSlopes,
797  tol,
798  prec),
799  TestCase::QUICK);
800 
801  // ============================================================================================
802  // 11ax 40MHz @ 5GHz
803  NS_LOG_FUNCTION("Check slopes for 11ax 40MHz @ 5GHz");
804  maskSlopes = {
805  std::make_pair(0, -40.0), // Outer band left (start)
806  std::make_pair(255, -28.047), // Outer band left (stop)
807  std::make_pair(256, -28.000), // Middle band left (start)
808  std::make_pair(505, -20.032), // Middle band left (stop)
809  std::make_pair(506, -20.0), // Flat junction band left (start)
810  std::make_pair(510, -20.0), // Flat junction band left (stop)
811  std::make_pair(511, -20.0), // Inner band left (start)
812  std::make_pair(523, -1.538), // Inner band left (stop)
813  std::make_pair(524, 0.0), // allocated band left (start)
814  std::make_pair(765, 0.0), // allocated band left (stop)
815  std::make_pair(766, -20.0), // DC band (start)
816  std::make_pair(770, -20.0), // DC band (stop)
817  std::make_pair(771, 0.0), // allocated band right (start)
818  std::make_pair(1012, 0.0), // allocated band right (stop)
819  std::make_pair(1013, -1.538), // Inner band right (start)
820  std::make_pair(1025, -20.0), // Inner band right (stop)
821  std::make_pair(1026, -20.0), // Flat junction band right (start)
822  std::make_pair(1030, -20.0), // Flat junction band right (stop)
823  std::make_pair(1031, -20.032), // Middle band right (start)
824  std::make_pair(1280, -28.000), // Middle band right (stop)
825  std::make_pair(1281, -28.047), // Outer band right (start)
826  std::make_pair(1536, -40.0), // Outer band right (stop)
827  };
828 
829  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 40MHz",
832  40,
833  maskSlopes,
834  tol,
835  prec),
836  TestCase::QUICK);
837 
838  // ============================================================================================
839  // 11ax 80MHz @ 2.4GHz
840  NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 2.4GHz");
841  maskSlopes = {
842  std::make_pair(0, -45.000), // Outer band left (start)
843  std::make_pair(511, -28.033), // Outer band left (stop)
844  std::make_pair(512, -28.000), // Middle band left (start)
845  std::make_pair(1017, -20.016), // Middle band left (stop)
846  std::make_pair(1018, -20.0), // Flat junction band left (start)
847  std::make_pair(1022, -20.0), // Flat junction band left (stop)
848  std::make_pair(1023, -20.0), // Inner band left (start)
849  std::make_pair(1035, -1.538), // Inner band left (stop)
850  std::make_pair(1036, 0.0), // allocated band left (start)
851  std::make_pair(1533, 0.0), // allocated band left (stop)
852  std::make_pair(1534, -20.0), // DC band (start)
853  std::make_pair(1538, -20.0), // DC band (stop)
854  std::make_pair(1539, 0.0), // allocated band right (start)
855  std::make_pair(2036, 0.0), // allocated band right (stop)
856  std::make_pair(2037, -1.538), // Inner band right (start)
857  std::make_pair(2049, -20.0), // Inner band right (stop)
858  std::make_pair(2050, -20.0), // Flat junction band right (start)
859  std::make_pair(2054, -20.0), // Flat junction band right (stop)
860  std::make_pair(2055, -20.016), // Middle band right (start)
861  std::make_pair(2560, -28.000), // Middle band right (stop)
862  std::make_pair(2561, -28.033), // Outer band right (start)
863  std::make_pair(3072, -45.000), // Outer band right (stop)
864  };
865 
866  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_2.4GHz 80MHz",
869  80,
870  maskSlopes,
871  tol,
872  prec),
873  TestCase::QUICK);
874 
875  // ============================================================================================
876  // 11ax 80MHz @ 5GHz
877  NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz");
878  maskSlopes = {
879  std::make_pair(0, -40.0), // Outer band left (start)
880  std::make_pair(511, -28.023), // Outer band left (stop)
881  std::make_pair(512, -28.000), // Middle band left (start)
882  std::make_pair(1017, -20.016), // Middle band left (stop)
883  std::make_pair(1018, -20.0), // Flat junction band left (start)
884  std::make_pair(1022, -20.0), // Flat junction band left (stop)
885  std::make_pair(1023, -20.0), // Inner band left (start)
886  std::make_pair(1035, -1.538), // Inner band left (stop)
887  std::make_pair(1036, 0.0), // allocated band left (start)
888  std::make_pair(1533, 0.0), // allocated band left (stop)
889  std::make_pair(1534, -20.0), // DC band (start)
890  std::make_pair(1538, -20.0), // DC band (stop)
891  std::make_pair(1539, 0.0), // allocated band right (start)
892  std::make_pair(2036, 0.0), // allocated band right (stop)
893  std::make_pair(2037, -1.538), // Inner band right (start)
894  std::make_pair(2049, -20.0), // Inner band right (stop)
895  std::make_pair(2050, -20.0), // Flat junction band right (start)
896  std::make_pair(2054, -20.0), // Flat junction band right (stop)
897  std::make_pair(2055, -20.016), // Middle band right (start)
898  std::make_pair(2560, -28.000), // Middle band right (stop)
899  std::make_pair(2561, -28.023), // Outer band right (start)
900  std::make_pair(3072, -40.0), // Outer band right (stop)
901  };
902 
903  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz",
906  80,
907  maskSlopes,
908  tol,
909  prec),
910  TestCase::QUICK);
911 
912  // ============================================================================================
913  // 11ax 160MHz @ 2.4GHz -> not enough space so skip
914 
915  // ============================================================================================
916  // 11ax 160MHz @ 5GHz
917  NS_LOG_FUNCTION("Check slopes for 11ax 160MHz @ 5GHz");
918  maskSlopes = {
919  std::make_pair(0, -40.0), // Outer band left (start)
920  std::make_pair(1023, -28.012), // Outer band left (stop)
921  std::make_pair(1024, -28.000), // Middle band left (start)
922  std::make_pair(2041, -20.008), // Middle band left (stop)
923  std::make_pair(2042, -20.0), // Flat junction band left (start)
924  std::make_pair(2046, -20.0), // Flat junction band left (stop)
925  std::make_pair(2047, -20.0), // Inner band left (start)
926  std::make_pair(2059, -1.538), // Inner band left (stop)
927  std::make_pair(2060, 0.0), // first 80 MHz allocated band left (start)
928  std::make_pair(2557, 0.0), // first 80 MHz allocated band left (stop)
929  std::make_pair(2558, -20.0), // first 80 MHz DC band (start)
930  std::make_pair(2562, -20.0), // first 80 MHz DC band (stop)
931  std::make_pair(2563, 0.0), // first 80 MHz allocated band right (start)
932  std::make_pair(3060, 0.0), // first 80 MHz allocated band right (stop)
933  std::make_pair(3061, -20.0), // gap between 80 MHz bands (start)
934  std::make_pair(3083, -20.0), // gap between 80 MHz bands (start)
935  std::make_pair(3084, 0.0), // second 80 MHz allocated band left (start)
936  std::make_pair(3581, 0.0), // second 80 MHz allocated band left (stop)
937  std::make_pair(3582, -20.0), // second 80 MHz DC band (start)
938  std::make_pair(3586, -20.0), // second 80 MHz DC band (stop)
939  std::make_pair(3587, 0.0), // second 80 MHz allocated band right (start)
940  std::make_pair(4084, 0.0), // second 80 MHz allocated band right (stop)
941  std::make_pair(4085, -1.538), // Inner band right (start)
942  std::make_pair(4097, -20.0), // Inner band right (stop)
943  std::make_pair(4098, -20.0), // Flat junction band right (start)
944  std::make_pair(4102, -20.0), // Flat junction band right (stop)
945  std::make_pair(4103, -20.008), // Middle band right (start)
946  std::make_pair(5120, -28.000), // Middle band right (stop)
947  std::make_pair(5121, -28.012), // Outer band right (start)
948  std::make_pair(6144, -40.0), // Outer band right (stop)
949  };
950 
951  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz",
954  160,
955  maskSlopes,
956  tol,
957  prec),
958  TestCase::QUICK);
959 
960  // ============================================================================================
961  // 11ax 80MHz @ 5GHz - first 20 MHz subchannel punctured
962  NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz with first 20 MHz subchannel punctured");
963  maskSlopes = {
964  std::make_pair(0, -40.0), // Outer band left (start)
965  std::make_pair(511, -28.023), // Outer band left (stop)
966  std::make_pair(512, -28.000), // Middle band left (start)
967  std::make_pair(1017, -20.016), // Middle band left (stop)
968  std::make_pair(1018, -20.0), // Flat junction band left (start)
969  std::make_pair(1022, -20.0), // Flat junction band left (stop)
970  std::make_pair(1023, -20.0), // punctured band (start)
971  std::make_pair(1272, -20.0), // punctured band (stop)
972  std::make_pair(1273, -20.0), // punctured band increasing slope (start)
973  std::make_pair(1279, 0.0), // punctured band increasing slope (stop)
974  std::make_pair(1280, 0.0), // allocated band left (start)
975  std::make_pair(1533, 0.0), // allocated band left (stop)
976  std::make_pair(1534, -20.0), // DC band (start)
977  std::make_pair(1538, -20.0), // DC band (stop)
978  std::make_pair(1539, 0.0), // allocated band right (start)
979  std::make_pair(2036, 0.0), // allocated band right (stop)
980  std::make_pair(2037, -1.538), // Inner band right (start)
981  std::make_pair(2049, -20.0), // Inner band right (stop)
982  std::make_pair(2050, -20.0), // Flat junction band right (start)
983  std::make_pair(2054, -20.0), // Flat junction band right (stop)
984  std::make_pair(2055, -20.016), // Middle band right (start)
985  std::make_pair(2560, -28.000), // Middle band right (stop)
986  std::make_pair(2561, -28.023), // Outer band right (start)
987  std::make_pair(3072, -40.0), // Outer band right (stop)
988  };
989 
990  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz first subchannel punctured",
993  80,
994  maskSlopes,
995  tol,
996  prec,
997  {true, false, false, false}),
998  TestCase::QUICK);
999 
1000  // ============================================================================================
1001  // 11ax 80MHz @ 5GHz - second 20 MHz subchannel punctured
1002  NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz with second 20 MHz subchannel punctured");
1003  maskSlopes = {
1004  std::make_pair(0, -40.0), // Outer band left (start)
1005  std::make_pair(511, -28.023), // Outer band left (stop)
1006  std::make_pair(512, -28.000), // Middle band left (start)
1007  std::make_pair(1017, -20.016), // Middle band left (stop)
1008  std::make_pair(1018, -20.0), // Flat junction band left (start)
1009  std::make_pair(1022, -20.0), // Flat junction band left (stop)
1010  std::make_pair(1023, -20.0), // Inner band left (start)
1011  std::make_pair(1035, -1.538), // Inner band left (stop)
1012  std::make_pair(1036, 0.0), // allocated band left (start)
1013  std::make_pair(1279, 0.0), // allocated band left (stop)
1014  std::make_pair(1280, 0.0), // punctured band decreasing slope (start)
1015  std::make_pair(1286, -20.0), // punctured band decreasing slope (stop)
1016  std::make_pair(1287, -20.0), // punctured band (start)
1017  std::make_pair(1528, -20.0), // punctured band (stop)
1018  std::make_pair(1529, -20.0), // punctured band increasing slope (start)
1019  std::make_pair(1533, -6.667), // punctured band increasing slope (stop)
1020  std::make_pair(1534, -20.0), // DC band (start)
1021  std::make_pair(1538, -20.0), // DC band (stop)
1022  std::make_pair(1539, 0.0), // allocated band right (start)
1023  std::make_pair(2036, 0.0), // allocated band right (stop)
1024  std::make_pair(2037, -1.538), // Inner band right (start)
1025  std::make_pair(2049, -20.0), // Inner band right (stop)
1026  std::make_pair(2050, -20.0), // Flat junction band right (start)
1027  std::make_pair(2054, -20.0), // Flat junction band right (stop)
1028  std::make_pair(2055, -20.016), // Middle band right (start)
1029  std::make_pair(2560, -28.000), // Middle band right (stop)
1030  std::make_pair(2561, -28.023), // Outer band right (start)
1031  std::make_pair(3072, -40.0), // Outer band right (stop)
1032  };
1033 
1034  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz second subchannel punctured",
1037  80,
1038  maskSlopes,
1039  tol,
1040  prec,
1041  {false, true, false, false}),
1042  TestCase::QUICK);
1043 
1044  // ============================================================================================
1045  // 11ax 80MHz @ 5GHz - third 20 MHz subchannel punctured
1046  NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz with third 20 MHz subchannel punctured");
1047  maskSlopes = {
1048  std::make_pair(0, -40.0), // Outer band left (start)
1049  std::make_pair(511, -28.023), // Outer band left (stop)
1050  std::make_pair(512, -28.000), // Middle band left (start)
1051  std::make_pair(1017, -20.016), // Middle band left (stop)
1052  std::make_pair(1018, -20.0), // Flat junction band left (start)
1053  std::make_pair(1022, -20.0), // Flat junction band left (stop)
1054  std::make_pair(1023, -20.0), // Inner band left (start)
1055  std::make_pair(1035, -1.538), // Inner band left (stop)
1056  std::make_pair(1036, 0.0), // allocated band left (start)
1057  std::make_pair(1533, 0.0), // allocated band left (stop)
1058  std::make_pair(1534, -20.0), // DC band (start)
1059  std::make_pair(1535, -20.0), // DC band (stop)
1060  std::make_pair(1539, -10.0), // punctured band decreasing slope (start)
1061  std::make_pair(1542, -20.0), // punctured band decreasing slope (stop)
1062  std::make_pair(1543, -20.0), // punctured band (start)
1063  std::make_pair(1784, -20.0), // punctured band (stop)
1064  std::make_pair(1785, -20.0), // punctured band increasing slope (start)
1065  std::make_pair(1791, 0.0), // punctured band increasing slope (stop)
1066  std::make_pair(1792, 0.0), // allocated band right (start)
1067  std::make_pair(2036, 0.0), // allocated band right (stop)
1068  std::make_pair(2037, -1.538), // Inner band right (start)
1069  std::make_pair(2049, -20.0), // Inner band right (stop)
1070  std::make_pair(2050, -20.0), // Flat junction band right (start)
1071  std::make_pair(2054, -20.0), // Flat junction band right (stop)
1072  std::make_pair(2055, -20.016), // Middle band right (start)
1073  std::make_pair(2560, -28.000), // Middle band right (stop)
1074  std::make_pair(2561, -28.023), // Outer band right (start)
1075  std::make_pair(3072, -40.0), // Outer band right (stop)
1076  };
1077 
1078  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz third subchannel punctured",
1081  80,
1082  maskSlopes,
1083  tol,
1084  prec,
1085  {false, false, true, false}),
1086  TestCase::QUICK);
1087 
1088  // ============================================================================================
1089  // 11ax 80MHz @ 5GHz - last 20 MHz subchannel punctured
1090  NS_LOG_FUNCTION("Check slopes for 11ax 80MHz @ 5GHz with last 20 MHz subchannel punctured");
1091  maskSlopes = {
1092  std::make_pair(0, -40.0), // Outer band left (start)
1093  std::make_pair(511, -28.023), // Outer band left (stop)
1094  std::make_pair(512, -28.000), // Middle band left (start)
1095  std::make_pair(1017, -20.016), // Middle band left (stop)
1096  std::make_pair(1018, -20.0), // Flat junction band left (start)
1097  std::make_pair(1022, -20.0), // Flat junction band left (stop)
1098  std::make_pair(1023, -20.0), // Inner band left (start)
1099  std::make_pair(1035, -1.538), // Inner band left (stop)
1100  std::make_pair(1036, 0.0), // allocated band left (start)
1101  std::make_pair(1533, 0.0), // allocated band left (stop)
1102  std::make_pair(1534, -20.0), // DC band (start)
1103  std::make_pair(1538, -20.0), // DC band (stop)
1104  std::make_pair(1539, 0.0), // allocated band right (start)
1105  std::make_pair(1791, 0.0), // allocated band right (stop)
1106  std::make_pair(1792, 0.0), // punctured band decreasing slope (start)
1107  std::make_pair(1798, -20.0), // punctured band decreasing slope (stop)
1108  std::make_pair(1799, -20.0), // punctured band (start)
1109  std::make_pair(2049, -20.0), // punctured band (stop)
1110  std::make_pair(2050, -20.0), // Flat junction band right (start)
1111  std::make_pair(2054, -20.0), // Flat junction band right (stop)
1112  std::make_pair(2055, -20.016), // Middle band right (start)
1113  std::make_pair(2560, -28.000), // Middle band right (stop)
1114  std::make_pair(2561, -28.023), // Outer band right (start)
1115  std::make_pair(3072, -40.0), // Outer band right (stop)
1116  };
1117 
1118  AddTestCase(new WifiOfdmMaskSlopesTestCase("11ax_5GHz 80MHz last subchannel punctured",
1121  80,
1122  maskSlopes,
1123  tol,
1124  prec,
1125  {false, false, false, true}),
1126  TestCase::QUICK);
1127 
1128  // ============================================================================================
1129  // 11ax 160MHz @ 5GHz - first two 20 MHz subchannels punctured
1131  "Check slopes for 11ax 160MHz @ 5GHz with two first 20 MHz subchannels punctured");
1132  maskSlopes = {
1133  std::make_pair(0, -40.0), // Outer band left (start)
1134  std::make_pair(1023, -28.012), // Outer band left (stop)
1135  std::make_pair(1024, -28.000), // Middle band left (start)
1136  std::make_pair(2041, -20.008), // Middle band left (stop)
1137  std::make_pair(2042, -20.0), // Flat junction band left (start)
1138  std::make_pair(2046, -20.0), // Flat junction band left (stop)
1139  std::make_pair(2047, -20.0), // punctured band (start)
1140  std::make_pair(2552, -20.0), // punctured band (stop)
1141  std::make_pair(2553, -20.0), // punctured band increasing slope (start)
1142  std::make_pair(2557, -6.66667), // punctured band increasing slope (stop)
1143  std::make_pair(2558, -20.0), // first 80 MHz DC band (start)
1144  std::make_pair(2562, -20.0), // first 80 MHz DC band (stop)
1145  std::make_pair(2563, 0.0), // first 80 MHz allocated band right (start)
1146  std::make_pair(3060, 0.0), // first 80 MHz allocated band right (stop)
1147  std::make_pair(3061, -20.0), // gap between 80 MHz bands (start)
1148  std::make_pair(3083, -20.0), // gap between 80 MHz bands (start)
1149  std::make_pair(3084, 0.0), // second 80 MHz allocated band left (start)
1150  std::make_pair(3581, 0.0), // second 80 MHz allocated band left (stop)
1151  std::make_pair(3582, -20.0), // second 80 MHz DC band (start)
1152  std::make_pair(3586, -20.0), // second 80 MHz DC band (stop)
1153  std::make_pair(3587, 0.0), // second 80 MHz allocated band right (start)
1154  std::make_pair(4084, 0.0), // second 80 MHz allocated band right (stop)
1155  std::make_pair(4085, -1.538), // Inner band right (start)
1156  std::make_pair(4097, -20.0), // Inner band right (stop)
1157  std::make_pair(4098, -20.0), // Flat junction band right (start)
1158  std::make_pair(4102, -20.0), // Flat junction band right (stop)
1159  std::make_pair(4103, -20.008), // Middle band right (start)
1160  std::make_pair(5120, -28.000), // Middle band right (stop)
1161  std::make_pair(5121, -28.012), // Outer band right (start)
1162  std::make_pair(6144, -40.0), // Outer band right (stop)
1163  };
1164 
1165  AddTestCase(
1166  new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz first subchannels punctured",
1169  160,
1170  maskSlopes,
1171  tol,
1172  prec,
1173  {true, true, false, false, false, false, false, false}),
1174  TestCase::QUICK);
1175 
1176  // ============================================================================================
1177  // 11ax 160MHz @ 5GHz - third and fourth 20 MHz subchannels punctured
1179  "Check slopes for 11ax 160MHz @ 5GHz with third and fourth 20 MHz subchannels punctured");
1180  maskSlopes = {
1181  std::make_pair(0, -40.0), // Outer band left (start)
1182  std::make_pair(1023, -28.012), // Outer band left (stop)
1183  std::make_pair(1024, -28.000), // Middle band left (start)
1184  std::make_pair(2041, -20.008), // Middle band left (stop)
1185  std::make_pair(2042, -20.0), // Flat junction band left (start)
1186  std::make_pair(2046, -20.0), // Flat junction band left (stop)
1187  std::make_pair(2047, -20.0), // Inner band left (start)
1188  std::make_pair(2059, -1.538), // Inner band left (stop)
1189  std::make_pair(2060, 0.0), // first 80 MHz allocated band left (start)
1190  std::make_pair(2557, 0.0), // first 80 MHz allocated band left (stop)
1191  std::make_pair(2558, -20.0), // first 80 MHz DC band (start)
1192  std::make_pair(2562, -20.0), // first 80 MHz DC band (stop)
1193  std::make_pair(2563, -10.0), // punctured band decreasing slope (start)
1194  std::make_pair(2566, -20.0), // punctured band decreasing slope (stop)
1195  std::make_pair(2567, -20.0), // punctured band (start)
1196  std::make_pair(3060, -20.0), // punctured band (stop)
1197  std::make_pair(3061, -20.0), // gap between 80 MHz bands (start)
1198  std::make_pair(3083, -20.0), // gap between 80 MHz bands (start)
1199  std::make_pair(3084, 0.0), // second 80 MHz allocated band left (start)
1200  std::make_pair(3581, 0.0), // second 80 MHz allocated band left (stop)
1201  std::make_pair(3582, -20.0), // second 80 MHz DC band (start)
1202  std::make_pair(3586, -20.0), // second 80 MHz DC band (stop)
1203  std::make_pair(3587, 0.0), // second 80 MHz allocated band right (start)
1204  std::make_pair(4084, 0.0), // second 80 MHz allocated band right (stop)
1205  std::make_pair(4085, -1.538), // Inner band right (start)
1206  std::make_pair(4097, -20.0), // Inner band right (stop)
1207  std::make_pair(4098, -20.0), // Flat junction band right (start)
1208  std::make_pair(4102, -20.0), // Flat junction band right (stop)
1209  std::make_pair(4103, -20.008), // Middle band right (start)
1210  std::make_pair(5120, -28.000), // Middle band right (stop)
1211  std::make_pair(5121, -28.012), // Outer band right (start)
1212  std::make_pair(6144, -40.0), // Outer band right (stop)
1213  };
1214 
1215  AddTestCase(
1216  new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz third and fourth subchannels punctured",
1219  160,
1220  maskSlopes,
1221  tol,
1222  prec,
1223  {false, false, true, true, false, false, false, false}),
1224  TestCase::QUICK);
1225 
1226  // ============================================================================================
1227  // 11ax 160MHz @ 5GHz - fifth and sixth 20 MHz subchannels punctured
1229  "Check slopes for 11ax 160MHz @ 5GHz with fifth and sixth 20 MHz subchannels punctured");
1230  maskSlopes = {
1231  std::make_pair(0, -40.0), // Outer band left (start)
1232  std::make_pair(1023, -28.012), // Outer band left (stop)
1233  std::make_pair(1024, -28.000), // Middle band left (start)
1234  std::make_pair(2041, -20.008), // Middle band left (stop)
1235  std::make_pair(2042, -20.0), // Flat junction band left (start)
1236  std::make_pair(2046, -20.0), // Flat junction band left (stop)
1237  std::make_pair(2047, -20.0), // Inner band left (start)
1238  std::make_pair(2059, -1.538), // Inner band left (stop)
1239  std::make_pair(2060, 0.0), // first 80 MHz allocated band left (start)
1240  std::make_pair(2557, 0.0), // first 80 MHz allocated band left (stop)
1241  std::make_pair(2558, -20.0), // first 80 MHz DC band (start)
1242  std::make_pair(2562, -20.0), // first 80 MHz DC band (stop)
1243  std::make_pair(2563, 0.0), // first 80 MHz allocated band right (start)
1244  std::make_pair(3060, 0.0), // first 80 MHz allocated band right (stop)
1245  std::make_pair(3061, -20.0), // gap between 80 MHz bands (start)
1246  std::make_pair(3083, -20.0), // gap between 80 MHz bands (start)
1247  std::make_pair(3084, -20.0), // punctured band (start)
1248  std::make_pair(3576, -20.0), // punctured band (stop)
1249  std::make_pair(3577, -20.0), // punctured band increasing slope (start)
1250  std::make_pair(3581, -6.667), // punctured band increasing slope (stop)
1251  std::make_pair(3582, -20.0), // second 80 MHz DC band (start)
1252  std::make_pair(3586, -20.0), // second 80 MHz DC band (stop)
1253  std::make_pair(3587, 0.0), // second 80 MHz allocated band right (start)
1254  std::make_pair(4084, 0.0), // second 80 MHz allocated band right (stop)
1255  std::make_pair(4085, -1.538), // Inner band right (start)
1256  std::make_pair(4097, -20.0), // Inner band right (stop)
1257  std::make_pair(4098, -20.0), // Flat junction band right (start)
1258  std::make_pair(4102, -20.0), // Flat junction band right (stop)
1259  std::make_pair(4103, -20.008), // Middle band right (start)
1260  std::make_pair(5120, -28.000), // Middle band right (stop)
1261  std::make_pair(5121, -28.012), // Outer band right (start)
1262  std::make_pair(6144, -40.0), // Outer band right (stop)
1263  };
1264 
1265  AddTestCase(
1266  new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz fifth and sixth subchannels punctured",
1269  160,
1270  maskSlopes,
1271  tol,
1272  prec,
1273  {false, false, false, false, true, true, false, false}),
1274  TestCase::QUICK);
1275 
1276  // ============================================================================================
1277  // 11ax 160MHz @ 5GHz - last two 20 MHz subchannels punctured
1279  "Check slopes for 11ax 160MHz @ 5GHz with two last 20 MHz subchannels punctured");
1280  maskSlopes = {
1281  std::make_pair(0, -40.0), // Outer band left (start)
1282  std::make_pair(1023, -28.012), // Outer band left (stop)
1283  std::make_pair(1024, -28.000), // Middle band left (start)
1284  std::make_pair(2041, -20.008), // Middle band left (stop)
1285  std::make_pair(2042, -20.0), // Flat junction band left (start)
1286  std::make_pair(2046, -20.0), // Flat junction band left (stop)
1287  std::make_pair(2047, -20.0), // Inner band left (start)
1288  std::make_pair(2059, -1.538), // Inner band left (stop)
1289  std::make_pair(2060, 0.0), // first 80 MHz allocated band left (start)
1290  std::make_pair(2557, 0.0), // first 80 MHz allocated band left (stop)
1291  std::make_pair(2558, -20.0), // first 80 MHz DC band (start)
1292  std::make_pair(2562, -20.0), // first 80 MHz DC band (stop)
1293  std::make_pair(2563, 0.0), // first 80 MHz allocated band right (start)
1294  std::make_pair(3060, 0.0), // first 80 MHz allocated band right (stop)
1295  std::make_pair(3061, -20.0), // gap between 80 MHz bands (start)
1296  std::make_pair(3083, -20.0), // gap between 80 MHz bands (start)
1297  std::make_pair(3084, 0.0), // second 80 MHz allocated band left (start)
1298  std::make_pair(3581, 0.0), // second 80 MHz allocated band left (stop)
1299  std::make_pair(3582, -20.0), // second 80 MHz DC band (start)
1300  std::make_pair(3586, -20.0), // second 80 MHz DC band (stop)
1301  std::make_pair(3587, -10.0), // punctured band decreasing slope (start)
1302  std::make_pair(3590, -20.0), // punctured band decreasing slope (stop)
1303  std::make_pair(3591, -20.0), // punctured band (start)
1304  std::make_pair(4097, -20.0), // punctured band (stop)
1305  std::make_pair(4098, -20.0), // Flat junction band right (start)
1306  std::make_pair(4102, -20.0), // Flat junction band right (stop)
1307  std::make_pair(4103, -20.008), // Middle band right (start)
1308  std::make_pair(5120, -28.000), // Middle band right (stop)
1309  std::make_pair(5121, -28.012), // Outer band right (start)
1310  std::make_pair(6144, -40.0), // Outer band right (stop)
1311  };
1312 
1313  AddTestCase(
1314  new WifiOfdmMaskSlopesTestCase("11ax_5GHz 160MHz last subchannels punctured",
1317  160,
1318  maskSlopes,
1319  tol,
1320  prec,
1321  {false, false, false, false, false, false, true, true}),
1322  TestCase::QUICK);
1323 }
#define max(a, b)
Definition: 80211b.c:42
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 (dBr)
~WifiOfdmMaskSlopesTestCase() override=default
double m_tolerance
tolerance (in dB)
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.
std::pair< uint32_t, double > IndexPowerPair
typedef for a pair of sub-band index and relative power value (dBr)
uint16_t m_channelWidth
the channel width in MHz to use for the test
WifiOfdmMaskSlopesTestCase(const std::string &name, WifiStandard standard, WifiPhyBand band, uint16_t channelWidth, const IndexPowerVect &maskRefs, double tolerance, std::size_t precision, const std::vector< bool > &puncturedSubchannels=std::vector< bool >{})
Constructor.
WifiPhyBand m_band
the wifi PHY band to use for the test
Ptr< SpectrumValue > m_actualSpectrum
actual spectrum value
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.
IndexPowerVect m_expectedPsd
expected power values
std::size_t m_precision
precision for double calculations (in decimals)
WifiStandard m_standard
the wifi standard to use for the test
Test suite for checking the consistency of different OFDM-based transmit masks.
Values::const_iterator ConstValuesBegin() const
Values::const_iterator ConstValuesEnd() const
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:275
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:45
#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:510
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
@ 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.
Definition: wifi-phy-band.h:39
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static WifiTransmitMaskTestSuite g_WifiTransmitMaskTestSuite