A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
23using namespace ns3;
24
25NS_LOG_COMPONENT_DEFINE("WifiRuAllocationTest");
26
27/**
28 * \ingroup wifi-test
29 * \ingroup tests
30 *
31 * \brief Test the WifiPhyOperatingChannel::Get20MHzIndicesCoveringRu() method.
32 */
34{
35 public:
36 /**
37 * Constructor
38 */
40 ~Wifi20MHzIndicesCoveringRuTest() override = default;
41
42 /**
43 * Check that the indices of the 20 MHz channels covering the given RU as computed
44 * by WifiPhyOperatingChannel::Get20MHzIndicesCoveringRu() are correct.
45 *
46 * \param primary20 the index of the primary20 channel to configure
47 * \param ru the given RU
48 * \param width the width in MHz of the channel to which the given RU refers to; normally,
49 * it is the width in MHz of the PPDU for which the RU is allocated
50 * \param indices the expected indices
51 */
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
60 WifiPhyOperatingChannel m_channel; //!< operating channel
61};
62
64 : TestCase("Check computation of the indices of the 20 MHz channels covering an RU")
65{
66}
67
68void
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
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
96void
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,
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,
673 width,
674 {0, 1, 2, 3, 4, 5, 6, 7});
675 }
676}
677
678/**
679 * \ingroup wifi-test
680 * \ingroup tests
681 *
682 * \brief wifi primary channels test suite
683 */
685{
686 public:
688};
689
691 : TestSuite("wifi-ru-allocation", Type::UNIT)
692{
693 AddTestCase(new Wifi20MHzIndicesCoveringRuTest(), TestCase::Duration::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
@ RU_26_TONE
Definition: he-ru.h:42
@ RU_484_TONE
Definition: he-ru.h:46
@ RU_996_TONE
Definition: he-ru.h:47
@ RU_106_TONE
Definition: he-ru.h:44
@ RU_52_TONE
Definition: he-ru.h:43
@ RU_242_TONE
Definition: he-ru.h:45
@ RU_2x996_TONE
Definition: he-ru.h:48
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
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:145
@ 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