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