A Discrete-Event Network Simulator
API
wifi-ru-allocation-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023 Universita' degli Studi di Napoli Federico II
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: Stefano Avallone <stavallo@unina.it>
18  */
19 
20 #include "ns3/test.h"
21 #include "ns3/wifi-phy-operating-channel.h"
22 
23 using namespace ns3;
24 
25 NS_LOG_COMPONENT_DEFINE("WifiRuAllocationTest");
26 
34 {
35  public:
40  ~Wifi20MHzIndicesCoveringRuTest() override = default;
41 
52  void RunOne(uint8_t primary20,
53  HeRu::RuSpec ru,
54  uint16_t width,
55  const std::set<uint8_t>& indices);
56 
57  private:
58  void DoRun() override;
59 
61 };
62 
64  : TestCase("Check computation of the indices of the 20 MHz channels covering an RU")
65 {
66 }
67 
68 void
70  HeRu::RuSpec ru,
71  uint16_t width,
72  const std::set<uint8_t>& indices)
73 {
74  auto printToStr = [](const std::set<uint8_t>& s) {
75  std::stringstream ss;
76  ss << "{";
77  for (const auto& index : s)
78  {
79  ss << +index << " ";
80  }
81  ss << "}";
82  return ss.str();
83  };
84 
85  m_channel.SetPrimary20Index(primary20);
86 
87  auto actualIndices = m_channel.Get20MHzIndicesCoveringRu(ru, width);
88  NS_TEST_ASSERT_MSG_EQ((actualIndices == indices),
89  true,
90  "Channel width=" << m_channel.GetWidth() << " MHz, PPDU width=" << width
91  << " MHz, p20Index=" << +primary20 << " , RU=" << ru
92  << ". Expected indices " << printToStr(indices)
93  << " differs from actual " << printToStr(actualIndices));
94 }
95 
96 void
98 {
99  /******************
100  * 20 MHz channel *
101  ******************/
103 
104  /* 20 MHz PPDU */
105  {
106  const uint16_t width = 20;
107  const uint8_t p20Index = 0;
108 
109  // All the 9 26-tone RUs are covered by the unique 20 MHz channel
110  for (std::size_t idx = 1; idx <= 9; idx++)
111  {
112  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {p20Index});
113  }
114  // All the 4 52-tone RUs are covered by the unique 20 MHz channel
115  for (std::size_t idx = 1; idx <= 4; idx++)
116  {
117  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {p20Index});
118  }
119  // Both 106-tone RUs are covered by the unique 20 MHz channel
120  for (std::size_t idx = 1; idx <= 2; idx++)
121  {
122  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {p20Index});
123  }
124  // The 242-tone RU is covered by the unique 20 MHz channel
125  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, true), width, {p20Index});
126  }
127 
128  /******************
129  * 40 MHz channel *
130  ******************/
132 
133  /* 20 MHz PPDU */
134  for (uint8_t p20Index = 0; p20Index < 2; p20Index++)
135  {
136  const uint16_t width = 20;
137 
138  // All the 9 26-tone RUs are covered by the primary 20 MHz channel
139  for (std::size_t idx = 1; idx <= 9; idx++)
140  {
141  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {p20Index});
142  }
143  // All the 4 52-tone RUs are covered by the primary 20 MHz channel
144  for (std::size_t idx = 1; idx <= 4; idx++)
145  {
146  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {p20Index});
147  }
148  // Both 106-tone RUs are covered by the primary 20 MHz channel
149  for (std::size_t idx = 1; idx <= 2; idx++)
150  {
151  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {p20Index});
152  }
153  // The 242-tone RU is covered by the primary 20 MHz channel
154  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, true), width, {p20Index});
155  }
156 
157  /* 40 MHz PPDU */
158  for (uint8_t p20Index = 0; p20Index < 2; p20Index++)
159  {
160  const uint16_t width = 40;
161 
162  // The first 9 26-tone RUs are covered by the first 20 MHz channel
163  for (std::size_t idx = 1; idx <= 9; idx++)
164  {
165  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {0});
166  }
167  // The second 9 26-tone RUs are covered by the second 20 MHz channel
168  for (std::size_t idx = 10; idx <= 18; idx++)
169  {
170  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {1});
171  }
172  // The first 4 52-tone RUs are covered by the first 20 MHz channel
173  for (std::size_t idx = 1; idx <= 4; idx++)
174  {
175  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {0});
176  }
177  // The second 4 52-tone RUs are covered by the second 20 MHz channel
178  for (std::size_t idx = 5; idx <= 8; idx++)
179  {
180  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {1});
181  }
182  // The first 2 106-tone RUs are covered by the first 20 MHz channel
183  for (std::size_t idx = 1; idx <= 2; idx++)
184  {
185  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {0});
186  }
187  // The second 2 106-tone RUs are covered by the second 20 MHz channel
188  for (std::size_t idx = 3; idx <= 4; idx++)
189  {
190  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {1});
191  }
192  // The first 242-tone RU is covered by the first 20 MHz channel
193  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, true), width, {0});
194  // The second 242-tone RU is covered by the second 20 MHz channel
195  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 2, true), width, {1});
196  // The 484-tone RU is covered by both 20 MHz channels
197  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_484_TONE, 1, true), width, {0, 1});
198  }
199 
200  /******************
201  * 80 MHz channel *
202  ******************/
204 
205  /* 20 MHz PPDU */
206  for (uint8_t p20Index = 0; p20Index < 4; p20Index++)
207  {
208  const uint16_t width = 20;
209 
210  // All the 9 26-tone RUs are covered by the primary 20 MHz channel
211  for (std::size_t idx = 1; idx <= 9; idx++)
212  {
213  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {p20Index});
214  }
215  // All the 4 52-tone RUs are covered by the primary 20 MHz channel
216  for (std::size_t idx = 1; idx <= 4; idx++)
217  {
218  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {p20Index});
219  }
220  // Both 106-tone RUs are covered by the primary 20 MHz channel
221  for (std::size_t idx = 1; idx <= 2; idx++)
222  {
223  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {p20Index});
224  }
225  // The 242-tone RU is covered by the primary 20 MHz channel
226  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, true), width, {p20Index});
227  }
228 
229  /* 40 MHz PPDU */
230  for (uint8_t p20Index = 0; p20Index < 4; p20Index++)
231  {
232  const uint16_t width = 40;
233  // PPDU is transmitted on P40, which may be in the lower or higher 40 MHz
234  const uint8_t p40Index = p20Index / 2;
235  // RUs can be allocated in one (or both) of the two 20 MHz channels in P40
236  const uint8_t ch20Index0 = p40Index * 2;
237  const uint8_t ch20Index1 = p40Index * 2 + 1;
238 
239  // The first 9 26-tone RUs are in the lower 20 MHz of the PPDU bandwidth
240  for (std::size_t idx = 1; idx <= 9; idx++)
241  {
242  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {ch20Index0});
243  }
244  // The second 9 26-tone RUs are in the higher 20 MHz of the PPDU bandwidth
245  for (std::size_t idx = 10; idx <= 18; idx++)
246  {
247  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {ch20Index1});
248  }
249  // The first 4 52-tone RUs are in the lower 20 MHz of the PPDU bandwidth
250  for (std::size_t idx = 1; idx <= 4; idx++)
251  {
252  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {ch20Index0});
253  }
254  // The second 4 52-tone RUs are in the higher 20 MHz of the PPDU bandwidth
255  for (std::size_t idx = 5; idx <= 8; idx++)
256  {
257  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {ch20Index1});
258  }
259  // The first 2 106-tone RUs are in the lower 20 MHz of the PPDU bandwidth
260  for (std::size_t idx = 1; idx <= 2; idx++)
261  {
262  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {ch20Index0});
263  }
264  // The second 2 106-tone RUs are in the higher 20 MHz of the PPDU bandwidth
265  for (std::size_t idx = 3; idx <= 4; idx++)
266  {
267  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {ch20Index1});
268  }
269  // The first 242-tone RU is in the lower 20 MHz of the PPDU bandwidth
270  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, true), width, {ch20Index0});
271  // The second 242-tone RU is in the higher 20 MHz of the PPDU bandwidth
272  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 2, true), width, {ch20Index1});
273  // The 484-tone RU is covered by both 20 MHz channels
274  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_484_TONE, 1, true), width, {ch20Index0, ch20Index1});
275  }
276 
277  /* 80 MHz PPDU */
278  for (uint8_t p20Index = 0; p20Index < 4; p20Index++)
279  {
280  const uint16_t width = 80;
281 
282  // The first 9 26-tone RUs are in the first 20 MHz channel
283  for (std::size_t idx = 1; idx <= 9; idx++)
284  {
285  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {0});
286  }
287  // The second 9 26-tone RUs are in the second 20 MHz channel
288  for (std::size_t idx = 10; idx <= 18; idx++)
289  {
290  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {1});
291  }
292  // The center 26-tone RU is covered by the central 20 MHz channels
293  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, 19, true), width, {1, 2});
294  // The following 9 26-tone RUs are in the third 20 MHz channel
295  for (std::size_t idx = 20; idx <= 28; idx++)
296  {
297  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {2});
298  }
299  // The last 9 26-tone RUs are in the fourth 20 MHz channel
300  for (std::size_t idx = 29; idx <= 37; idx++)
301  {
302  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {3});
303  }
304  // The first 4 52-tone RUs are in the first 20 MHz channel
305  for (std::size_t idx = 1; idx <= 4; idx++)
306  {
307  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {0});
308  }
309  // The second 4 52-tone RUs are in the second 20 MHz channel
310  for (std::size_t idx = 5; idx <= 8; idx++)
311  {
312  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {1});
313  }
314  // The third 4 52-tone RUs are in the third 20 MHz channel
315  for (std::size_t idx = 9; idx <= 12; idx++)
316  {
317  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {2});
318  }
319  // The fourth 4 52-tone RUs are in the fourth 20 MHz channel
320  for (std::size_t idx = 13; idx <= 16; idx++)
321  {
322  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {3});
323  }
324  // The first 2 106-tone RUs are in the first 20 MHz channel
325  for (std::size_t idx = 1; idx <= 2; idx++)
326  {
327  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {0});
328  }
329  // The second 2 106-tone RUs are in the second 20 MHz channel
330  for (std::size_t idx = 3; idx <= 4; idx++)
331  {
332  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {1});
333  }
334  // The third 2 106-tone RUs are in the third 20 MHz channel
335  for (std::size_t idx = 5; idx <= 6; idx++)
336  {
337  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {2});
338  }
339  // The fourth 2 106-tone RUs are in the fourth 20 MHz channel
340  for (std::size_t idx = 7; idx <= 8; idx++)
341  {
342  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {3});
343  }
344  // The first 242-tone RU is in the first 20 MHz channel
345  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, true), width, {0});
346  // The second 242-tone RU is in the second 20 MHz channel
347  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 2, true), width, {1});
348  // The third 242-tone RU is in the third 20 MHz channel
349  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 3, true), width, {2});
350  // The fourth 242-tone RU is in the fourth 20 MHz channel
351  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 4, true), width, {3});
352  // The first 484-tone RU is covered by the first two 20 MHz channels
353  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_484_TONE, 1, true), width, {0, 1});
354  // The second 484-tone RU is covered by the last two 20 MHz channels
355  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_484_TONE, 2, true), width, {2, 3});
356  // The 996-tone RU is covered by all the 20 MHz channels
357  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_996_TONE, 1, true), width, {0, 1, 2, 3});
358  }
359 
360  /******************
361  * 160 MHz channel *
362  ******************/
364 
365  /* 20 MHz PPDU */
366  for (uint8_t p20Index = 0; p20Index < 8; p20Index++)
367  {
368  const uint16_t width = 20;
369 
370  // All the 9 26-tone RUs are covered by the primary 20 MHz channel
371  for (std::size_t idx = 1; idx <= 9; idx++)
372  {
373  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {p20Index});
374  }
375  // All the 4 52-tone RUs are covered by the primary 20 MHz channel
376  for (std::size_t idx = 1; idx <= 4; idx++)
377  {
378  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {p20Index});
379  }
380  // Both 106-tone RUs are covered by the primary 20 MHz channel
381  for (std::size_t idx = 1; idx <= 2; idx++)
382  {
383  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {p20Index});
384  }
385  // The 242-tone RU is covered by the primary 20 MHz channel
386  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, true), width, {p20Index});
387  }
388 
389  /* 40 MHz PPDU */
390  for (uint8_t p20Index = 0; p20Index < 8; p20Index++)
391  {
392  const uint16_t width = 40;
393  // PPDU is transmitted on P40, which is one of the four 40 MHz channels
394  const uint8_t p40Index = p20Index / 2;
395  // RUs can be allocated in one (or both) of the two 20 MHz channels in P40
396  const uint8_t ch20Index0 = p40Index * 2;
397  const uint8_t ch20Index1 = p40Index * 2 + 1;
398 
399  // The first 9 26-tone RUs are in the lower 20 MHz of the PPDU bandwidth
400  for (std::size_t idx = 1; idx <= 9; idx++)
401  {
402  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {ch20Index0});
403  }
404  // The second 9 26-tone RUs are in the higher 20 MHz of the PPDU bandwidth
405  for (std::size_t idx = 10; idx <= 18; idx++)
406  {
407  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {ch20Index1});
408  }
409  // The first 4 52-tone RUs are in the lower 20 MHz of the PPDU bandwidth
410  for (std::size_t idx = 1; idx <= 4; idx++)
411  {
412  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {ch20Index0});
413  }
414  // The second 4 52-tone RUs are in the higher 20 MHz of the PPDU bandwidth
415  for (std::size_t idx = 5; idx <= 8; idx++)
416  {
417  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {ch20Index1});
418  }
419  // The first 2 106-tone RUs are in the lower 20 MHz of the PPDU bandwidth
420  for (std::size_t idx = 1; idx <= 2; idx++)
421  {
422  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {ch20Index0});
423  }
424  // The second 2 106-tone RUs are in the higher 20 MHz of the PPDU bandwidth
425  for (std::size_t idx = 3; idx <= 4; idx++)
426  {
427  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {ch20Index1});
428  }
429  // The first 242-tone RU is in the lower 20 MHz of the PPDU bandwidth
430  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, true), width, {ch20Index0});
431  // The second 242-tone RU is in the higher 20 MHz of the PPDU bandwidth
432  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 2, true), width, {ch20Index1});
433  // The 484-tone RU is covered by both 20 MHz channels
434  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_484_TONE, 1, true), width, {ch20Index0, ch20Index1});
435  }
436 
437  /* 80 MHz PPDU */
438  for (uint8_t p20Index = 0; p20Index < 8; p20Index++)
439  {
440  const uint16_t width = 80;
441  // PPDU is transmitted on P80, which is one of the two 80 MHz channels
442  const uint8_t p80Index = p20Index / 4;
443  // RUs can be allocated in one (or more) of the four 20 MHz channels in P80
444  const uint8_t ch20Index0 = p80Index * 4;
445  const uint8_t ch20Index1 = p80Index * 4 + 1;
446  const uint8_t ch20Index2 = p80Index * 4 + 2;
447  const uint8_t ch20Index3 = p80Index * 4 + 3;
448 
449  // The first 9 26-tone RUs are in the first 20 MHz channel
450  for (std::size_t idx = 1; idx <= 9; idx++)
451  {
452  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {ch20Index0});
453  }
454  // The second 9 26-tone RUs are in the second 20 MHz channel
455  for (std::size_t idx = 10; idx <= 18; idx++)
456  {
457  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {ch20Index1});
458  }
459  // The center 26-tone RU is covered by the central 20 MHz channels
460  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, 19, true), width, {ch20Index1, ch20Index2});
461  // The following 9 26-tone RUs are in the third 20 MHz channel
462  for (std::size_t idx = 20; idx <= 28; idx++)
463  {
464  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {ch20Index2});
465  }
466  // The last 9 26-tone RUs are in the fourth 20 MHz channel
467  for (std::size_t idx = 29; idx <= 37; idx++)
468  {
469  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_26_TONE, idx, true), width, {ch20Index3});
470  }
471  // The first 4 52-tone RUs are in the first 20 MHz channel
472  for (std::size_t idx = 1; idx <= 4; idx++)
473  {
474  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {ch20Index0});
475  }
476  // The second 4 52-tone RUs are in the second 20 MHz channel
477  for (std::size_t idx = 5; idx <= 8; idx++)
478  {
479  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {ch20Index1});
480  }
481  // The third 4 52-tone RUs are in the third 20 MHz channel
482  for (std::size_t idx = 9; idx <= 12; idx++)
483  {
484  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {ch20Index2});
485  }
486  // The fourth 4 52-tone RUs are in the fourth 20 MHz channel
487  for (std::size_t idx = 13; idx <= 16; idx++)
488  {
489  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_52_TONE, idx, true), width, {ch20Index3});
490  }
491  // The first 2 106-tone RUs are in the first 20 MHz channel
492  for (std::size_t idx = 1; idx <= 2; idx++)
493  {
494  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {ch20Index0});
495  }
496  // The second 2 106-tone RUs are in the second 20 MHz channel
497  for (std::size_t idx = 3; idx <= 4; idx++)
498  {
499  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {ch20Index1});
500  }
501  // The third 2 106-tone RUs are in the third 20 MHz channel
502  for (std::size_t idx = 5; idx <= 6; idx++)
503  {
504  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {ch20Index2});
505  }
506  // The fourth 2 106-tone RUs are in the fourth 20 MHz channel
507  for (std::size_t idx = 7; idx <= 8; idx++)
508  {
509  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_106_TONE, idx, true), width, {ch20Index3});
510  }
511  // The first 242-tone RU is in the first 20 MHz channel
512  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, true), width, {ch20Index0});
513  // The second 242-tone RU is in the second 20 MHz channel
514  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 2, true), width, {ch20Index1});
515  // The third 242-tone RU is in the third 20 MHz channel
516  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 3, true), width, {ch20Index2});
517  // The fourth 242-tone RU is in the fourth 20 MHz channel
518  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 4, true), width, {ch20Index3});
519  // The first 484-tone RU is covered by the first two 20 MHz channels
520  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_484_TONE, 1, true), width, {ch20Index0, ch20Index1});
521  // The second 484-tone RU is covered by the last two 20 MHz channels
522  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_484_TONE, 2, true), width, {ch20Index2, ch20Index3});
523  // The 996-tone RU is covered by all the 20 MHz channels
524  RunOne(p20Index,
525  HeRu::RuSpec(HeRu::RU_996_TONE, 1, true),
526  width,
527  {ch20Index0, ch20Index1, ch20Index2, ch20Index3});
528  }
529 
530  /* 160 MHz PPDU */
531  for (uint8_t p20Index = 0; p20Index < 8; p20Index++)
532  {
533  const uint16_t width = 160;
534 
535  for (auto primary80MHz : {true, false})
536  {
537  // RUs can be allocated in one (or more) of the four 20 MHz channels in P80/S80
538  // (depending on the primary80MHz flag)
539  const uint8_t p80Index = (primary80MHz == (p20Index < 4)) ? 0 : 1;
540  const uint8_t ch20Index0 = p80Index * 4;
541  const uint8_t ch20Index1 = p80Index * 4 + 1;
542  const uint8_t ch20Index2 = p80Index * 4 + 2;
543  const uint8_t ch20Index3 = p80Index * 4 + 3;
544 
545  // The first 9 26-tone RUs are in the first 20 MHz channel
546  for (std::size_t idx = 1; idx <= 9; idx++)
547  {
548  RunOne(p20Index,
549  HeRu::RuSpec(HeRu::RU_26_TONE, idx, primary80MHz),
550  width,
551  {ch20Index0});
552  }
553  // The second 9 26-tone RUs are in the second 20 MHz channel
554  for (std::size_t idx = 10; idx <= 18; idx++)
555  {
556  RunOne(p20Index,
557  HeRu::RuSpec(HeRu::RU_26_TONE, idx, primary80MHz),
558  width,
559  {ch20Index1});
560  }
561  // The center 26-tone RU is covered by the central 20 MHz channels
562  RunOne(p20Index,
563  HeRu::RuSpec(HeRu::RU_26_TONE, 19, primary80MHz),
564  width,
565  {ch20Index1, ch20Index2});
566  // The following 9 26-tone RUs are in the third 20 MHz channel
567  for (std::size_t idx = 20; idx <= 28; idx++)
568  {
569  RunOne(p20Index,
570  HeRu::RuSpec(HeRu::RU_26_TONE, idx, primary80MHz),
571  width,
572  {ch20Index2});
573  }
574  // The last 9 26-tone RUs are in the fourth 20 MHz channel
575  for (std::size_t idx = 29; idx <= 37; idx++)
576  {
577  RunOne(p20Index,
578  HeRu::RuSpec(HeRu::RU_26_TONE, idx, primary80MHz),
579  width,
580  {ch20Index3});
581  }
582  // The first 4 52-tone RUs are in the first 20 MHz channel
583  for (std::size_t idx = 1; idx <= 4; idx++)
584  {
585  RunOne(p20Index,
586  HeRu::RuSpec(HeRu::RU_52_TONE, idx, primary80MHz),
587  width,
588  {ch20Index0});
589  }
590  // The second 4 52-tone RUs are in the second 20 MHz channel
591  for (std::size_t idx = 5; idx <= 8; idx++)
592  {
593  RunOne(p20Index,
594  HeRu::RuSpec(HeRu::RU_52_TONE, idx, primary80MHz),
595  width,
596  {ch20Index1});
597  }
598  // The third 4 52-tone RUs are in the third 20 MHz channel
599  for (std::size_t idx = 9; idx <= 12; idx++)
600  {
601  RunOne(p20Index,
602  HeRu::RuSpec(HeRu::RU_52_TONE, idx, primary80MHz),
603  width,
604  {ch20Index2});
605  }
606  // The fourth 4 52-tone RUs are in the fourth 20 MHz channel
607  for (std::size_t idx = 13; idx <= 16; idx++)
608  {
609  RunOne(p20Index,
610  HeRu::RuSpec(HeRu::RU_52_TONE, idx, primary80MHz),
611  width,
612  {ch20Index3});
613  }
614  // The first 2 106-tone RUs are in the first 20 MHz channel
615  for (std::size_t idx = 1; idx <= 2; idx++)
616  {
617  RunOne(p20Index,
618  HeRu::RuSpec(HeRu::RU_106_TONE, idx, primary80MHz),
619  width,
620  {ch20Index0});
621  }
622  // The second 2 106-tone RUs are in the second 20 MHz channel
623  for (std::size_t idx = 3; idx <= 4; idx++)
624  {
625  RunOne(p20Index,
626  HeRu::RuSpec(HeRu::RU_106_TONE, idx, primary80MHz),
627  width,
628  {ch20Index1});
629  }
630  // The third 2 106-tone RUs are in the third 20 MHz channel
631  for (std::size_t idx = 5; idx <= 6; idx++)
632  {
633  RunOne(p20Index,
634  HeRu::RuSpec(HeRu::RU_106_TONE, idx, primary80MHz),
635  width,
636  {ch20Index2});
637  }
638  // The fourth 2 106-tone RUs are in the fourth 20 MHz channel
639  for (std::size_t idx = 7; idx <= 8; idx++)
640  {
641  RunOne(p20Index,
642  HeRu::RuSpec(HeRu::RU_106_TONE, idx, primary80MHz),
643  width,
644  {ch20Index3});
645  }
646  // The first 242-tone RU is in the first 20 MHz channel
647  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 1, primary80MHz), width, {ch20Index0});
648  // The second 242-tone RU is in the second 20 MHz channel
649  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 2, primary80MHz), width, {ch20Index1});
650  // The third 242-tone RU is in the third 20 MHz channel
651  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 3, primary80MHz), width, {ch20Index2});
652  // The fourth 242-tone RU is in the fourth 20 MHz channel
653  RunOne(p20Index, HeRu::RuSpec(HeRu::RU_242_TONE, 4, primary80MHz), width, {ch20Index3});
654  // The first 484-tone RU is covered by the first two 20 MHz channels
655  RunOne(p20Index,
656  HeRu::RuSpec(HeRu::RU_484_TONE, 1, primary80MHz),
657  width,
658  {ch20Index0, ch20Index1});
659  // The second 484-tone RU is covered by the last two 20 MHz channels
660  RunOne(p20Index,
661  HeRu::RuSpec(HeRu::RU_484_TONE, 2, primary80MHz),
662  width,
663  {ch20Index2, ch20Index3});
664  // The 996-tone RU is covered by all the 20 MHz channels
665  RunOne(p20Index,
666  HeRu::RuSpec(HeRu::RU_996_TONE, 1, primary80MHz),
667  width,
668  {ch20Index0, ch20Index1, ch20Index2, ch20Index3});
669  }
670  // The 2x996-tone RU is covered by all the eight 20 MHz channels
671  RunOne(p20Index,
672  HeRu::RuSpec(HeRu::RU_2x996_TONE, 1, true),
673  width,
674  {0, 1, 2, 3, 4, 5, 6, 7});
675  }
676 }
677 
685 {
686  public:
688 };
689 
691  : TestSuite("wifi-ru-allocation", UNIT)
692 {
693  AddTestCase(new Wifi20MHzIndicesCoveringRuTest(), TestCase::QUICK);
694 }
695 
Test the WifiPhyOperatingChannel::Get20MHzIndicesCoveringRu() method.
void RunOne(uint8_t primary20, HeRu::RuSpec ru, uint16_t width, const std::set< uint8_t > &indices)
Check that the indices of the 20 MHz channels covering the given RU as computed by WifiPhyOperatingCh...
WifiPhyOperatingChannel m_channel
operating channel
~Wifi20MHzIndicesCoveringRuTest() override=default
void DoRun() override
Implementation to actually run this TestCase.
wifi primary channels test suite
RU Specification.
Definition: he-ru.h:66
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
Class that keeps track of all information about the current PHY operating channel.
void SetPrimary20Index(uint8_t index)
Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel with the lowest center...
void SetDefault(uint16_t width, WifiStandard standard, WifiPhyBand band)
Set the default channel of the given width and for the given standard and band.
uint16_t GetWidth() const
Return the width of the whole operating channel (in MHz).
std::set< uint8_t > Get20MHzIndicesCoveringRu(HeRu::RuSpec ru, uint16_t width) const
Get the channel indices of the minimum subset of 20 MHz channels containing the given RU.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
@ WIFI_STANDARD_80211ax
@ 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 WifiRuAllocationTestSuite g_wifiRuAllocationTestSuite
the test suite