A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tx-duration-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 CTTC
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Nicola Baldo <nbaldo@cttc.es>
7 * Sébastien Deronne <sebastien.deronne@gmail.com>
8 */
9
10#include "ns3/dsss-phy.h"
11#include "ns3/eht-phy.h" //includes OFDM, HT, VHT and HE
12#include "ns3/eht-ppdu.h" //includes OFDM, HT, VHT and HE
13#include "ns3/erp-ofdm-phy.h"
14#include "ns3/he-ru.h"
15#include "ns3/log.h"
16#include "ns3/packet.h"
17#include "ns3/simulator.h"
18#include "ns3/test.h"
19#include "ns3/wifi-psdu.h"
20#include "ns3/yans-wifi-phy.h"
21
22#include <list>
23#include <numeric>
24
25using namespace ns3;
26
27NS_LOG_COMPONENT_DEFINE("TxDurationTest");
28
29namespace
30{
31/**
32 * Create an HE or an EHT RU Specification.
33 * If a primary80 is provided, an HE RU Specification is created, other it is an EHT RU
34 * Specification.
35 *
36 * @param ruType the RU type
37 * @param index the RU index (starting at 1)
38 * @param primaryOrLow80MHz whether the RU is allocated in the primary 80MHz channel or in the low
39 * 80 MHz if the RU is allocated in the secondary 160 MHz
40 * @param primary160MHz whether the RU is allocated in the primary 160MHz channel (only for EHT)
41 * @return the created RU Specification.
42 */
45 std::size_t index,
46 bool primaryOrLow80MHz,
47 std::optional<bool> primary160MHz = std::nullopt)
48{
49 if (!primary160MHz)
50 {
51 return HeRu::RuSpec{ruType, index, primaryOrLow80MHz};
52 }
53 return EhtRu::RuSpec{ruType, index, *primary160MHz, primaryOrLow80MHz};
54}
55
56} // namespace
57
58/**
59 * @ingroup wifi-test
60 * @ingroup tests
61 *
62 * @brief Tx Duration Test
63 */
65{
66 public:
68 ~TxDurationTest() override;
69 void DoRun() override;
70
71 private:
72 /**
73 * Check if the payload tx duration returned by the PHY corresponds to a known value
74 *
75 * @param size size of payload in octets (includes everything after the PHY header)
76 * @param payloadMode the WifiMode used for the transmission
77 * @param channelWidth the channel width used for the transmission
78 * @param guardInterval the guard interval duration used for the transmission
79 * @param preamble the WifiPreamble used for the transmission
80 * @param knownDuration the known duration value of the transmission
81 *
82 * @return true if values correspond, false otherwise
83 */
85 WifiMode payloadMode,
86 MHz_u channelWidth,
87 Time guardInterval,
88 WifiPreamble preamble,
89 Time knownDuration);
90
91 /**
92 * Check if the overall tx duration returned by the PHY corresponds to a known value
93 *
94 * @param size size of payload in octets (includes everything after the PHY header)
95 * @param payloadMode the WifiMode used for the transmission
96 * @param channelWidth the channel width used for the transmission
97 * @param guardInterval the guard interval duration used for the transmission
98 * @param preamble the WifiPreamble used for the transmission
99 * @param knownDuration the known duration value of the transmission
100 *
101 * @return true if values correspond, false otherwise
102 */
103 bool CheckTxDuration(uint32_t size,
104 WifiMode payloadMode,
105 MHz_u channelWidth,
106 Time guardInterval,
107 WifiPreamble preamble,
108 Time knownDuration);
109
110 /**
111 * Check if the overall Tx duration returned by WifiPhy for a MU PPDU
112 * corresponds to a known value
113 *
114 * @param sizes the list of PSDU sizes for each station in octets
115 * @param userInfos the list of HE MU specific user transmission parameters
116 * @param channelWidth the channel width used for the transmission
117 * @param guardInterval the guard interval duration used for the transmission
118 * @param preamble the WifiPreamble used for the transmission
119 * @param knownDuration the known duration value of the transmission
120 *
121 * @return true if values correspond, false otherwise
122 */
123 static bool CheckMuTxDuration(std::list<uint32_t> sizes,
124 std::list<HeMuUserInfo> userInfos,
125 MHz_u channelWidth,
126 Time guardInterval,
127 WifiPreamble preamble,
128 Time knownDuration);
129
130 /**
131 * Calculate the overall Tx duration returned by WifiPhy for list of sizes.
132 * A map of WifiPsdu indexed by STA-ID is built using the provided lists
133 * and handed over to the corresponding SU/MU WifiPhy Tx duration computing
134 * method.
135 * Note that provided lists should be of same size.
136 *
137 * @param sizes the list of PSDU sizes for each station in octets
138 * @param staIds the list of STA-IDs of each station
139 * @param txVector the TXVECTOR used for the transmission of the PPDU
140 * @param band the selected wifi PHY band
141 *
142 * @return the overall Tx duration for the list of sizes (SU or MU PPDU)
143 */
144 static Time CalculateTxDurationUsingList(std::list<uint32_t> sizes,
145 std::list<uint16_t> staIds,
146 WifiTxVector txVector,
147 WifiPhyBand band);
148};
149
151 : TestCase("Wifi TX Duration")
152{
153}
154
158
159bool
161 WifiMode payloadMode,
162 MHz_u channelWidth,
163 Time guardInterval,
164 WifiPreamble preamble,
165 Time knownDuration)
166{
167 WifiTxVector txVector;
168 txVector.SetMode(payloadMode);
169 txVector.SetPreambleType(preamble);
170 txVector.SetChannelWidth(channelWidth);
171 txVector.SetGuardInterval(guardInterval);
172 std::list<WifiPhyBand> testedBands;
174 if ((payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM) && (channelWidth <= 160))
175 {
176 testedBands.push_back(WIFI_PHY_BAND_5GHZ);
177 }
178 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_HE)
179 {
180 testedBands.push_back(WIFI_PHY_BAND_6GHZ);
181 }
182 if ((payloadMode.GetModulationClass() != WIFI_MOD_CLASS_OFDM) &&
183 (payloadMode.GetModulationClass() != WIFI_MOD_CLASS_VHT) && (channelWidth < 80))
184 {
185 testedBands.push_back(WIFI_PHY_BAND_2_4GHZ);
186 }
187 for (auto& testedBand : testedBands)
188 {
189 if ((testedBand == WIFI_PHY_BAND_2_4GHZ) &&
190 (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM))
191 {
192 knownDuration +=
193 MicroSeconds(6); // 2.4 GHz band should be at the end of the bands to test
194 }
195 Time calculatedDuration = YansWifiPhy::GetPayloadDuration(size, txVector, testedBand);
196 if (calculatedDuration != knownDuration)
197 {
198 std::cerr << "size=" << size << " band=" << testedBand << " mode=" << payloadMode
199 << " channelWidth=" << channelWidth << " guardInterval=" << guardInterval
200 << " datarate=" << payloadMode.GetDataRate(channelWidth, guardInterval, 1)
201 << " known=" << knownDuration << " calculated=" << calculatedDuration
202 << std::endl;
203 return false;
204 }
205 }
206 return true;
207}
208
209bool
211 WifiMode payloadMode,
212 MHz_u channelWidth,
213 Time guardInterval,
214 WifiPreamble preamble,
215 Time knownDuration)
216{
217 WifiTxVector txVector{};
218 txVector.SetMode(payloadMode);
219 txVector.SetPreambleType(preamble);
220 txVector.SetChannelWidth(channelWidth);
221 txVector.SetGuardInterval(guardInterval);
222 std::list<WifiPhyBand> testedBands;
224 if ((payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM) && (channelWidth <= 160))
225 {
226 testedBands.push_back(WIFI_PHY_BAND_5GHZ);
227 }
228 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_HE)
229 {
230 testedBands.push_back(WIFI_PHY_BAND_6GHZ);
231 }
232 if ((payloadMode.GetModulationClass() != WIFI_MOD_CLASS_OFDM) &&
233 (payloadMode.GetModulationClass() != WIFI_MOD_CLASS_VHT) && (channelWidth < 80))
234 {
235 testedBands.push_back(WIFI_PHY_BAND_2_4GHZ);
236 }
237 for (auto& testedBand : testedBands)
238 {
239 if ((testedBand == WIFI_PHY_BAND_2_4GHZ) &&
240 (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM))
241 {
242 knownDuration +=
243 MicroSeconds(6); // 2.4 GHz band should be at the end of the bands to test
244 }
245 Time calculatedDuration = YansWifiPhy::CalculateTxDuration(size, txVector, testedBand);
246 Time calculatedDurationUsingList =
247 CalculateTxDurationUsingList(std::list<uint32_t>{size},
248 std::list<uint16_t>{SU_STA_ID},
249 txVector,
250 testedBand);
251 if (calculatedDuration != knownDuration ||
252 calculatedDuration != calculatedDurationUsingList)
253 {
254 std::cerr << "size=" << size << " band=" << testedBand << " mode=" << payloadMode
255 << " channelWidth=" << +channelWidth << " guardInterval=" << guardInterval
256 << " datarate=" << payloadMode.GetDataRate(channelWidth, guardInterval, 1)
257 << " preamble=" << preamble << " known=" << knownDuration
258 << " calculated=" << calculatedDuration
259 << " calculatedUsingList=" << calculatedDurationUsingList << std::endl;
260 return false;
261 }
262 }
263 return true;
264}
265
266bool
267TxDurationTest::CheckMuTxDuration(std::list<uint32_t> sizes,
268 std::list<HeMuUserInfo> userInfos,
269 MHz_u channelWidth,
270 Time guardInterval,
271 WifiPreamble preamble,
272 Time knownDuration)
273{
274 NS_ASSERT(sizes.size() == userInfos.size() && sizes.size() > 1);
276 channelWidth < std::accumulate(
277 std::begin(userInfos),
278 std::end(userInfos),
279 MHz_u{0},
280 [](const MHz_u prevBw, const HeMuUserInfo& info) {
281 return prevBw + WifiRu::GetBandwidth(WifiRu::GetRuType(info.ru));
282 }),
283 "Cannot accommodate all the RUs in the provided band"); // MU-MIMO (for which allocations
284 // use the same RU) is not supported
285 WifiTxVector txVector;
286 txVector.SetPreambleType(preamble);
287 txVector.SetChannelWidth(channelWidth);
288 txVector.SetGuardInterval(guardInterval);
289 if (IsEht(preamble))
290 {
291 txVector.SetEhtPpduType(0);
292 }
293 std::list<uint16_t> staIds;
294
295 uint16_t staId = 1;
296 for (const auto& userInfo : userInfos)
297 {
298 txVector.SetHeMuUserInfo(staId, userInfo);
299 staIds.push_back(staId++);
300 }
302 const uint16_t ruAllocPer20 = IsEht(preamble) ? 64 : 192;
303 txVector.SetRuAllocation({ruAllocPer20, ruAllocPer20}, 0);
304
306 std::list<WifiPhyBand> testedBands;
307 if (channelWidth <= 160)
308 {
309 testedBands.push_back(WIFI_PHY_BAND_5GHZ);
310 }
311 testedBands.push_back(WIFI_PHY_BAND_6GHZ);
312 if (channelWidth < 80)
313 {
314 // Durations vary depending on frequency; test also 2.4 GHz (bug 1971)
315 testedBands.push_back(WIFI_PHY_BAND_2_4GHZ);
316 }
317 for (auto& testedBand : testedBands)
318 {
319 if (testedBand == WIFI_PHY_BAND_2_4GHZ)
320 {
321 knownDuration +=
322 MicroSeconds(6); // 2.4 GHz band should be at the end of the bands to test
323 }
324 Time calculatedDuration;
325 uint32_t longestSize = 0;
326 auto iterStaId = staIds.begin();
327 for (auto& size : sizes)
328 {
329 Time ppduDurationForSta =
330 YansWifiPhy::CalculateTxDuration(size, txVector, testedBand, *iterStaId);
331 if (ppduDurationForSta > calculatedDuration)
332 {
333 calculatedDuration = ppduDurationForSta;
334 staId = *iterStaId;
335 longestSize = size;
336 }
337 ++iterStaId;
338 }
339 Time calculatedDurationUsingList =
340 CalculateTxDurationUsingList(sizes, staIds, txVector, testedBand);
341 if (calculatedDuration != knownDuration ||
342 calculatedDuration != calculatedDurationUsingList)
343 {
344 std::cerr << "size=" << longestSize << " band=" << testedBand << " staId=" << staId
345 << " nss=" << +txVector.GetNss(staId) << " mode=" << txVector.GetMode(staId)
346 << " channelWidth=" << channelWidth << " guardInterval=" << guardInterval
347 << " datarate="
348 << txVector.GetMode(staId).GetDataRate(channelWidth,
349 guardInterval,
350 txVector.GetNss(staId))
351 << " known=" << knownDuration << " calculated=" << calculatedDuration
352 << " calculatedUsingList=" << calculatedDurationUsingList << std::endl;
353 return false;
354 }
355 }
356 return true;
357}
358
359Time
361 std::list<uint16_t> staIds,
362 WifiTxVector txVector,
363 WifiPhyBand band)
364{
365 NS_ASSERT(sizes.size() == staIds.size());
366 WifiConstPsduMap psduMap;
367 auto itStaId = staIds.begin();
368 WifiMacHeader hdr;
369 hdr.SetType(WIFI_MAC_CTL_ACK); // so that size may not be empty while being as short as possible
370 for (auto& size : sizes)
371 {
372 // MAC header and FCS are to deduce from size
373 psduMap[*itStaId++] =
374 Create<WifiPsdu>(Create<Packet>(size - hdr.GetSerializedSize() - 4), hdr);
375 }
376 return WifiPhy::CalculateTxDuration(psduMap, txVector, band);
377}
378
379void
381{
382 bool retval = true;
383
384 // IEEE Std 802.11-2007 Table 18-2 "Example of LENGTH calculations for CCK"
385 retval = retval &&
388 MHz_u{22},
389 NanoSeconds(800),
391 MicroSeconds(744)) &&
394 MHz_u{22},
395 NanoSeconds(800),
397 MicroSeconds(745)) &&
400 MHz_u{22},
401 NanoSeconds(800),
403 MicroSeconds(746)) &&
406 MHz_u{22},
407 NanoSeconds(800),
409 MicroSeconds(747));
410
411 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11b CCK duration failed");
412
413 // Similar, but we add PHY preamble and header durations
414 // and we test different rates.
415 // The payload durations for modes other than 11mbb have been
416 // calculated by hand according to IEEE Std 802.11-2007 18.2.3.5
417 retval = retval &&
418 CheckTxDuration(1023,
420 MHz_u{22},
421 NanoSeconds(800),
423 MicroSeconds(744 + 96)) &&
424 CheckTxDuration(1024,
426 MHz_u{22},
427 NanoSeconds(800),
429 MicroSeconds(745 + 96)) &&
430 CheckTxDuration(1025,
432 MHz_u{22},
433 NanoSeconds(800),
435 MicroSeconds(746 + 96)) &&
436 CheckTxDuration(1026,
438 MHz_u{22},
439 NanoSeconds(800),
441 MicroSeconds(747 + 96)) &&
442 CheckTxDuration(1023,
444 MHz_u{22},
445 NanoSeconds(800),
447 MicroSeconds(744 + 192)) &&
448 CheckTxDuration(1024,
450 MHz_u{22},
451 NanoSeconds(800),
453 MicroSeconds(745 + 192)) &&
454 CheckTxDuration(1025,
456 MHz_u{22},
457 NanoSeconds(800),
459 MicroSeconds(746 + 192)) &&
460 CheckTxDuration(1026,
462 MHz_u{22},
463 NanoSeconds(800),
465 MicroSeconds(747 + 192)) &&
466 CheckTxDuration(1023,
468 MHz_u{22},
469 NanoSeconds(800),
471 MicroSeconds(1488 + 96)) &&
472 CheckTxDuration(1024,
474 MHz_u{22},
475 NanoSeconds(800),
477 MicroSeconds(1490 + 96)) &&
478 CheckTxDuration(1025,
480 MHz_u{22},
481 NanoSeconds(800),
483 MicroSeconds(1491 + 96)) &&
484 CheckTxDuration(1026,
486 MHz_u{22},
487 NanoSeconds(800),
489 MicroSeconds(1493 + 96)) &&
490 CheckTxDuration(1023,
492 MHz_u{22},
493 NanoSeconds(800),
495 MicroSeconds(1488 + 192)) &&
496 CheckTxDuration(1024,
498 MHz_u{22},
499 NanoSeconds(800),
501 MicroSeconds(1490 + 192)) &&
502 CheckTxDuration(1025,
504 MHz_u{22},
505 NanoSeconds(800),
507 MicroSeconds(1491 + 192)) &&
508 CheckTxDuration(1026,
510 MHz_u{22},
511 NanoSeconds(800),
513 MicroSeconds(1493 + 192)) &&
514 CheckTxDuration(1023,
516 MHz_u{22},
517 NanoSeconds(800),
519 MicroSeconds(4092 + 96)) &&
520 CheckTxDuration(1024,
522 MHz_u{22},
523 NanoSeconds(800),
525 MicroSeconds(4096 + 96)) &&
526 CheckTxDuration(1025,
528 MHz_u{22},
529 NanoSeconds(800),
531 MicroSeconds(4100 + 96)) &&
532 CheckTxDuration(1026,
534 MHz_u{22},
535 NanoSeconds(800),
537 MicroSeconds(4104 + 96)) &&
538 CheckTxDuration(1023,
540 MHz_u{22},
541 NanoSeconds(800),
543 MicroSeconds(4092 + 192)) &&
544 CheckTxDuration(1024,
546 MHz_u{22},
547 NanoSeconds(800),
549 MicroSeconds(4096 + 192)) &&
550 CheckTxDuration(1025,
552 MHz_u{22},
553 NanoSeconds(800),
555 MicroSeconds(4100 + 192)) &&
556 CheckTxDuration(1026,
558 MHz_u{22},
559 NanoSeconds(800),
561 MicroSeconds(4104 + 192)) &&
562 CheckTxDuration(1023,
564 MHz_u{22},
565 NanoSeconds(800),
567 MicroSeconds(8184 + 192)) &&
568 CheckTxDuration(1024,
570 MHz_u{22},
571 NanoSeconds(800),
573 MicroSeconds(8192 + 192)) &&
574 CheckTxDuration(1025,
576 MHz_u{22},
577 NanoSeconds(800),
579 MicroSeconds(8200 + 192)) &&
580 CheckTxDuration(1026,
582 MHz_u{22},
583 NanoSeconds(800),
585 MicroSeconds(8208 + 192)) &&
586 CheckTxDuration(1023,
588 MHz_u{22},
589 NanoSeconds(800),
591 MicroSeconds(8184 + 192)) &&
592 CheckTxDuration(1024,
594 MHz_u{22},
595 NanoSeconds(800),
597 MicroSeconds(8192 + 192)) &&
598 CheckTxDuration(1025,
600 MHz_u{22},
601 NanoSeconds(800),
603 MicroSeconds(8200 + 192)) &&
604 CheckTxDuration(1026,
606 MHz_u{22},
607 NanoSeconds(800),
609 MicroSeconds(8208 + 192));
610
611 // values from
612 // https://web.archive.org/web/20100711002639/http://mailman.isi.edu/pipermail/ns-developers/2009-July/006226.html
613 retval = retval && CheckTxDuration(14,
615 MHz_u{22},
616 NanoSeconds(800),
618 MicroSeconds(304));
619
620 // values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
621 retval = retval &&
622 CheckTxDuration(1536,
624 MHz_u{22},
625 NanoSeconds(800),
627 MicroSeconds(1310)) &&
630 MHz_u{22},
631 NanoSeconds(800),
633 MicroSeconds(248)) &&
636 MHz_u{22},
637 NanoSeconds(800),
639 MicroSeconds(203));
640
641 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11b duration failed");
642
643 // 802.11a durations
644 // values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
645 retval = retval &&
646 CheckTxDuration(1536,
648 MHz_u{20},
649 NanoSeconds(800),
651 MicroSeconds(248)) &&
654 MHz_u{20},
655 NanoSeconds(800),
657 MicroSeconds(32)) &&
660 MHz_u{20},
661 NanoSeconds(800),
663 MicroSeconds(24));
664
665 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11a duration failed");
666
667 // 802.11g durations are same as 802.11a durations but with 6 us signal extension
668 retval = retval &&
669 CheckTxDuration(1536,
671 MHz_u{20},
672 NanoSeconds(800),
674 MicroSeconds(254)) &&
677 MHz_u{20},
678 NanoSeconds(800),
680 MicroSeconds(38)) &&
683 MHz_u{20},
684 NanoSeconds(800),
686 MicroSeconds(30));
687
688 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11g duration failed");
689
690 // 802.11n durations
691 retval = retval &&
692 CheckTxDuration(1536,
694 MHz_u{20},
695 NanoSeconds(800),
697 MicroSeconds(228)) &&
700 MHz_u{20},
701 NanoSeconds(800),
703 MicroSeconds(48)) &&
706 MHz_u{20},
707 NanoSeconds(800),
709 MicroSeconds(40)) &&
710 CheckTxDuration(1536,
712 MHz_u{20},
713 NanoSeconds(400),
715 NanoSeconds(1742400)) &&
718 MHz_u{20},
719 NanoSeconds(400),
721 MicroSeconds(126)) &&
724 MHz_u{20},
725 NanoSeconds(400),
727 NanoSeconds(57600)) &&
728 CheckTxDuration(1536,
730 MHz_u{20},
731 NanoSeconds(400),
733 NanoSeconds(226800)) &&
736 MHz_u{20},
737 NanoSeconds(400),
739 NanoSeconds(46800)) &&
742 MHz_u{20},
743 NanoSeconds(400),
745 NanoSeconds(39600)) &&
746 CheckTxDuration(1536,
748 MHz_u{40},
749 NanoSeconds(800),
751 MicroSeconds(128)) &&
754 MHz_u{40},
755 NanoSeconds(800),
757 MicroSeconds(44)) &&
760 MHz_u{40},
761 NanoSeconds(800),
763 MicroSeconds(40)) &&
764 CheckTxDuration(1536,
766 MHz_u{40},
767 NanoSeconds(400),
769 NanoSeconds(118800)) &&
772 MHz_u{40},
773 NanoSeconds(400),
775 NanoSeconds(43200)) &&
778 MHz_u{40},
779 NanoSeconds(400),
781 NanoSeconds(39600));
782
783 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11n duration failed");
784
785 // 802.11ac durations
786 retval = retval &&
787 CheckTxDuration(1536,
789 MHz_u{20},
790 NanoSeconds(800),
792 MicroSeconds(196)) &&
795 MHz_u{20},
796 NanoSeconds(800),
798 MicroSeconds(48)) &&
801 MHz_u{20},
802 NanoSeconds(800),
804 MicroSeconds(40)) &&
805 CheckTxDuration(1536,
807 MHz_u{20},
808 NanoSeconds(400),
810 MicroSeconds(180)) &&
813 MHz_u{20},
814 NanoSeconds(400),
816 NanoSeconds(46800)) &&
819 MHz_u{20},
820 NanoSeconds(400),
822 NanoSeconds(39600)) &&
823 CheckTxDuration(1536,
825 MHz_u{40},
826 NanoSeconds(800),
828 MicroSeconds(108)) &&
831 MHz_u{40},
832 NanoSeconds(800),
834 MicroSeconds(40)) &&
837 MHz_u{40},
838 NanoSeconds(800),
840 MicroSeconds(40)) &&
841 CheckTxDuration(1536,
843 MHz_u{40},
844 NanoSeconds(400),
846 NanoSeconds(100800)) &&
849 MHz_u{40},
850 NanoSeconds(400),
852 NanoSeconds(39600)) &&
855 MHz_u{40},
856 NanoSeconds(400),
858 NanoSeconds(39600)) &&
859 CheckTxDuration(1536,
861 MHz_u{80},
862 NanoSeconds(800),
864 MicroSeconds(460)) &&
867 MHz_u{80},
868 NanoSeconds(800),
870 MicroSeconds(60)) &&
873 MHz_u{80},
874 NanoSeconds(800),
876 MicroSeconds(44)) &&
877 CheckTxDuration(1536,
879 MHz_u{80},
880 NanoSeconds(400),
882 NanoSeconds(417600)) &&
885 MHz_u{80},
886 NanoSeconds(400),
888 NanoSeconds(57600)) &&
891 MHz_u{80},
892 NanoSeconds(400),
894 NanoSeconds(43200)) &&
895 CheckTxDuration(1536,
897 MHz_u{80},
898 NanoSeconds(800),
900 MicroSeconds(68)) &&
903 MHz_u{80},
904 NanoSeconds(800),
906 MicroSeconds(40)) &&
909 MHz_u{80},
910 NanoSeconds(800),
912 MicroSeconds(40)) &&
913 CheckTxDuration(1536,
915 MHz_u{80},
916 NanoSeconds(400),
918 NanoSeconds(64800)) &&
921 MHz_u{80},
922 NanoSeconds(400),
924 NanoSeconds(39600)) &&
927 MHz_u{80},
928 NanoSeconds(400),
930 NanoSeconds(39600)) &&
931 CheckTxDuration(1536,
933 MHz_u{160},
934 NanoSeconds(800),
936 MicroSeconds(56)) &&
939 MHz_u{160},
940 NanoSeconds(800),
942 MicroSeconds(40)) &&
945 MHz_u{160},
946 NanoSeconds(800),
948 MicroSeconds(40)) &&
949 CheckTxDuration(1536,
951 MHz_u{160},
952 NanoSeconds(400),
954 MicroSeconds(54)) &&
957 MHz_u{160},
958 NanoSeconds(400),
960 NanoSeconds(39600)) &&
963 MHz_u{160},
964 NanoSeconds(400),
966 NanoSeconds(39600));
967
968 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11ac duration failed");
969
970 // 802.11ax SU durations
971 retval = retval &&
972 CheckTxDuration(1536,
974 MHz_u{20},
975 NanoSeconds(800),
977 NanoSeconds(1485600)) &&
980 MHz_u{20},
981 NanoSeconds(800),
983 NanoSeconds(125600)) &&
986 MHz_u{20},
987 NanoSeconds(800),
989 NanoSeconds(71200)) &&
990 CheckTxDuration(1536,
992 MHz_u{40},
993 NanoSeconds(800),
995 NanoSeconds(764800)) &&
998 MHz_u{40},
999 NanoSeconds(800),
1001 NanoSeconds(84800)) &&
1002 CheckTxDuration(14,
1004 MHz_u{40},
1005 NanoSeconds(800),
1007 NanoSeconds(57600)) &&
1008 CheckTxDuration(1536,
1010 MHz_u{80},
1011 NanoSeconds(800),
1013 NanoSeconds(397600)) &&
1014 CheckTxDuration(76,
1016 MHz_u{80},
1017 NanoSeconds(800),
1019 NanoSeconds(71200)) &&
1020 CheckTxDuration(14,
1022 MHz_u{80},
1023 NanoSeconds(800),
1025 NanoSeconds(57600)) &&
1026 CheckTxDuration(1536,
1028 MHz_u{160},
1029 NanoSeconds(800),
1031 NanoSeconds(220800)) &&
1032 CheckTxDuration(76,
1034 MHz_u{160},
1035 NanoSeconds(800),
1037 NanoSeconds(57600)) &&
1038 CheckTxDuration(14,
1040 MHz_u{160},
1041 NanoSeconds(800),
1043 NanoSeconds(57600)) &&
1044 CheckTxDuration(1536,
1046 MHz_u{20},
1047 NanoSeconds(1600),
1049 NanoSeconds(1570400)) &&
1050 CheckTxDuration(76,
1052 MHz_u{20},
1053 NanoSeconds(1600),
1055 NanoSeconds(130400)) &&
1056 CheckTxDuration(14,
1058 MHz_u{20},
1059 NanoSeconds(1600),
1061 NanoSeconds(72800)) &&
1062 CheckTxDuration(1536,
1064 MHz_u{40},
1065 NanoSeconds(1600),
1067 NanoSeconds(807200)) &&
1068 CheckTxDuration(76,
1070 MHz_u{40},
1071 NanoSeconds(1600),
1073 NanoSeconds(87200)) &&
1074 CheckTxDuration(14,
1076 MHz_u{40},
1077 NanoSeconds(1600),
1079 NanoSeconds(58400)) &&
1080 CheckTxDuration(1536,
1082 MHz_u{80},
1083 NanoSeconds(1600),
1085 NanoSeconds(418400)) &&
1086 CheckTxDuration(76,
1088 MHz_u{80},
1089 NanoSeconds(1600),
1091 NanoSeconds(72800)) &&
1092 CheckTxDuration(14,
1094 MHz_u{80},
1095 NanoSeconds(1600),
1097 NanoSeconds(58400)) &&
1098 CheckTxDuration(1536,
1100 MHz_u{160},
1101 NanoSeconds(1600),
1103 NanoSeconds(231200)) &&
1104 CheckTxDuration(76,
1106 MHz_u{160},
1107 NanoSeconds(1600),
1109 NanoSeconds(58400)) &&
1110 CheckTxDuration(14,
1112 MHz_u{160},
1113 NanoSeconds(1600),
1115 NanoSeconds(58400)) &&
1116 CheckTxDuration(1536,
1118 MHz_u{20},
1119 NanoSeconds(3200),
1121 MicroSeconds(1740)) &&
1122 CheckTxDuration(76,
1124 MHz_u{20},
1125 NanoSeconds(3200),
1127 MicroSeconds(140)) &&
1128 CheckTxDuration(14,
1130 MHz_u{20},
1131 NanoSeconds(3200),
1133 MicroSeconds(76)) &&
1134 CheckTxDuration(1536,
1136 MHz_u{40},
1137 NanoSeconds(3200),
1139 MicroSeconds(892)) &&
1140 CheckTxDuration(76,
1142 MHz_u{40},
1143 NanoSeconds(3200),
1145 MicroSeconds(92)) &&
1146 CheckTxDuration(14,
1148 MHz_u{40},
1149 NanoSeconds(3200),
1151 MicroSeconds(60)) &&
1152 CheckTxDuration(1536,
1154 MHz_u{80},
1155 NanoSeconds(3200),
1157 MicroSeconds(460)) &&
1158 CheckTxDuration(76,
1160 MHz_u{80},
1161 NanoSeconds(3200),
1163 MicroSeconds(76)) &&
1164 CheckTxDuration(14,
1166 MHz_u{80},
1167 NanoSeconds(3200),
1169 MicroSeconds(60)) &&
1170 CheckTxDuration(1536,
1172 MHz_u{160},
1173 NanoSeconds(3200),
1175 MicroSeconds(252)) &&
1176 CheckTxDuration(76,
1178 MHz_u{160},
1179 NanoSeconds(3200),
1181 MicroSeconds(60)) &&
1182 CheckTxDuration(14,
1184 MHz_u{160},
1185 NanoSeconds(3200),
1187 MicroSeconds(60)) &&
1188 CheckTxDuration(1536,
1190 MHz_u{20},
1191 NanoSeconds(800),
1193 NanoSeconds(139200)) &&
1194 CheckTxDuration(76,
1196 MHz_u{20},
1197 NanoSeconds(800),
1199 NanoSeconds(57600)) &&
1200 CheckTxDuration(14,
1202 MHz_u{20},
1203 NanoSeconds(800),
1205 NanoSeconds(57600)) &&
1206 CheckTxDuration(1536,
1208 MHz_u{40},
1209 NanoSeconds(800),
1211 NanoSeconds(98400)) &&
1212 CheckTxDuration(76,
1214 MHz_u{40},
1215 NanoSeconds(800),
1217 NanoSeconds(57600)) &&
1218 CheckTxDuration(14,
1220 MHz_u{40},
1221 NanoSeconds(800),
1223 NanoSeconds(57600)) &&
1224 CheckTxDuration(1536,
1226 MHz_u{80},
1227 NanoSeconds(800),
1229 NanoSeconds(71200)) &&
1230 CheckTxDuration(76,
1232 MHz_u{80},
1233 NanoSeconds(800),
1235 NanoSeconds(57600)) &&
1236 CheckTxDuration(14,
1238 MHz_u{80},
1239 NanoSeconds(800),
1241 NanoSeconds(57600)) &&
1242 CheckTxDuration(1536,
1244 MHz_u{160},
1245 NanoSeconds(800),
1247 NanoSeconds(57600)) &&
1248 CheckTxDuration(76,
1250 MHz_u{160},
1251 NanoSeconds(800),
1253 NanoSeconds(57600)) &&
1254 CheckTxDuration(14,
1256 MHz_u{160},
1257 NanoSeconds(800),
1259 NanoSeconds(57600)) &&
1260 CheckTxDuration(1536,
1262 MHz_u{20},
1263 NanoSeconds(1600),
1265 NanoSeconds(144800)) &&
1266 CheckTxDuration(76,
1268 MHz_u{20},
1269 NanoSeconds(1600),
1271 NanoSeconds(58400)) &&
1272 CheckTxDuration(14,
1274 MHz_u{20},
1275 NanoSeconds(1600),
1277 NanoSeconds(58400)) &&
1278 CheckTxDuration(1536,
1280 MHz_u{40},
1281 NanoSeconds(1600),
1283 NanoSeconds(101600)) &&
1284 CheckTxDuration(76,
1286 MHz_u{40},
1287 NanoSeconds(1600),
1289 NanoSeconds(58400)) &&
1290 CheckTxDuration(14,
1292 MHz_u{40},
1293 NanoSeconds(1600),
1295 NanoSeconds(58400)) &&
1296 CheckTxDuration(1536,
1298 MHz_u{80},
1299 NanoSeconds(1600),
1301 NanoSeconds(72800)) &&
1302 CheckTxDuration(76,
1304 MHz_u{80},
1305 NanoSeconds(1600),
1307 NanoSeconds(58400)) &&
1308 CheckTxDuration(14,
1310 MHz_u{80},
1311 NanoSeconds(1600),
1313 NanoSeconds(58400)) &&
1314 CheckTxDuration(1536,
1316 MHz_u{160},
1317 NanoSeconds(1600),
1319 NanoSeconds(58400)) &&
1320 CheckTxDuration(76,
1322 MHz_u{160},
1323 NanoSeconds(1600),
1325 NanoSeconds(58400)) &&
1326 CheckTxDuration(14,
1328 MHz_u{160},
1329 NanoSeconds(1600),
1331 NanoSeconds(58400)) &&
1332 CheckTxDuration(1536,
1334 MHz_u{20},
1335 NanoSeconds(3200),
1337 MicroSeconds(156)) &&
1338 CheckTxDuration(76,
1340 MHz_u{20},
1341 NanoSeconds(3200),
1343 MicroSeconds(60)) &&
1344 CheckTxDuration(14,
1346 MHz_u{20},
1347 NanoSeconds(3200),
1349 MicroSeconds(60)) &&
1350 CheckTxDuration(1536,
1352 MHz_u{40},
1353 NanoSeconds(3200),
1355 MicroSeconds(108)) &&
1356 CheckTxDuration(76,
1358 MHz_u{40},
1359 NanoSeconds(3200),
1361 MicroSeconds(60)) &&
1362 CheckTxDuration(14,
1364 MHz_u{40},
1365 NanoSeconds(3200),
1367 MicroSeconds(60)) &&
1368 CheckTxDuration(1536,
1370 MHz_u{80},
1371 NanoSeconds(3200),
1373 MicroSeconds(76)) &&
1374 CheckTxDuration(76,
1376 MHz_u{80},
1377 NanoSeconds(3200),
1379 MicroSeconds(60)) &&
1380 CheckTxDuration(14,
1382 MHz_u{80},
1383 NanoSeconds(3200),
1385 MicroSeconds(60)) &&
1386 CheckTxDuration(1536,
1388 MHz_u{160},
1389 NanoSeconds(3200),
1391 MicroSeconds(60)) &&
1392 CheckTxDuration(76,
1394 MHz_u{160},
1395 NanoSeconds(3200),
1397 MicroSeconds(60)) &&
1398 CheckTxDuration(14,
1400 MHz_u{160},
1401 NanoSeconds(3200),
1403 MicroSeconds(60));
1404
1405 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11ax SU duration failed");
1406
1407 // 802.11ax MU durations
1408 retval = retval &&
1410 std::list<uint32_t>{1536, 1536},
1411 std::list<HeMuUserInfo>{{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 0, 1},
1412 {HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 0, 1}},
1413 MHz_u{40},
1414 NanoSeconds(800),
1417 1493600)) // equivalent to HE_SU for 20 MHz with 2 extra HE-SIG-B (i.e. 8 us)
1419 std::list<uint32_t>{1536, 1536},
1420 std::list<HeMuUserInfo>{{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 1, 1},
1421 {HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 0, 1}},
1422 MHz_u{40},
1423 NanoSeconds(800),
1425 NanoSeconds(1493600)) // shouldn't change if first PSDU is shorter
1427 std::list<uint32_t>{1536, 76},
1428 std::list<HeMuUserInfo>{{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 0, 1},
1429 {HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 0, 1}},
1430 MHz_u{40},
1431 NanoSeconds(800),
1433 NanoSeconds(1493600));
1434
1435 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11ax MU duration failed");
1436
1437 // 802.11be SU durations
1438 retval = retval &&
1439 CheckTxDuration(1536,
1441 MHz_u{20},
1442 NanoSeconds(800),
1444 NanoSeconds(1493600)) &&
1445 CheckTxDuration(76,
1447 MHz_u{20},
1448 NanoSeconds(800),
1450 NanoSeconds(133600)) &&
1451 CheckTxDuration(14,
1453 MHz_u{20},
1454 NanoSeconds(800),
1456 NanoSeconds(79200)) &&
1457 CheckTxDuration(1536,
1459 MHz_u{40},
1460 NanoSeconds(800),
1462 NanoSeconds(772800)) &&
1463 CheckTxDuration(76,
1465 MHz_u{40},
1466 NanoSeconds(800),
1468 NanoSeconds(92800)) &&
1469 CheckTxDuration(14,
1471 MHz_u{40},
1472 NanoSeconds(800),
1474 NanoSeconds(65600)) &&
1475 CheckTxDuration(1536,
1477 MHz_u{80},
1478 NanoSeconds(800),
1480 NanoSeconds(409600)) &&
1481 CheckTxDuration(76,
1483 MHz_u{80},
1484 NanoSeconds(800),
1486 NanoSeconds(83200)) &&
1487 CheckTxDuration(14,
1489 MHz_u{80},
1490 NanoSeconds(800),
1492 NanoSeconds(69600)) &&
1493 CheckTxDuration(1536,
1495 MHz_u{160},
1496 NanoSeconds(800),
1498 NanoSeconds(232800)) &&
1499 CheckTxDuration(76,
1501 MHz_u{160},
1502 NanoSeconds(800),
1504 NanoSeconds(69600)) &&
1505 CheckTxDuration(14,
1507 MHz_u{160},
1508 NanoSeconds(800),
1510 NanoSeconds(69600)) &&
1511 CheckTxDuration(1536,
1513 MHz_u{320},
1514 NanoSeconds(800),
1516 NanoSeconds(159200)) &&
1517 CheckTxDuration(76,
1519 MHz_u{320},
1520 NanoSeconds(800),
1522 NanoSeconds(77600)) &&
1523 CheckTxDuration(14,
1525 MHz_u{320},
1526 NanoSeconds(800),
1528 NanoSeconds(77600)) &&
1529 CheckTxDuration(1536,
1531 MHz_u{20},
1532 NanoSeconds(1600),
1534 NanoSeconds(1578400)) &&
1535 CheckTxDuration(76,
1537 MHz_u{20},
1538 NanoSeconds(1600),
1540 NanoSeconds(138400)) &&
1541 CheckTxDuration(14,
1543 MHz_u{20},
1544 NanoSeconds(1600),
1546 NanoSeconds(80800)) &&
1547 CheckTxDuration(1536,
1549 MHz_u{40},
1550 NanoSeconds(1600),
1552 NanoSeconds(815200)) &&
1553 CheckTxDuration(76,
1555 MHz_u{40},
1556 NanoSeconds(1600),
1558 NanoSeconds(95200)) &&
1559 CheckTxDuration(14,
1561 MHz_u{40},
1562 NanoSeconds(1600),
1564 NanoSeconds(66400)) &&
1565 CheckTxDuration(1536,
1567 MHz_u{80},
1568 NanoSeconds(1600),
1570 NanoSeconds(430400)) &&
1571 CheckTxDuration(76,
1573 MHz_u{80},
1574 NanoSeconds(1600),
1576 NanoSeconds(84800)) &&
1577 CheckTxDuration(14,
1579 MHz_u{80},
1580 NanoSeconds(1600),
1582 NanoSeconds(70400)) &&
1583 CheckTxDuration(1536,
1585 MHz_u{160},
1586 NanoSeconds(1600),
1588 NanoSeconds(243200)) &&
1589 CheckTxDuration(76,
1591 MHz_u{160},
1592 NanoSeconds(1600),
1594 NanoSeconds(70400)) &&
1595 CheckTxDuration(14,
1597 MHz_u{160},
1598 NanoSeconds(1600),
1600 NanoSeconds(70400)) &&
1601 CheckTxDuration(1536,
1603 MHz_u{320},
1604 NanoSeconds(1600),
1606 NanoSeconds(164800)) &&
1607 CheckTxDuration(76,
1609 MHz_u{320},
1610 NanoSeconds(1600),
1612 NanoSeconds(78400)) &&
1613 CheckTxDuration(14,
1615 MHz_u{320},
1616 NanoSeconds(1600),
1618 NanoSeconds(78400)) &&
1619 CheckTxDuration(1536,
1621 MHz_u{20},
1622 NanoSeconds(3200),
1624 MicroSeconds(1748)) &&
1625 CheckTxDuration(76,
1627 MHz_u{20},
1628 NanoSeconds(3200),
1630 MicroSeconds(148)) &&
1631 CheckTxDuration(14,
1633 MHz_u{20},
1634 NanoSeconds(3200),
1636 MicroSeconds(84)) &&
1637 CheckTxDuration(1536,
1639 MHz_u{40},
1640 NanoSeconds(3200),
1642 MicroSeconds(900)) &&
1643 CheckTxDuration(76,
1645 MHz_u{40},
1646 NanoSeconds(3200),
1648 MicroSeconds(100)) &&
1649 CheckTxDuration(14,
1651 MHz_u{40},
1652 NanoSeconds(3200),
1654 MicroSeconds(68)) &&
1655 CheckTxDuration(1536,
1657 MHz_u{80},
1658 NanoSeconds(3200),
1660 MicroSeconds(472)) &&
1661 CheckTxDuration(76,
1663 MHz_u{80},
1664 NanoSeconds(3200),
1666 MicroSeconds(88)) &&
1667 CheckTxDuration(14,
1669 MHz_u{80},
1670 NanoSeconds(3200),
1672 MicroSeconds(72)) &&
1673 CheckTxDuration(1536,
1675 MHz_u{160},
1676 NanoSeconds(3200),
1678 MicroSeconds(264)) &&
1679 CheckTxDuration(76,
1681 MHz_u{160},
1682 NanoSeconds(3200),
1684 MicroSeconds(72)) &&
1685 CheckTxDuration(14,
1687 MHz_u{160},
1688 NanoSeconds(3200),
1690 MicroSeconds(72)) &&
1691 CheckTxDuration(1536,
1693 MHz_u{320},
1694 NanoSeconds(3200),
1696 MicroSeconds(176)) &&
1697 CheckTxDuration(76,
1699 MHz_u{320},
1700 NanoSeconds(3200),
1702 MicroSeconds(80)) &&
1703 CheckTxDuration(14,
1705 MHz_u{320},
1706 NanoSeconds(3200),
1708 MicroSeconds(80)) &&
1709 CheckTxDuration(1536,
1711 MHz_u{20},
1712 NanoSeconds(800),
1714 NanoSeconds(129600)) &&
1715 CheckTxDuration(76,
1717 MHz_u{20},
1718 NanoSeconds(800),
1720 NanoSeconds(61600)) &&
1721 CheckTxDuration(14,
1723 MHz_u{20},
1724 NanoSeconds(800),
1726 NanoSeconds(61600)) &&
1727 CheckTxDuration(1536,
1729 MHz_u{40},
1730 NanoSeconds(800),
1732 NanoSeconds(88800)) &&
1733 CheckTxDuration(76,
1735 MHz_u{40},
1736 NanoSeconds(800),
1738 NanoSeconds(61600)) &&
1739 CheckTxDuration(14,
1741 MHz_u{40},
1742 NanoSeconds(800),
1744 NanoSeconds(61600)) &&
1745 CheckTxDuration(1536,
1747 MHz_u{80},
1748 NanoSeconds(800),
1750 NanoSeconds(75200)) &&
1751 CheckTxDuration(76,
1753 MHz_u{80},
1754 NanoSeconds(800),
1756 NanoSeconds(61600)) &&
1757 CheckTxDuration(14,
1759 MHz_u{80},
1760 NanoSeconds(800),
1762 NanoSeconds(61600)) &&
1763 CheckTxDuration(1536,
1765 MHz_u{160},
1766 NanoSeconds(800),
1768 NanoSeconds(61600)) &&
1769 CheckTxDuration(76,
1771 MHz_u{160},
1772 NanoSeconds(800),
1774 NanoSeconds(61600)) &&
1775 CheckTxDuration(14,
1777 MHz_u{160},
1778 NanoSeconds(800),
1780 NanoSeconds(61600)) &&
1781 CheckTxDuration(1536,
1783 MHz_u{320},
1784 NanoSeconds(800),
1786 NanoSeconds(61600)) &&
1787 CheckTxDuration(76,
1789 MHz_u{320},
1790 NanoSeconds(800),
1792 NanoSeconds(61600)) &&
1793 CheckTxDuration(14,
1795 MHz_u{320},
1796 NanoSeconds(800),
1798 NanoSeconds(61600)) &&
1799 CheckTxDuration(1536,
1801 MHz_u{20},
1802 NanoSeconds(1600),
1804 NanoSeconds(134400)) &&
1805 CheckTxDuration(76,
1807 MHz_u{20},
1808 NanoSeconds(1600),
1810 NanoSeconds(62400)) &&
1811 CheckTxDuration(14,
1813 MHz_u{20},
1814 NanoSeconds(1600),
1816 NanoSeconds(62400)) &&
1817 CheckTxDuration(1536,
1819 MHz_u{40},
1820 NanoSeconds(1600),
1822 NanoSeconds(91200)) &&
1823 CheckTxDuration(76,
1825 MHz_u{40},
1826 NanoSeconds(1600),
1828 NanoSeconds(62400)) &&
1829 CheckTxDuration(14,
1831 MHz_u{40},
1832 NanoSeconds(1600),
1834 NanoSeconds(62400)) &&
1835 CheckTxDuration(1536,
1837 MHz_u{80},
1838 NanoSeconds(1600),
1840 NanoSeconds(76800)) &&
1841 CheckTxDuration(76,
1843 MHz_u{80},
1844 NanoSeconds(1600),
1846 NanoSeconds(62400)) &&
1847 CheckTxDuration(14,
1849 MHz_u{80},
1850 NanoSeconds(1600),
1852 NanoSeconds(62400)) &&
1853 CheckTxDuration(1536,
1855 MHz_u{160},
1856 NanoSeconds(1600),
1858 NanoSeconds(62400)) &&
1859 CheckTxDuration(76,
1861 MHz_u{160},
1862 NanoSeconds(1600),
1864 NanoSeconds(62400)) &&
1865 CheckTxDuration(14,
1867 MHz_u{160},
1868 NanoSeconds(1600),
1870 NanoSeconds(62400)) &&
1871 CheckTxDuration(1536,
1873 MHz_u{320},
1874 NanoSeconds(1600),
1876 NanoSeconds(62400)) &&
1877 CheckTxDuration(76,
1879 MHz_u{320},
1880 NanoSeconds(1600),
1882 NanoSeconds(62400)) &&
1883 CheckTxDuration(14,
1885 MHz_u{320},
1886 NanoSeconds(1600),
1888 NanoSeconds(62400)) &&
1889 CheckTxDuration(1536,
1891 MHz_u{20},
1892 NanoSeconds(3200),
1894 MicroSeconds(144)) &&
1895 CheckTxDuration(76,
1897 MHz_u{20},
1898 NanoSeconds(3200),
1900 MicroSeconds(64)) &&
1901 CheckTxDuration(14,
1903 MHz_u{20},
1904 NanoSeconds(3200),
1906 MicroSeconds(64)) &&
1907 CheckTxDuration(1536,
1909 MHz_u{40},
1910 NanoSeconds(3200),
1912 MicroSeconds(96)) &&
1913 CheckTxDuration(76,
1915 MHz_u{40},
1916 NanoSeconds(3200),
1918 MicroSeconds(64)) &&
1919 CheckTxDuration(14,
1921 MHz_u{40},
1922 NanoSeconds(3200),
1924 MicroSeconds(64)) &&
1925 CheckTxDuration(1536,
1927 MHz_u{80},
1928 NanoSeconds(3200),
1930 MicroSeconds(80)) &&
1931 CheckTxDuration(76,
1933 MHz_u{80},
1934 NanoSeconds(3200),
1936 MicroSeconds(64)) &&
1937 CheckTxDuration(14,
1939 MHz_u{80},
1940 NanoSeconds(3200),
1942 MicroSeconds(64)) &&
1943 CheckTxDuration(1536,
1945 MHz_u{160},
1946 NanoSeconds(3200),
1948 MicroSeconds(64)) &&
1949 CheckTxDuration(76,
1951 MHz_u{160},
1952 NanoSeconds(3200),
1954 MicroSeconds(64)) &&
1955 CheckTxDuration(14,
1957 MHz_u{160},
1958 NanoSeconds(3200),
1960 MicroSeconds(64)) &&
1961 CheckTxDuration(1536,
1963 MHz_u{320},
1964 NanoSeconds(3200),
1966 MicroSeconds(64)) &&
1967 CheckTxDuration(76,
1969 MHz_u{320},
1970 NanoSeconds(3200),
1972 MicroSeconds(64)) &&
1973 CheckTxDuration(14,
1975 MHz_u{320},
1976 NanoSeconds(3200),
1978 MicroSeconds(64));
1979
1980 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11be SU duration failed");
1981
1982 // 802.11be MU durations
1983 retval =
1984 retval &&
1986 std::list<uint32_t>{1536, 1536},
1987 std::list<HeMuUserInfo>{{EhtRu::RuSpec{RuType::RU_242_TONE, 1, true, true}, 0, 1},
1988 {EhtRu::RuSpec{RuType::RU_242_TONE, 2, true, true}, 0, 1}},
1989 MHz_u{40},
1990 NanoSeconds(800),
1992 NanoSeconds(1493600)) // equivalent to 802.11ax MU
1994 std::list<uint32_t>{1536, 1536},
1995 std::list<HeMuUserInfo>{{EhtRu::RuSpec{RuType::RU_242_TONE, 1, true, true}, 1, 1},
1996 {EhtRu::RuSpec{RuType::RU_242_TONE, 2, true, true}, 0, 1}},
1997 MHz_u{40},
1998 NanoSeconds(800),
2000 NanoSeconds(1493600)) // shouldn't change if first PSDU is shorter
2002 std::list<uint32_t>{1536, 76},
2003 std::list<HeMuUserInfo>{{EhtRu::RuSpec{RuType::RU_242_TONE, 1, true, true}, 0, 1},
2004 {EhtRu::RuSpec{RuType::RU_242_TONE, 2, true, true}, 0, 1}},
2005 MHz_u{40},
2006 NanoSeconds(800),
2008 NanoSeconds(1493600));
2009
2010 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11be MU duration failed");
2011
2013}
2014
2015/**
2016 * @ingroup wifi-test
2017 * @ingroup tests
2018 *
2019 * @brief HE-SIG-B/EHT-SIG duration test
2020 */
2022{
2023 public:
2024 /**
2025 * OFDMA or MU-MIMO
2026 */
2028 {
2030 MU_MIMO
2032
2033 /**
2034 * Constructor
2035 *
2036 * @param userInfos the HE MU specific per-user information to use for the test
2037 * @param sigBMode the mode to transmit HE-SIG-B for the test
2038 * @param channelWidth the channel width to select for the test
2039 * @param p20Index the index of the primary20 channel
2040 * @param expectedMuType the expected MU type (OFDMA or MU-MIMO)
2041 * @param expectedRuAllocation the expected RuType::RU_ALLOCATION
2042 * @param expectedNumUsersPerCc the expected number of users per content channel
2043 * @param expectedSigBDuration the expected duration of the HE-SIG-B header
2044 */
2045 MuSigDurationTest(const std::list<HeMuUserInfo>& userInfos,
2046 const WifiMode& sigBMode,
2047 MHz_u channelWidth,
2048 uint8_t p20Index,
2049 MuType expectedMuType,
2050 const RuAllocation& expectedRuAllocation,
2051 const std::pair<std::size_t, std::size_t>& expectedNumUsersPerCc,
2052 Time expectedSigBDuration);
2053
2054 private:
2055 void DoRun() override;
2056 void DoTeardown() override;
2057
2058 /**
2059 * Build a TXVECTOR for HE MU or EHT MU.
2060 *
2061 * @return the configured TXVECTOR for HE MU or EHT MU
2062 */
2064
2065 Ptr<YansWifiPhy> m_phy; ///< the PHY under test
2066
2067 std::list<HeMuUserInfo> m_userInfos; ///< HE MU specific per-user information
2068 WifiMode m_sigBMode; ///< Mode used to transmit HE-SIG-B
2069 MHz_u m_channelWidth; ///< Channel width
2070 uint8_t m_p20Index; ///< index of the primary20 channel
2071 MuType m_expectedMuType; ///< Expected MU type (OFDMA or MU-MIMO)
2072 RuAllocation m_expectedRuAllocation; ///< Expected RuType::RU_ALLOCATION
2073 std::pair<std::size_t, std::size_t>
2074 m_expectedNumUsersPerCc; ///< Expected number of users per content channel
2075 Time m_expectedSigBDuration; ///< Expected duration of the HE-SIG-B/EHT-SIG header
2076};
2077
2079 const std::list<HeMuUserInfo>& userInfos,
2080 const WifiMode& sigBMode,
2081 MHz_u channelWidth,
2082 uint8_t p20Index,
2083 MuType expectedMuType,
2084 const RuAllocation& expectedRuAllocation,
2085 const std::pair<std::size_t, std::size_t>& expectedNumUsersPerCc,
2086 Time expectedSigBDuration)
2087 : TestCase{"Check HE-SIG-B or EHT-SIG duration computation"},
2088 m_userInfos{userInfos},
2089 m_sigBMode{sigBMode},
2090 m_channelWidth{channelWidth},
2091 m_p20Index{p20Index},
2092 m_expectedMuType{expectedMuType},
2093 m_expectedRuAllocation{expectedRuAllocation},
2094 m_expectedNumUsersPerCc{expectedNumUsersPerCc},
2095 m_expectedSigBDuration{expectedSigBDuration}
2096{
2097}
2098
2101{
2102 const auto isHe = WifiRu::IsHe(m_userInfos.begin()->ru);
2103 WifiTxVector txVector;
2106 txVector.SetGuardInterval(NanoSeconds(3200));
2107 txVector.SetStbc(false);
2108 txVector.SetNess(0);
2109 std::list<uint16_t> staIds;
2110 uint16_t staId = 1;
2111 if (!isHe)
2112 {
2113 txVector.SetEhtPpduType(0);
2114 }
2115 for (const auto& userInfo : m_userInfos)
2116 {
2117 txVector.SetHeMuUserInfo(staId, userInfo);
2118 staIds.push_back(staId++);
2119 }
2120 txVector.SetSigBMode(m_sigBMode);
2121 NS_ASSERT(m_expectedMuType == OFDMA ? txVector.IsDlOfdma() : txVector.IsDlMuMimo());
2122 return txVector;
2123}
2124
2125void
2127{
2129 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
2130 MHz_u{0},
2131 MHz_u{320},
2134 ->number;
2138
2139 const auto& txVector = BuildTxVector();
2140 auto phyEntity = m_phy->GetPhyEntity(txVector.GetModulationClass());
2141
2142 // Verify mode for HE-SIG-B/EHT-SIG field
2143 NS_TEST_EXPECT_MSG_EQ(phyEntity->GetSigMode(WIFI_PPDU_FIELD_SIG_B, txVector),
2144 m_sigBMode,
2145 "Incorrect mode used to send HE-SIG-B/EHT-SIG");
2146
2147 // Verify RuType::RU_ALLOCATION in TXVECTOR
2148 NS_TEST_EXPECT_MSG_EQ((txVector.GetRuAllocation(0) == m_expectedRuAllocation),
2149 true,
2150 "Incorrect RuType::RU_ALLOCATION");
2151
2152 // Verify number of users for content channels 1 and 2
2153 const auto& numUsersPerCc = HePpdu::GetNumRusPerHeSigBContentChannel(
2154 txVector.GetChannelWidth(),
2155 txVector.GetModulationClass(),
2156 txVector.GetRuAllocation(m_p20Index),
2157 txVector.GetCenter26ToneRuIndication(),
2158 txVector.IsSigBCompression(),
2159 txVector.IsSigBCompression() ? txVector.GetHeMuUserInfoMap().size() : 0);
2160 const auto contentChannels = HePpdu::GetHeSigBContentChannels(txVector, 0);
2161 NS_TEST_EXPECT_MSG_EQ(numUsersPerCc.first,
2163 "Incorrect number of users in content channel 1");
2164 NS_TEST_EXPECT_MSG_EQ(numUsersPerCc.second,
2166 "Incorrect number of users in content channel 2");
2167 NS_TEST_EXPECT_MSG_EQ(contentChannels.at(0).size(),
2169 "Incorrect number of users in content channel 1");
2170 NS_TEST_EXPECT_MSG_EQ((contentChannels.size() > 1 ? contentChannels.at(1).size() : 0),
2172 "Incorrect number of users in content channel 2");
2173
2174 // Verify total HE-SIG-B/EHT-SIG duration
2175 if (txVector.GetModulationClass() == WIFI_MOD_CLASS_HE)
2176 {
2177 NS_TEST_EXPECT_MSG_EQ(phyEntity->GetDuration(WIFI_PPDU_FIELD_SIG_B, txVector),
2179 "Incorrect duration for HE-SIG-B");
2180 }
2181 else // EHT
2182 {
2183 NS_TEST_EXPECT_MSG_EQ(phyEntity->GetDuration(WIFI_PPDU_FIELD_EHT_SIG, txVector),
2185 "Incorrect duration for EHT-SIG");
2186 }
2187
2188 // Verify user infos in reconstructed TX vector
2189 WifiConstPsduMap psdus;
2190 Time ppduDuration;
2191 for (std::size_t i = 0; i < m_userInfos.size(); ++i)
2192 {
2193 WifiMacHeader hdr;
2194 auto psdu = Create<WifiPsdu>(Create<Packet>(1000), hdr);
2195 ppduDuration = std::max(
2196 ppduDuration,
2197 WifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand(), i + 1));
2198 psdus.insert(std::make_pair(i, psdu));
2199 }
2200 auto ppdu = phyEntity->BuildPpdu(psdus, txVector, ppduDuration);
2201 ppdu->ResetTxVector();
2202 const auto& rxVector = ppdu->GetTxVector();
2203 NS_TEST_EXPECT_MSG_EQ((txVector.GetHeMuUserInfoMap() == rxVector.GetHeMuUserInfoMap()),
2204 true,
2205 "Incorrect user infos in reconstructed TXVECTOR");
2206
2208}
2209
2210void
2212{
2213 m_phy->Dispose();
2214 m_phy = nullptr;
2215}
2216
2217/**
2218 * @ingroup wifi-test
2219 * @ingroup tests
2220 *
2221 * @brief PHY header sections consistency test
2222 */
2224{
2225 public:
2227 ~PhyHeaderSectionsTest() override;
2228 void DoRun() override;
2229
2230 private:
2231 /**
2232 * Check if map of PHY header sections returned by a given PHY entity
2233 * corresponds to a known value
2234 *
2235 * @param obtained the map of PHY header sections to check
2236 * @param expected the expected map of PHY header sections
2237 */
2240};
2241
2243 : TestCase("PHY header sections consistency")
2244{
2245}
2246
2250
2251void
2254{
2255 NS_ASSERT_MSG(obtained.size() == expected.size(),
2256 "The expected map size (" << expected.size() << ") was not obtained ("
2257 << obtained.size() << ")");
2258
2259 auto itObtained = obtained.begin();
2260 auto itExpected = expected.begin();
2261 for (; itObtained != obtained.end() || itExpected != expected.end();)
2262 {
2263 WifiPpduField field = itObtained->first;
2264 auto window = itObtained->second.first;
2265 auto mode = itObtained->second.second;
2266
2267 WifiPpduField fieldRef = itExpected->first;
2268 auto windowRef = itExpected->second.first;
2269 auto modeRef = itExpected->second.second;
2270
2272 fieldRef,
2273 "The expected PPDU field (" << fieldRef << ") was not obtained ("
2274 << field << ")");
2275 NS_TEST_EXPECT_MSG_EQ(window.first,
2276 windowRef.first,
2277 "The expected start time (" << windowRef.first
2278 << ") was not obtained (" << window.first
2279 << ")");
2280 NS_TEST_EXPECT_MSG_EQ(window.second,
2281 windowRef.second,
2282 "The expected stop time (" << windowRef.second
2283 << ") was not obtained (" << window.second
2284 << ")");
2286 modeRef,
2287 "The expected mode (" << modeRef << ") was not obtained (" << mode
2288 << ")");
2289 ++itObtained;
2290 ++itExpected;
2291 }
2292}
2293
2294void
2296{
2297 Time ppduStart = Seconds(1);
2298 Ptr<PhyEntity> phyEntity;
2300 WifiTxVector txVector;
2301 WifiMode nonHtMode;
2302
2303 // ==================================================================================
2304 // 11b (HR/DSSS)
2305 phyEntity = Create<DsssPhy>();
2307 txVector.SetChannelWidth(MHz_u{22});
2308
2309 // -> long PPDU format
2311 nonHtMode = DsssPhy::GetDsssRate1Mbps();
2312 sections = {
2313 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(144)}, nonHtMode}},
2315 {{ppduStart + MicroSeconds(144), ppduStart + MicroSeconds(192)}, nonHtMode}},
2316 };
2317 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2318
2319 // -> long PPDU format if data rate is 1 Mbps (even if preamble is tagged short)
2321 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2322
2323 // -> short PPDU format
2325 nonHtMode = DsssPhy::GetDsssRate2Mbps();
2327 sections = {
2328 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(72)}, nonHtMode}},
2330 {{ppduStart + MicroSeconds(72), ppduStart + MicroSeconds(96)}, nonHtMode}},
2331 };
2332 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2333
2334 // ==================================================================================
2335 // 11a (OFDM)
2337
2338 // -> one iteration per variant: default, 10 MHz, and 5 MHz
2339 std::map<OfdmPhyVariant, std::size_t> variants{
2340 // number to use to deduce rate and BW info for each variant
2341 {OFDM_PHY_DEFAULT, 1},
2342 {OFDM_PHY_10_MHZ, 2},
2343 {OFDM_PHY_5_MHZ, 4},
2344 };
2345 for (auto variant : variants)
2346 {
2347 phyEntity = Create<OfdmPhy>(variant.first);
2348 std::size_t ratio = variant.second;
2349 const auto bw = MHz_u{20} / ratio;
2350 txVector.SetChannelWidth(bw);
2351 txVector.SetMode(OfdmPhy::GetOfdmRate(12000000 / ratio, bw));
2352 nonHtMode = OfdmPhy::GetOfdmRate(6000000 / ratio, bw);
2353 sections = {
2355 {{ppduStart, ppduStart + MicroSeconds(16 * ratio)}, nonHtMode}},
2357 {{ppduStart + MicroSeconds(16 * ratio), ppduStart + MicroSeconds(20 * ratio)},
2358 nonHtMode}},
2359 };
2360 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2361 }
2362
2363 // ==================================================================================
2364 // 11g (ERP-OFDM)
2365 phyEntity = Create<ErpOfdmPhy>();
2366 txVector.SetChannelWidth(MHz_u{20});
2367 txVector.SetMode(ErpOfdmPhy::GetErpOfdmRate(54000000));
2368 nonHtMode = ErpOfdmPhy::GetErpOfdmRate6Mbps();
2369 sections = {
2370 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
2372 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(20)}, nonHtMode}},
2373 };
2374 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2375
2376 // ==================================================================================
2377 // 11n (HT)
2378 phyEntity = Create<HtPhy>(4);
2379 txVector.SetChannelWidth(MHz_u{20});
2380 txVector.SetMode(HtPhy::GetHtMcs6());
2381 nonHtMode = OfdmPhy::GetOfdmRate6Mbps();
2382 WifiMode htSigMode = nonHtMode;
2383
2384 // -> HT-mixed format for 2 SS and no ESS
2386 txVector.SetNss(2);
2387 txVector.SetNess(0);
2388 sections = {
2389 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
2391 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(20)}, nonHtMode}},
2393 {{ppduStart + MicroSeconds(20), ppduStart + MicroSeconds(28)}, htSigMode}},
2395 {{ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(40)}, // 1 HT-STF + 2 HT-LTFs
2396 htSigMode}},
2397 };
2398 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2399 txVector.SetChannelWidth(MHz_u{20}); // shouldn't have any impact
2400 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2401
2402 // -> HT-mixed format for 3 SS and 1 ESS
2403 txVector.SetNss(3);
2404 txVector.SetNess(1);
2405 sections[WIFI_PPDU_FIELD_TRAINING] = {
2406 {ppduStart + MicroSeconds(28),
2407 ppduStart + MicroSeconds(52)}, // 1 HT-STF + 5 HT-LTFs (4 data + 1 extension)
2408 htSigMode};
2409 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2410
2411 // ==================================================================================
2412 // 11ac (VHT)
2413 phyEntity = Create<VhtPhy>();
2414 txVector.SetChannelWidth(MHz_u{20});
2415 txVector.SetNess(0);
2416 txVector.SetMode(VhtPhy::GetVhtMcs7());
2417 WifiMode sigAMode = nonHtMode;
2418 WifiMode sigBMode = VhtPhy::GetVhtMcs0();
2419
2420 // -> VHT SU format for 5 SS
2422 txVector.SetNss(5);
2423 sections = {
2424 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
2426 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(20)}, nonHtMode}},
2428 {{ppduStart + MicroSeconds(20), ppduStart + MicroSeconds(28)}, sigAMode}},
2430 {{ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(56)}, // 1 VHT-STF + 6 VHT-LTFs
2431 sigAMode}},
2432 };
2433 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2434
2435 // -> VHT SU format for 7 SS
2436 txVector.SetNss(7);
2437 sections[WIFI_PPDU_FIELD_TRAINING] = {
2438 {ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(64)}, // 1 VHT-STF + 8 VHT-LTFs
2439 sigAMode};
2440 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2441
2442 // -> VHT MU format for 3 SS
2444 txVector.SetNss(3);
2445 sections[WIFI_PPDU_FIELD_TRAINING] = {
2446 {ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(48)}, // 1 VHT-STF + 4 VHT-LTFs
2447 sigAMode};
2448 sections[WIFI_PPDU_FIELD_SIG_B] = {{ppduStart + MicroSeconds(48), ppduStart + MicroSeconds(52)},
2449 sigBMode};
2450 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2451 txVector.SetChannelWidth(MHz_u{80}); // shouldn't have any impact
2452 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2453
2454 // ==================================================================================
2455 // 11ax (HE)
2456 phyEntity = Create<HePhy>();
2457 txVector.SetChannelWidth(MHz_u{20});
2458 txVector.SetNss(2); // HE-LTF duration assumed to be always 8 us for the time being (see note in
2459 // HePhy::GetTrainingDuration)
2460 txVector.SetMode(HePhy::GetHeMcs9());
2461 std::map<uint16_t, HeMuUserInfo> userInfoMap = {
2462 {1, {HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 4, 2}},
2463 {2, {HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 9, 1}}};
2464 sigAMode = HePhy::GetVhtMcs0();
2465 sigBMode = HePhy::GetVhtMcs4(); // because of first user info map
2466
2467 // -> HE SU format
2469 sections = {
2470 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
2472 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(24)}, // L-SIG + RL-SIG
2473 nonHtMode}},
2475 {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)}, sigAMode}},
2477 {{ppduStart + MicroSeconds(32),
2478 ppduStart + MicroSeconds(52)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
2479 sigAMode}},
2480 };
2481 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2482
2483 // -> HE ER SU format
2485 sections[WIFI_PPDU_FIELD_SIG_A] = {
2486 {ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(40)}, // 16 us HE-SIG-A
2487 sigAMode};
2488 sections[WIFI_PPDU_FIELD_TRAINING] = {
2489 {ppduStart + MicroSeconds(40),
2490 ppduStart + MicroSeconds(60)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
2491 sigAMode};
2492 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2493
2494 // -> HE TB format
2496 txVector.SetHeMuUserInfo(1, userInfoMap.at(1));
2497 txVector.SetHeMuUserInfo(2, userInfoMap.at(2));
2498 sections[WIFI_PPDU_FIELD_SIG_A] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
2499 sigAMode};
2500 sections[WIFI_PPDU_FIELD_TRAINING] = {
2501 {ppduStart + MicroSeconds(32),
2502 ppduStart + MicroSeconds(56)}, // 1 HE-STF (@ 8 us) + 2 HE-LTFs (@ 8 us)
2503 sigAMode};
2504 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2505
2506 // -> HE MU format
2508 txVector.SetSigBMode(sigBMode);
2509 txVector.SetRuAllocation({96}, 0);
2510 sections[WIFI_PPDU_FIELD_SIG_A] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
2511 sigAMode};
2512 sections[WIFI_PPDU_FIELD_SIG_B] = {
2513 {ppduStart + MicroSeconds(32), ppduStart + MicroSeconds(36)}, // only one symbol
2514 sigBMode};
2515 sections[WIFI_PPDU_FIELD_TRAINING] = {
2516 {ppduStart + MicroSeconds(36),
2517 ppduStart + MicroSeconds(56)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
2518 sigBMode};
2519 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2520 txVector.SetChannelWidth(MHz_u{160}); // shouldn't have any impact
2521 txVector.SetRuAllocation({96, 113, 113, 113, 113, 113, 113, 113}, 0);
2522
2523 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2524
2525 // ==================================================================================
2526 // 11be (EHT)
2527 sections.erase(WIFI_PPDU_FIELD_SIG_A); // FIXME: do we keep using separate type for 11be?
2528 sections.erase(WIFI_PPDU_FIELD_SIG_B); // FIXME: do we keep using separate type for 11be?
2529 phyEntity = Create<EhtPhy>();
2530 txVector.SetChannelWidth(MHz_u{20});
2531 txVector.SetNss(2); // EHT-LTF duration assumed to be always 8 us for the time being (see note
2532 // in HePhy::GetTrainingDuration)
2533 txVector.SetMode(EhtPhy::GetEhtMcs9());
2534 userInfoMap = {{1, {EhtRu::RuSpec{RuType::RU_52_TONE, 1, true, true}, 4, 2}},
2535 {2, {EhtRu::RuSpec{RuType::RU_52_TONE, 2, true, true}, 9, 1}},
2536 {3, {EhtRu::RuSpec{RuType::RU_52_TONE, 3, true, true}, 4, 2}},
2537 {4, {EhtRu::RuSpec{RuType::RU_52_TONE, 4, true, true}, 9, 1}}};
2538 WifiMode uSigMode = EhtPhy::GetVhtMcs0();
2539 WifiMode ehtSigMode = EhtPhy::GetVhtMcs4(); // because of first user info map
2540
2541 // -> EHT TB format
2543 txVector.SetHeMuUserInfo(1, userInfoMap.at(1));
2544 txVector.SetHeMuUserInfo(2, userInfoMap.at(2));
2545 sections[WIFI_PPDU_FIELD_U_SIG] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
2546 uSigMode};
2547 sections[WIFI_PPDU_FIELD_TRAINING] = {
2548 {ppduStart + MicroSeconds(32),
2549 ppduStart + MicroSeconds(56)}, // 1 EHT-STF (@ 8 us) + 2 EHT-LTFs (@ 8 us)
2550 uSigMode};
2551 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2552
2553 // -> EHT MU format
2555 txVector.SetEhtPpduType(0); // EHT MU transmission
2556 txVector.SetRuAllocation({24}, 0);
2557 sections[WIFI_PPDU_FIELD_U_SIG] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
2558 uSigMode};
2559 sections[WIFI_PPDU_FIELD_EHT_SIG] = {
2560 {ppduStart + MicroSeconds(32), ppduStart + MicroSeconds(36)}, // only one symbol
2561 ehtSigMode};
2562 sections[WIFI_PPDU_FIELD_TRAINING] = {
2563 {ppduStart + MicroSeconds(36),
2564 ppduStart + MicroSeconds(56)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
2565 ehtSigMode};
2566 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2567 txVector.SetChannelWidth(MHz_u{160}); // shouldn't have any impact
2568 txVector.SetRuAllocation({24, 27, 27, 27, 27, 27, 27, 27}, 0);
2569
2570 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
2571}
2572
2573/**
2574 * @ingroup wifi-test
2575 * @ingroup tests
2576 *
2577 * @brief Tx Duration Test Suite
2578 */
2580{
2581 public:
2583};
2584
2586 : TestSuite("wifi-devices-tx-duration", Type::UNIT)
2587{
2588 AddTestCase(new TxDurationTest, TestCase::Duration::QUICK);
2589
2590 AddTestCase(new PhyHeaderSectionsTest, TestCase::Duration::QUICK);
2591
2592 const auto p80OrLow80 = true;
2593 const auto s80OrHigh80 = false;
2594 for (const auto p160 :
2595 std::initializer_list<std::optional<bool>>{std::nullopt /* HE-SIG-B */,
2596 std::optional(true) /* EHT-SIG */})
2597 {
2598 // 20 MHz band, OFDMA, even number of users in content channel
2600 new MuSigDurationTest({{MakeRuSpec(RuType::RU_106_TONE, 1, p80OrLow80, p160), 11, 1},
2601 {MakeRuSpec(RuType::RU_106_TONE, 2, p80OrLow80, p160), 10, 4}},
2603 MHz_u{20},
2604 0,
2606 (p160 == std::nullopt) ? RuAllocation{96} : RuAllocation{48},
2607 std::make_pair(2, 0), // both users in content channel 1
2608 MicroSeconds(4)), // one OFDM symbol;
2609 TestCase::Duration::QUICK);
2610
2611 // 40 MHz band, OFDMA, even number of users per content channel
2613 {{MakeRuSpec(RuType::RU_106_TONE, 1, p80OrLow80, p160), 11, 1}, // CC1
2614 {MakeRuSpec(RuType::RU_106_TONE, 2, p80OrLow80, p160), 10, 4}, // CC1
2615 {MakeRuSpec(RuType::RU_52_TONE, 5, p80OrLow80, p160), 4, 1}, // CC2
2616 {MakeRuSpec(RuType::RU_52_TONE, 6, p80OrLow80, p160), 6, 2}, // CC2
2617 {MakeRuSpec(RuType::RU_52_TONE, 7, p80OrLow80, p160), 5, 3}, // CC2
2618 {MakeRuSpec(RuType::RU_52_TONE, 8, p80OrLow80, p160), 6, 2}}, // CC2
2620 MHz_u{40},
2621 0,
2623 (p160 == std::nullopt) ? RuAllocation{96, 112} : RuAllocation{48, 24},
2624 std::make_pair(2, 4), // two users in content channel 1 and
2625 // four users in content channel 2
2626 MicroSeconds(4)), // one OFDM symbol;
2627 TestCase::Duration::QUICK);
2628
2629 // 40 MHz band, OFDMA, odd number of users in second content channel
2631 {{MakeRuSpec(RuType::RU_106_TONE, 1, p80OrLow80, p160), 11, 1}, // CC1
2632 {MakeRuSpec(RuType::RU_106_TONE, 2, p80OrLow80, p160), 10, 4}, // CC1
2633 {MakeRuSpec(RuType::RU_52_TONE, 5, p80OrLow80, p160), 4, 1}, // CC2
2634 {MakeRuSpec(RuType::RU_52_TONE, 6, p80OrLow80, p160), 6, 2}, // CC2
2635 {MakeRuSpec(RuType::RU_52_TONE, 7, p80OrLow80, p160), 5, 3}, // CC2
2636 {MakeRuSpec(RuType::RU_52_TONE, 8, p80OrLow80, p160), 6, 2}, // CC2
2637 {MakeRuSpec(RuType::RU_26_TONE, 14, p80OrLow80, p160), 3, 1}}, // CC2
2639 MHz_u{40},
2640 0,
2642 (p160 == std::nullopt) ? RuAllocation{96, 15} : RuAllocation{48, 15},
2643 std::make_pair(2, 5), // two users in content channel 1 and
2644 // five users in content channel 2
2645 MicroSeconds(8)), // two OFDM symbols
2646 TestCase::Duration::QUICK);
2647
2648 // 80 MHz band, OFDMA
2650 {{MakeRuSpec(RuType::RU_106_TONE, 1, p80OrLow80, p160), 11, 1}, // CC1
2651 {MakeRuSpec(RuType::RU_106_TONE, 2, p80OrLow80, p160), 10, 4}, // CC1
2652 {MakeRuSpec(RuType::RU_52_TONE, 5, p80OrLow80, p160), 4, 1}, // CC2
2653 {MakeRuSpec(RuType::RU_52_TONE, 6, p80OrLow80, p160), 6, 2}, // CC2
2654 {MakeRuSpec(RuType::RU_52_TONE, 7, p80OrLow80, p160), 5, 3}, // CC2
2655 {MakeRuSpec(RuType::RU_52_TONE, 8, p80OrLow80, p160), 6, 2}, // CC2
2656 {MakeRuSpec(RuType::RU_26_TONE, 14, p80OrLow80, p160), 3, 1}, // CC2
2657 {MakeRuSpec(RuType::RU_242_TONE, 3, p80OrLow80, p160), 1, 1}, // CC1
2658 {MakeRuSpec(RuType::RU_242_TONE, 4, p80OrLow80, p160), 4, 1}}, // CC2
2660 MHz_u{80},
2661 0,
2663 (p160 == std::nullopt) ? RuAllocation{96, 15, 192, 192}
2664 : RuAllocation{48, 15, 64, 64},
2665 std::make_pair(3, 6), // three users in content channel 1
2666 // and six users in content channel 2
2667 MicroSeconds(16)), // four OFDM symbols
2668 TestCase::Duration::QUICK);
2669
2670 // 80 MHz band, OFDMA, no central 26-tones RU
2672 {{MakeRuSpec(RuType::RU_26_TONE, 1, p80OrLow80, p160), 8, 1}, // CC1
2673 {MakeRuSpec(RuType::RU_26_TONE, 2, p80OrLow80, p160), 8, 1}, // CC1
2674 {MakeRuSpec(RuType::RU_26_TONE, 3, p80OrLow80, p160), 8, 1}, // CC1
2675 {MakeRuSpec(RuType::RU_26_TONE, 4, p80OrLow80, p160), 8, 1}, // CC1
2676 {MakeRuSpec(RuType::RU_26_TONE, 5, p80OrLow80, p160), 8, 1}, // CC1
2677 {MakeRuSpec(RuType::RU_26_TONE, 6, p80OrLow80, p160), 8, 1}, // CC1
2678 {MakeRuSpec(RuType::RU_26_TONE, 7, p80OrLow80, p160), 8, 1}, // CC1
2679 {MakeRuSpec(RuType::RU_26_TONE, 8, p80OrLow80, p160), 8, 1}, // CC1
2680 {MakeRuSpec(RuType::RU_26_TONE, 9, p80OrLow80, p160), 8, 1}, // CC1
2681 {MakeRuSpec(RuType::RU_26_TONE, 10, p80OrLow80, p160), 8, 1}, // CC2
2682 {MakeRuSpec(RuType::RU_26_TONE, 11, p80OrLow80, p160), 8, 1}, // CC2
2683 {MakeRuSpec(RuType::RU_26_TONE, 12, p80OrLow80, p160), 8, 1}, // CC2
2684 {MakeRuSpec(RuType::RU_26_TONE, 13, p80OrLow80, p160), 8, 1}, // CC2
2685 {MakeRuSpec(RuType::RU_26_TONE, 14, p80OrLow80, p160), 8, 1}, // CC2
2686 {MakeRuSpec(RuType::RU_26_TONE, 15, p80OrLow80, p160), 8, 1}, // CC2
2687 {MakeRuSpec(RuType::RU_26_TONE, 16, p80OrLow80, p160), 8, 1}, // CC2
2688 {MakeRuSpec(RuType::RU_26_TONE, 17, p80OrLow80, p160), 8, 1}, // CC2
2689 {MakeRuSpec(RuType::RU_26_TONE, 18, p80OrLow80, p160), 8, 1}, // CC2
2690 {MakeRuSpec(RuType::RU_26_TONE, 20, p80OrLow80, p160), 8, 1}, // CC1
2691 {MakeRuSpec(RuType::RU_26_TONE, 21, p80OrLow80, p160), 8, 1}, // CC1
2692 {MakeRuSpec(RuType::RU_26_TONE, 22, p80OrLow80, p160), 8, 1}, // CC1
2693 {MakeRuSpec(RuType::RU_26_TONE, 23, p80OrLow80, p160), 8, 1}, // CC1
2694 {MakeRuSpec(RuType::RU_26_TONE, 24, p80OrLow80, p160), 8, 1}, // CC1
2695 {MakeRuSpec(RuType::RU_26_TONE, 25, p80OrLow80, p160), 8, 1}, // CC1
2696 {MakeRuSpec(RuType::RU_26_TONE, 26, p80OrLow80, p160), 8, 1}, // CC1
2697 {MakeRuSpec(RuType::RU_26_TONE, 27, p80OrLow80, p160), 8, 1}, // CC1
2698 {MakeRuSpec(RuType::RU_26_TONE, 28, p80OrLow80, p160), 8, 1}, // CC2
2699 {MakeRuSpec(RuType::RU_26_TONE, 29, p80OrLow80, p160), 8, 1}, // CC2
2700 {MakeRuSpec(RuType::RU_26_TONE, 30, p80OrLow80, p160), 8, 1}, // CC2
2701 {MakeRuSpec(RuType::RU_26_TONE, 31, p80OrLow80, p160), 8, 1}, // CC2
2702 {MakeRuSpec(RuType::RU_26_TONE, 32, p80OrLow80, p160), 8, 1}, // CC2
2703 {MakeRuSpec(RuType::RU_26_TONE, 33, p80OrLow80, p160), 8, 1}, // CC2
2704 {MakeRuSpec(RuType::RU_26_TONE, 34, p80OrLow80, p160), 8, 1}, // CC2
2705 {MakeRuSpec(RuType::RU_26_TONE, 35, p80OrLow80, p160), 8, 1}, // CC2
2706 {MakeRuSpec(RuType::RU_26_TONE, 36, p80OrLow80, p160), 8, 1}, // CC2
2707 {MakeRuSpec(RuType::RU_26_TONE, 37, p80OrLow80, p160), 8, 1}}, // CC2
2709 MHz_u{80},
2710 0,
2712 {0, 0, 0, 0},
2713 std::make_pair(18, 18), // 18 users users in each content channel
2714 MicroSeconds(12)), // three OFDM symbols
2715 TestCase::Duration::QUICK);
2716
2717 // 160 MHz band, OFDMA, no central 26-tones RU
2719 {{MakeRuSpec(RuType::RU_106_TONE, 1, p80OrLow80, p160), 11, 1}, // CC1
2720 {MakeRuSpec(RuType::RU_106_TONE, 2, p80OrLow80, p160), 10, 4}, // CC1
2721 {MakeRuSpec(RuType::RU_52_TONE, 5, p80OrLow80, p160), 4, 1}, // CC2
2722 {MakeRuSpec(RuType::RU_52_TONE, 6, p80OrLow80, p160), 6, 2}, // CC2
2723 {MakeRuSpec(RuType::RU_52_TONE, 7, p80OrLow80, p160), 5, 3}, // CC2
2724 {MakeRuSpec(RuType::RU_52_TONE, 8, p80OrLow80, p160), 6, 2}, // CC2
2725 {MakeRuSpec(RuType::RU_26_TONE, 14, p80OrLow80, p160), 3, 1}, // CC2
2726 {MakeRuSpec(RuType::RU_242_TONE, 3, p80OrLow80, p160), 1, 1}, // CC1
2727 {MakeRuSpec(RuType::RU_242_TONE, 4, p80OrLow80, p160), 4, 1}, // CC2
2728 {MakeRuSpec(RuType::RU_996_TONE, 1, s80OrHigh80, p160),
2729 1,
2730 1}}, // CC1 or CC2 => CC1 for better split
2732 MHz_u{160},
2733 0,
2735 (p160 == std::nullopt) ? RuAllocation{96, 15, 192, 192, 208, 115, 208, 115}
2736 : RuAllocation{48, 15, 64, 64, 80, 30, 80, 30},
2737 std::make_pair(4, 6), // four users in content channel 1 and
2738 // seven users in content channel 2
2739 MicroSeconds(16)), // four OFDM symbols
2740 TestCase::Duration::QUICK);
2741
2742 // 20 MHz band, OFDMA, one unallocated RU at the middle
2745 {{MakeRuSpec(RuType::RU_26_TONE, 1, p80OrLow80, p160), 11, 1}, // CC1
2746 {MakeRuSpec(RuType::RU_26_TONE, 2, p80OrLow80, p160), 11, 1}, // CC1
2747 {MakeRuSpec(RuType::RU_26_TONE, 3, p80OrLow80, p160), 11, 1}, // CC1
2748 {MakeRuSpec(RuType::RU_26_TONE, 4, p80OrLow80, p160), 11, 1}, // CC1
2749 {MakeRuSpec(RuType::RU_26_TONE, 6, p80OrLow80, p160), 11, 1}, // CC1
2750 {MakeRuSpec(RuType::RU_26_TONE, 7, p80OrLow80, p160), 11, 1}, // CC1
2751 {MakeRuSpec(RuType::RU_26_TONE, 8, p80OrLow80, p160), 11, 1}, // CC1
2752 {MakeRuSpec(RuType::RU_26_TONE, 9, p80OrLow80, p160), 11, 1}}, // CC1
2754 MHz_u{20},
2755 0,
2757 {0},
2758 std::make_pair(9, 0), // 9 users (8 users + 1 empty user) in content channel 1
2759 MicroSeconds(8)), // two OFDM symbols
2760 TestCase::Duration::QUICK);
2761
2762 // 40 MHz band, OFDMA, unallocated RUs at the begin and at the end of the
2763 // first 20 MHz subband and in the middle of the second 20 MHz subband
2766 {{MakeRuSpec(RuType::RU_52_TONE, 2, p80OrLow80, p160), 10, 1}, // CC1
2767 {MakeRuSpec(RuType::RU_52_TONE, 3, p80OrLow80, p160), 10, 2}, // CC1
2768 {MakeRuSpec(RuType::RU_52_TONE, 5, p80OrLow80, p160), 11, 1}, // CC2
2769 {MakeRuSpec(RuType::RU_52_TONE, 8, p80OrLow80, p160), 11, 2}}, // CC2
2771 MHz_u{40},
2772 0,
2774 (p160 == std::nullopt) ? RuAllocation{112, 112} : RuAllocation{24, 24},
2775 std::make_pair(4,
2776 4), // 4 users (2 users + 2 empty users) in each content channel
2777 MicroSeconds(4)), // one OFDM symbol
2778 TestCase::Duration::QUICK);
2779
2780 // 40 MHz band, OFDMA, one unallocated RUs in the first 20 MHz subband and
2781 // two unallocated RUs in second 20 MHz subband
2784 {{MakeRuSpec(RuType::RU_52_TONE, 1, p80OrLow80, p160), 10, 1}, // CC1
2785 {MakeRuSpec(RuType::RU_52_TONE, 2, p80OrLow80, p160), 10, 2}, // CC1
2786 {MakeRuSpec(RuType::RU_52_TONE, 3, p80OrLow80, p160), 11, 1}, // CC1
2787 {MakeRuSpec(RuType::RU_52_TONE, 5, p80OrLow80, p160), 11, 2}, // CC2
2788 {MakeRuSpec(RuType::RU_52_TONE, 6, p80OrLow80, p160), 11, 3}}, // CC2
2790 MHz_u{40},
2791 0,
2793 (p160 == std::nullopt) ? RuAllocation{112, 112} : RuAllocation{24, 24},
2794 std::make_pair(4,
2795 4), // 4 users (3 users + 1 empty user) in content channel 1 and
2796 // 4 users (2 users + 2 empty users) in content channel 2
2797 MicroSeconds(4)), // one OFDM symbol
2798 TestCase::Duration::QUICK);
2799 }
2800
2801 // 80 MHz band, OFDMA, central 26-tones RU (11ax only)
2803 {{HeRu::RuSpec{RuType::RU_26_TONE, 1, true}, 8, 1}, // CC1
2804 {HeRu::RuSpec{RuType::RU_26_TONE, 2, true}, 8, 1}, // CC1
2805 {HeRu::RuSpec{RuType::RU_26_TONE, 3, true}, 8, 1}, // CC1
2806 {HeRu::RuSpec{RuType::RU_26_TONE, 4, true}, 8, 1}, // CC1
2807 {HeRu::RuSpec{RuType::RU_26_TONE, 5, true}, 8, 1}, // CC1
2808 {HeRu::RuSpec{RuType::RU_26_TONE, 6, true}, 8, 1}, // CC1
2809 {HeRu::RuSpec{RuType::RU_26_TONE, 7, true}, 8, 1}, // CC1
2810 {HeRu::RuSpec{RuType::RU_26_TONE, 8, true}, 8, 1}, // CC1
2811 {HeRu::RuSpec{RuType::RU_26_TONE, 9, true}, 8, 1}, // CC1
2812 {HeRu::RuSpec{RuType::RU_26_TONE, 10, true}, 8, 1}, // CC2
2813 {HeRu::RuSpec{RuType::RU_26_TONE, 11, true}, 8, 1}, // CC2
2814 {HeRu::RuSpec{RuType::RU_26_TONE, 12, true}, 8, 1}, // CC2
2815 {HeRu::RuSpec{RuType::RU_26_TONE, 13, true}, 8, 1}, // CC2
2816 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 8, 1}, // CC2
2817 {HeRu::RuSpec{RuType::RU_26_TONE, 15, true}, 8, 1}, // CC2
2818 {HeRu::RuSpec{RuType::RU_26_TONE, 16, true}, 8, 1}, // CC2
2819 {HeRu::RuSpec{RuType::RU_26_TONE, 17, true}, 8, 1}, // CC2
2820 {HeRu::RuSpec{RuType::RU_26_TONE, 18, true}, 8, 1}, // CC2
2821 {HeRu::RuSpec{RuType::RU_26_TONE, 19, true}, 8, 1}, // CC1
2822 {HeRu::RuSpec{RuType::RU_26_TONE, 20, true}, 8, 1}, // CC1
2823 {HeRu::RuSpec{RuType::RU_26_TONE, 21, true}, 8, 1}, // CC1
2824 {HeRu::RuSpec{RuType::RU_26_TONE, 22, true}, 8, 1}, // CC1
2825 {HeRu::RuSpec{RuType::RU_26_TONE, 23, true}, 8, 1}, // CC1
2826 {HeRu::RuSpec{RuType::RU_26_TONE, 24, true}, 8, 1}, // CC1
2827 {HeRu::RuSpec{RuType::RU_26_TONE, 25, true}, 8, 1}, // CC1
2828 {HeRu::RuSpec{RuType::RU_26_TONE, 26, true}, 8, 1}, // CC1
2829 {HeRu::RuSpec{RuType::RU_26_TONE, 27, true}, 8, 1}, // CC1
2830 {HeRu::RuSpec{RuType::RU_26_TONE, 28, true}, 8, 1}, // CC2
2831 {HeRu::RuSpec{RuType::RU_26_TONE, 29, true}, 8, 1}, // CC2
2832 {HeRu::RuSpec{RuType::RU_26_TONE, 30, true}, 8, 1}, // CC2
2833 {HeRu::RuSpec{RuType::RU_26_TONE, 31, true}, 8, 1}, // CC2
2834 {HeRu::RuSpec{RuType::RU_26_TONE, 32, true}, 8, 1}, // CC2
2835 {HeRu::RuSpec{RuType::RU_26_TONE, 33, true}, 8, 1}, // CC2
2836 {HeRu::RuSpec{RuType::RU_26_TONE, 34, true}, 8, 1}, // CC2
2837 {HeRu::RuSpec{RuType::RU_26_TONE, 35, true}, 8, 1}, // CC2
2838 {HeRu::RuSpec{RuType::RU_26_TONE, 36, true}, 8, 1}, // CC2
2839 {HeRu::RuSpec{RuType::RU_26_TONE, 37, true}, 8, 1}}, // CC2
2841 MHz_u{80},
2842 0,
2844 {0, 0, 0, 0},
2845 std::make_pair(19,
2846 18), // 19 users (18 users + 1 central tones-RU user) in content
2847 // channel 1 and 18 users user in content channel 2
2848 MicroSeconds(12)), // three OFDM symbols
2849 TestCase::Duration::QUICK);
2850
2851 // 160 MHz band, OFDMA, central 26-tones RU in low 80 MHz (11ax only)
2852 AddTestCase(new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2853 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2854 {HeRu::RuSpec{RuType::RU_52_TONE, 5, true}, 4, 1}, // CC2
2855 {HeRu::RuSpec{RuType::RU_52_TONE, 6, true}, 6, 2}, // CC2
2856 {HeRu::RuSpec{RuType::RU_52_TONE, 7, true}, 5, 3}, // CC2
2857 {HeRu::RuSpec{RuType::RU_52_TONE, 8, true}, 6, 2}, // CC2
2858 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 3, 1}, // CC2
2859 {HeRu::RuSpec{RuType::RU_26_TONE, 19, true}, 8, 2}, // CC1
2860 {HeRu::RuSpec{RuType::RU_242_TONE, 3, true}, 1, 1}, // CC1
2861 {HeRu::RuSpec{RuType::RU_242_TONE, 4, true}, 4, 1}, // CC2
2862 {HeRu::RuSpec{RuType::RU_996_TONE, 1, false},
2863 1,
2864 1}}, // CC1 or CC2 => CC1 for better split
2866 MHz_u{160},
2867 0,
2869 {96, 15, 192, 192, 208, 115, 208, 115},
2870 std::make_pair(5, 6), // five users in content channel 1 and
2871 // seven users in content channel 2
2872 MicroSeconds(16)), // four OFDM symbols
2873 TestCase::Duration::QUICK);
2874
2875 // 160 MHz band, OFDMA, central 26-tones RU in high 80 MHz (11ax only)
2877 new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2878 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2879 {HeRu::RuSpec{RuType::RU_106_TONE, 3, true}, 11, 1}, // CC2
2880 {HeRu::RuSpec{RuType::RU_106_TONE, 4, true}, 10, 4}, // CC2
2881 {HeRu::RuSpec{RuType::RU_242_TONE, 3, true}, 10, 1}, // CC1
2882 {HeRu::RuSpec{RuType::RU_242_TONE, 4, true}, 11, 1}, // CC2
2883 {HeRu::RuSpec{RuType::RU_484_TONE, 1, false}, 7, 1}, // CC1 or CC2
2884 {HeRu::RuSpec{RuType::RU_26_TONE, 19, false}, 8, 2}, // CC2
2885 {HeRu::RuSpec{RuType::RU_484_TONE, 2, false}, 9, 1}}, // CC1 or CC2
2887 MHz_u{160},
2888 0,
2890 {96, 96, 192, 192, 200, 114, 114, 200},
2891 std::make_pair(4, 5), // two users in content channel 1 and
2892 // one user in content channel 2
2893 MicroSeconds(4)), // two OFDM symbols
2894 TestCase::Duration::QUICK);
2895
2896 // 160 MHz band, OFDMA, central 26-tones RU in both 80 MHz (11ax only)
2898 new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2899 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2900 {HeRu::RuSpec{RuType::RU_106_TONE, 3, true}, 11, 1}, // CC2
2901 {HeRu::RuSpec{RuType::RU_106_TONE, 4, true}, 10, 4}, // CC2
2902 {HeRu::RuSpec{RuType::RU_26_TONE, 19, true}, 8, 2}, // CC1
2903 {HeRu::RuSpec{RuType::RU_242_TONE, 3, true}, 10, 1}, // CC1
2904 {HeRu::RuSpec{RuType::RU_242_TONE, 4, true}, 11, 1}, // CC2
2905 {HeRu::RuSpec{RuType::RU_484_TONE, 1, false}, 7, 1}, // CC1 or CC2
2906 {HeRu::RuSpec{RuType::RU_26_TONE, 19, false}, 8, 2}, // CC2
2907 {HeRu::RuSpec{RuType::RU_484_TONE, 2, false}, 9, 1}}, // CC1 or CC2
2909 MHz_u{160},
2910 0,
2912 {96, 96, 192, 192, 200, 114, 114, 200},
2913 std::make_pair(5, 5), // two users in content channel 1 and
2914 // one user in content channel 2
2915 MicroSeconds(4)), // two OFDM symbols
2916 TestCase::Duration::QUICK);
2917
2918 // 160 MHz band, OFDMA, 11ax maximum number of users
2919 AddTestCase(new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_26_TONE, 1, true}, 8, 1}, // CC1
2920 {HeRu::RuSpec{RuType::RU_26_TONE, 2, true}, 8, 1}, // CC1
2921 {HeRu::RuSpec{RuType::RU_26_TONE, 3, true}, 8, 1}, // CC1
2922 {HeRu::RuSpec{RuType::RU_26_TONE, 4, true}, 8, 1}, // CC1
2923 {HeRu::RuSpec{RuType::RU_26_TONE, 5, true}, 8, 1}, // CC1
2924 {HeRu::RuSpec{RuType::RU_26_TONE, 6, true}, 8, 1}, // CC1
2925 {HeRu::RuSpec{RuType::RU_26_TONE, 7, true}, 8, 1}, // CC1
2926 {HeRu::RuSpec{RuType::RU_26_TONE, 8, true}, 8, 1}, // CC1
2927 {HeRu::RuSpec{RuType::RU_26_TONE, 9, true}, 8, 1}, // CC1
2928 {HeRu::RuSpec{RuType::RU_26_TONE, 10, true}, 8, 1}, // CC2
2929 {HeRu::RuSpec{RuType::RU_26_TONE, 11, true}, 8, 1}, // CC2
2930 {HeRu::RuSpec{RuType::RU_26_TONE, 12, true}, 8, 1}, // CC2
2931 {HeRu::RuSpec{RuType::RU_26_TONE, 13, true}, 8, 1}, // CC2
2932 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 8, 1}, // CC2
2933 {HeRu::RuSpec{RuType::RU_26_TONE, 15, true}, 8, 1}, // CC2
2934 {HeRu::RuSpec{RuType::RU_26_TONE, 16, true}, 8, 1}, // CC2
2935 {HeRu::RuSpec{RuType::RU_26_TONE, 17, true}, 8, 1}, // CC2
2936 {HeRu::RuSpec{RuType::RU_26_TONE, 18, true}, 8, 1}, // CC2
2937 {HeRu::RuSpec{RuType::RU_26_TONE, 19, true}, 8, 1}, // CC1
2938 {HeRu::RuSpec{RuType::RU_26_TONE, 20, true}, 8, 1}, // CC1
2939 {HeRu::RuSpec{RuType::RU_26_TONE, 21, true}, 8, 1}, // CC1
2940 {HeRu::RuSpec{RuType::RU_26_TONE, 22, true}, 8, 1}, // CC1
2941 {HeRu::RuSpec{RuType::RU_26_TONE, 23, true}, 8, 1}, // CC1
2942 {HeRu::RuSpec{RuType::RU_26_TONE, 24, true}, 8, 1}, // CC1
2943 {HeRu::RuSpec{RuType::RU_26_TONE, 25, true}, 8, 1}, // CC1
2944 {HeRu::RuSpec{RuType::RU_26_TONE, 26, true}, 8, 1}, // CC1
2945 {HeRu::RuSpec{RuType::RU_26_TONE, 27, true}, 8, 1}, // CC1
2946 {HeRu::RuSpec{RuType::RU_26_TONE, 28, true}, 8, 1}, // CC2
2947 {HeRu::RuSpec{RuType::RU_26_TONE, 29, true}, 8, 1}, // CC2
2948 {HeRu::RuSpec{RuType::RU_26_TONE, 30, true}, 8, 1}, // CC2
2949 {HeRu::RuSpec{RuType::RU_26_TONE, 31, true}, 8, 1}, // CC2
2950 {HeRu::RuSpec{RuType::RU_26_TONE, 32, true}, 8, 1}, // CC2
2951 {HeRu::RuSpec{RuType::RU_26_TONE, 33, true}, 8, 1}, // CC2
2952 {HeRu::RuSpec{RuType::RU_26_TONE, 34, true}, 8, 1}, // CC2
2953 {HeRu::RuSpec{RuType::RU_26_TONE, 35, true}, 8, 1}, // CC2
2954 {HeRu::RuSpec{RuType::RU_26_TONE, 36, true}, 8, 1}, // CC2
2955 {HeRu::RuSpec{RuType::RU_26_TONE, 37, true}, 8, 1}, // CC2
2956 {HeRu::RuSpec{RuType::RU_26_TONE, 1, false}, 8, 1}, // CC1
2957 {HeRu::RuSpec{RuType::RU_26_TONE, 2, false}, 8, 1}, // CC1
2958 {HeRu::RuSpec{RuType::RU_26_TONE, 3, false}, 8, 1}, // CC1
2959 {HeRu::RuSpec{RuType::RU_26_TONE, 4, false}, 8, 1}, // CC1
2960 {HeRu::RuSpec{RuType::RU_26_TONE, 5, false}, 8, 1}, // CC1
2961 {HeRu::RuSpec{RuType::RU_26_TONE, 6, false}, 8, 1}, // CC1
2962 {HeRu::RuSpec{RuType::RU_26_TONE, 7, false}, 8, 1}, // CC1
2963 {HeRu::RuSpec{RuType::RU_26_TONE, 8, false}, 8, 1}, // CC1
2964 {HeRu::RuSpec{RuType::RU_26_TONE, 9, false}, 8, 1}, // CC1
2965 {HeRu::RuSpec{RuType::RU_26_TONE, 10, false}, 8, 1}, // CC2
2966 {HeRu::RuSpec{RuType::RU_26_TONE, 11, false}, 8, 1}, // CC2
2967 {HeRu::RuSpec{RuType::RU_26_TONE, 12, false}, 8, 1}, // CC2
2968 {HeRu::RuSpec{RuType::RU_26_TONE, 13, false}, 8, 1}, // CC2
2969 {HeRu::RuSpec{RuType::RU_26_TONE, 14, false}, 8, 1}, // CC2
2970 {HeRu::RuSpec{RuType::RU_26_TONE, 15, false}, 8, 1}, // CC2
2971 {HeRu::RuSpec{RuType::RU_26_TONE, 16, false}, 8, 1}, // CC2
2972 {HeRu::RuSpec{RuType::RU_26_TONE, 17, false}, 8, 1}, // CC2
2973 {HeRu::RuSpec{RuType::RU_26_TONE, 18, false}, 8, 1}, // CC2
2974 {HeRu::RuSpec{RuType::RU_26_TONE, 19, false}, 8, 1}, // CC1
2975 {HeRu::RuSpec{RuType::RU_26_TONE, 20, false}, 8, 1}, // CC1
2976 {HeRu::RuSpec{RuType::RU_26_TONE, 21, false}, 8, 1}, // CC1
2977 {HeRu::RuSpec{RuType::RU_26_TONE, 22, false}, 8, 1}, // CC1
2978 {HeRu::RuSpec{RuType::RU_26_TONE, 23, false}, 8, 1}, // CC1
2979 {HeRu::RuSpec{RuType::RU_26_TONE, 24, false}, 8, 1}, // CC1
2980 {HeRu::RuSpec{RuType::RU_26_TONE, 25, false}, 8, 1}, // CC1
2981 {HeRu::RuSpec{RuType::RU_26_TONE, 26, false}, 8, 1}, // CC1
2982 {HeRu::RuSpec{RuType::RU_26_TONE, 27, false}, 8, 1}, // CC1
2983 {HeRu::RuSpec{RuType::RU_26_TONE, 28, false}, 8, 1}, // CC2
2984 {HeRu::RuSpec{RuType::RU_26_TONE, 29, false}, 8, 1}, // CC2
2985 {HeRu::RuSpec{RuType::RU_26_TONE, 30, false}, 8, 1}, // CC2
2986 {HeRu::RuSpec{RuType::RU_26_TONE, 31, false}, 8, 1}, // CC2
2987 {HeRu::RuSpec{RuType::RU_26_TONE, 32, false}, 8, 1}, // CC2
2988 {HeRu::RuSpec{RuType::RU_26_TONE, 33, false}, 8, 1}, // CC2
2989 {HeRu::RuSpec{RuType::RU_26_TONE, 34, false}, 8, 1}, // CC2
2990 {HeRu::RuSpec{RuType::RU_26_TONE, 35, false}, 8, 1}, // CC2
2991 {HeRu::RuSpec{RuType::RU_26_TONE, 36, false}, 8, 1}, // CC2
2992 {HeRu::RuSpec{RuType::RU_26_TONE, 37, false}, 8, 1}}, // CC2
2994 MHz_u{160},
2995 0,
2997 {0, 0, 0, 0, 0, 0, 0, 0},
2998 std::make_pair(37,
2999 37), // 37 users (36 users + 1 central tones-RU
3000 // user) in each content channel
3001 MicroSeconds(20)), // five OFDM symbols
3002 TestCase::Duration::QUICK);
3003
3004 // 320 MHz band, OFDMA, 11be maximum number of users
3006 new MuSigDurationTest({{EhtRu::RuSpec{RuType::RU_26_TONE, 1, true, true}, 8, 1}, // CC1
3007 {EhtRu::RuSpec{RuType::RU_26_TONE, 2, true, true}, 8, 1}, // CC1
3008 {EhtRu::RuSpec{RuType::RU_26_TONE, 3, true, true}, 8, 1}, // CC1
3009 {EhtRu::RuSpec{RuType::RU_26_TONE, 4, true, true}, 8, 1}, // CC1
3010 {EhtRu::RuSpec{RuType::RU_26_TONE, 5, true, true}, 8, 1}, // CC1
3011 {EhtRu::RuSpec{RuType::RU_26_TONE, 6, true, true}, 8, 1}, // CC1
3012 {EhtRu::RuSpec{RuType::RU_26_TONE, 7, true, true}, 8, 1}, // CC1
3013 {EhtRu::RuSpec{RuType::RU_26_TONE, 8, true, true}, 8, 1}, // CC1
3014 {EhtRu::RuSpec{RuType::RU_26_TONE, 9, true, true}, 8, 1}, // CC1
3015 {EhtRu::RuSpec{RuType::RU_26_TONE, 10, true, true}, 8, 1}, // CC2
3016 {EhtRu::RuSpec{RuType::RU_26_TONE, 11, true, true}, 8, 1}, // CC2
3017 {EhtRu::RuSpec{RuType::RU_26_TONE, 12, true, true}, 8, 1}, // CC2
3018 {EhtRu::RuSpec{RuType::RU_26_TONE, 13, true, true}, 8, 1}, // CC2
3019 {EhtRu::RuSpec{RuType::RU_26_TONE, 14, true, true}, 8, 1}, // CC2
3020 {EhtRu::RuSpec{RuType::RU_26_TONE, 15, true, true}, 8, 1}, // CC2
3021 {EhtRu::RuSpec{RuType::RU_26_TONE, 16, true, true}, 8, 1}, // CC2
3022 {EhtRu::RuSpec{RuType::RU_26_TONE, 17, true, true}, 8, 1}, // CC2
3023 {EhtRu::RuSpec{RuType::RU_26_TONE, 18, true, true}, 8, 1}, // CC2
3024 {EhtRu::RuSpec{RuType::RU_26_TONE, 20, true, true}, 8, 1}, // CC1
3025 {EhtRu::RuSpec{RuType::RU_26_TONE, 21, true, true}, 8, 1}, // CC1
3026 {EhtRu::RuSpec{RuType::RU_26_TONE, 22, true, true}, 8, 1}, // CC1
3027 {EhtRu::RuSpec{RuType::RU_26_TONE, 23, true, true}, 8, 1}, // CC1
3028 {EhtRu::RuSpec{RuType::RU_26_TONE, 24, true, true}, 8, 1}, // CC1
3029 {EhtRu::RuSpec{RuType::RU_26_TONE, 25, true, true}, 8, 1}, // CC1
3030 {EhtRu::RuSpec{RuType::RU_26_TONE, 26, true, true}, 8, 1}, // CC1
3031 {EhtRu::RuSpec{RuType::RU_26_TONE, 27, true, true}, 8, 1}, // CC1
3032 {EhtRu::RuSpec{RuType::RU_26_TONE, 28, true, true}, 8, 1}, // CC2
3033 {EhtRu::RuSpec{RuType::RU_26_TONE, 29, true, true}, 8, 1}, // CC2
3034 {EhtRu::RuSpec{RuType::RU_26_TONE, 30, true, true}, 8, 1}, // CC2
3035 {EhtRu::RuSpec{RuType::RU_26_TONE, 31, true, true}, 8, 1}, // CC2
3036 {EhtRu::RuSpec{RuType::RU_26_TONE, 32, true, true}, 8, 1}, // CC2
3037 {EhtRu::RuSpec{RuType::RU_26_TONE, 33, true, true}, 8, 1}, // CC2
3038 {EhtRu::RuSpec{RuType::RU_26_TONE, 34, true, true}, 8, 1}, // CC2
3039 {EhtRu::RuSpec{RuType::RU_26_TONE, 35, true, true}, 8, 1}, // CC2
3040 {EhtRu::RuSpec{RuType::RU_26_TONE, 36, true, true}, 8, 1}, // CC2
3041 {EhtRu::RuSpec{RuType::RU_26_TONE, 37, true, true}, 8, 1}, // CC2
3042 {EhtRu::RuSpec{RuType::RU_26_TONE, 1, true, false}, 8, 1}, // CC1
3043 {EhtRu::RuSpec{RuType::RU_26_TONE, 2, true, false}, 8, 1}, // CC1
3044 {EhtRu::RuSpec{RuType::RU_26_TONE, 3, true, false}, 8, 1}, // CC1
3045 {EhtRu::RuSpec{RuType::RU_26_TONE, 4, true, false}, 8, 1}, // CC1
3046 {EhtRu::RuSpec{RuType::RU_26_TONE, 5, true, false}, 8, 1}, // CC1
3047 {EhtRu::RuSpec{RuType::RU_26_TONE, 6, true, false}, 8, 1}, // CC1
3048 {EhtRu::RuSpec{RuType::RU_26_TONE, 7, true, false}, 8, 1}, // CC1
3049 {EhtRu::RuSpec{RuType::RU_26_TONE, 8, true, false}, 8, 1}, // CC1
3050 {EhtRu::RuSpec{RuType::RU_26_TONE, 9, true, false}, 8, 1}, // CC1
3051 {EhtRu::RuSpec{RuType::RU_26_TONE, 10, true, false}, 8, 1}, // CC2
3052 {EhtRu::RuSpec{RuType::RU_26_TONE, 11, true, false}, 8, 1}, // CC2
3053 {EhtRu::RuSpec{RuType::RU_26_TONE, 12, true, false}, 8, 1}, // CC2
3054 {EhtRu::RuSpec{RuType::RU_26_TONE, 13, true, false}, 8, 1}, // CC2
3055 {EhtRu::RuSpec{RuType::RU_26_TONE, 14, true, false}, 8, 1}, // CC2
3056 {EhtRu::RuSpec{RuType::RU_26_TONE, 15, true, false}, 8, 1}, // CC2
3057 {EhtRu::RuSpec{RuType::RU_26_TONE, 16, true, false}, 8, 1}, // CC2
3058 {EhtRu::RuSpec{RuType::RU_26_TONE, 17, true, false}, 8, 1}, // CC2
3059 {EhtRu::RuSpec{RuType::RU_26_TONE, 18, true, false}, 8, 1}, // CC2
3060 {EhtRu::RuSpec{RuType::RU_26_TONE, 20, true, false}, 8, 1}, // CC1
3061 {EhtRu::RuSpec{RuType::RU_26_TONE, 21, true, false}, 8, 1}, // CC1
3062 {EhtRu::RuSpec{RuType::RU_26_TONE, 22, true, false}, 8, 1}, // CC1
3063 {EhtRu::RuSpec{RuType::RU_26_TONE, 23, true, false}, 8, 1}, // CC1
3064 {EhtRu::RuSpec{RuType::RU_26_TONE, 24, true, false}, 8, 1}, // CC1
3065 {EhtRu::RuSpec{RuType::RU_26_TONE, 25, true, false}, 8, 1}, // CC1
3066 {EhtRu::RuSpec{RuType::RU_26_TONE, 26, true, false}, 8, 1}, // CC1
3067 {EhtRu::RuSpec{RuType::RU_26_TONE, 27, true, false}, 8, 1}, // CC1
3068 {EhtRu::RuSpec{RuType::RU_26_TONE, 28, true, false}, 8, 1}, // CC2
3069 {EhtRu::RuSpec{RuType::RU_26_TONE, 29, true, false}, 8, 1}, // CC2
3070 {EhtRu::RuSpec{RuType::RU_26_TONE, 30, true, false}, 8, 1}, // CC2
3071 {EhtRu::RuSpec{RuType::RU_26_TONE, 31, true, false}, 8, 1}, // CC2
3072 {EhtRu::RuSpec{RuType::RU_26_TONE, 32, true, false}, 8, 1}, // CC2
3073 {EhtRu::RuSpec{RuType::RU_26_TONE, 33, true, false}, 8, 1}, // CC2
3074 {EhtRu::RuSpec{RuType::RU_26_TONE, 34, true, false}, 8, 1}, // CC2
3075 {EhtRu::RuSpec{RuType::RU_26_TONE, 35, true, false}, 8, 1}, // CC2
3076 {EhtRu::RuSpec{RuType::RU_26_TONE, 36, true, false}, 8, 1}, // CC2
3077 {EhtRu::RuSpec{RuType::RU_26_TONE, 37, true, false}, 8, 1}, // CC2
3078 {EhtRu::RuSpec{RuType::RU_26_TONE, 1, false, true}, 8, 1}, // CC1
3079 {EhtRu::RuSpec{RuType::RU_26_TONE, 2, false, true}, 8, 1}, // CC1
3080 {EhtRu::RuSpec{RuType::RU_26_TONE, 3, false, true}, 8, 1}, // CC1
3081 {EhtRu::RuSpec{RuType::RU_26_TONE, 4, false, true}, 8, 1}, // CC1
3082 {EhtRu::RuSpec{RuType::RU_26_TONE, 5, false, true}, 8, 1}, // CC1
3083 {EhtRu::RuSpec{RuType::RU_26_TONE, 6, false, true}, 8, 1}, // CC1
3084 {EhtRu::RuSpec{RuType::RU_26_TONE, 7, false, true}, 8, 1}, // CC1
3085 {EhtRu::RuSpec{RuType::RU_26_TONE, 8, false, true}, 8, 1}, // CC1
3086 {EhtRu::RuSpec{RuType::RU_26_TONE, 9, false, true}, 8, 1}, // CC1
3087 {EhtRu::RuSpec{RuType::RU_26_TONE, 10, false, true}, 8, 1}, // CC2
3088 {EhtRu::RuSpec{RuType::RU_26_TONE, 11, false, true}, 8, 1}, // CC2
3089 {EhtRu::RuSpec{RuType::RU_26_TONE, 12, false, true}, 8, 1}, // CC2
3090 {EhtRu::RuSpec{RuType::RU_26_TONE, 13, false, true}, 8, 1}, // CC2
3091 {EhtRu::RuSpec{RuType::RU_26_TONE, 14, false, true}, 8, 1}, // CC2
3092 {EhtRu::RuSpec{RuType::RU_26_TONE, 15, false, true}, 8, 1}, // CC2
3093 {EhtRu::RuSpec{RuType::RU_26_TONE, 16, false, true}, 8, 1}, // CC2
3094 {EhtRu::RuSpec{RuType::RU_26_TONE, 17, false, true}, 8, 1}, // CC2
3095 {EhtRu::RuSpec{RuType::RU_26_TONE, 18, false, true}, 8, 1}, // CC2
3096 {EhtRu::RuSpec{RuType::RU_26_TONE, 20, false, true}, 8, 1}, // CC1
3097 {EhtRu::RuSpec{RuType::RU_26_TONE, 21, false, true}, 8, 1}, // CC1
3098 {EhtRu::RuSpec{RuType::RU_26_TONE, 22, false, true}, 8, 1}, // CC1
3099 {EhtRu::RuSpec{RuType::RU_26_TONE, 23, false, true}, 8, 1}, // CC1
3100 {EhtRu::RuSpec{RuType::RU_26_TONE, 24, false, true}, 8, 1}, // CC1
3101 {EhtRu::RuSpec{RuType::RU_26_TONE, 25, false, true}, 8, 1}, // CC1
3102 {EhtRu::RuSpec{RuType::RU_26_TONE, 26, false, true}, 8, 1}, // CC1
3103 {EhtRu::RuSpec{RuType::RU_26_TONE, 27, false, true}, 8, 1}, // CC1
3104 {EhtRu::RuSpec{RuType::RU_26_TONE, 28, false, true}, 8, 1}, // CC2
3105 {EhtRu::RuSpec{RuType::RU_26_TONE, 29, false, true}, 8, 1}, // CC2
3106 {EhtRu::RuSpec{RuType::RU_26_TONE, 30, false, true}, 8, 1}, // CC2
3107 {EhtRu::RuSpec{RuType::RU_26_TONE, 31, false, true}, 8, 1}, // CC2
3108 {EhtRu::RuSpec{RuType::RU_26_TONE, 32, false, true}, 8, 1}, // CC2
3109 {EhtRu::RuSpec{RuType::RU_26_TONE, 33, false, true}, 8, 1}, // CC2
3110 {EhtRu::RuSpec{RuType::RU_26_TONE, 34, false, true}, 8, 1}, // CC2
3111 {EhtRu::RuSpec{RuType::RU_26_TONE, 35, false, true}, 8, 1}, // CC2
3112 {EhtRu::RuSpec{RuType::RU_26_TONE, 36, false, true}, 8, 1}, // CC2
3113 {EhtRu::RuSpec{RuType::RU_26_TONE, 37, false, true}, 8, 1}, // CC2
3114 {EhtRu::RuSpec{RuType::RU_26_TONE, 1, false, false}, 8, 1}, // CC1
3115 {EhtRu::RuSpec{RuType::RU_26_TONE, 2, false, false}, 8, 1}, // CC1
3116 {EhtRu::RuSpec{RuType::RU_26_TONE, 3, false, false}, 8, 1}, // CC1
3117 {EhtRu::RuSpec{RuType::RU_26_TONE, 4, false, false}, 8, 1}, // CC1
3118 {EhtRu::RuSpec{RuType::RU_26_TONE, 5, false, false}, 8, 1}, // CC1
3119 {EhtRu::RuSpec{RuType::RU_26_TONE, 6, false, false}, 8, 1}, // CC1
3120 {EhtRu::RuSpec{RuType::RU_26_TONE, 7, false, false}, 8, 1}, // CC1
3121 {EhtRu::RuSpec{RuType::RU_26_TONE, 8, false, false}, 8, 1}, // CC1
3122 {EhtRu::RuSpec{RuType::RU_26_TONE, 9, false, false}, 8, 1}, // CC1
3123 {EhtRu::RuSpec{RuType::RU_26_TONE, 10, false, false}, 8, 1}, // CC2
3124 {EhtRu::RuSpec{RuType::RU_26_TONE, 11, false, false}, 8, 1}, // CC2
3125 {EhtRu::RuSpec{RuType::RU_26_TONE, 12, false, false}, 8, 1}, // CC2
3126 {EhtRu::RuSpec{RuType::RU_26_TONE, 13, false, false}, 8, 1}, // CC2
3127 {EhtRu::RuSpec{RuType::RU_26_TONE, 14, false, false}, 8, 1}, // CC2
3128 {EhtRu::RuSpec{RuType::RU_26_TONE, 15, false, false}, 8, 1}, // CC2
3129 {EhtRu::RuSpec{RuType::RU_26_TONE, 16, false, false}, 8, 1}, // CC2
3130 {EhtRu::RuSpec{RuType::RU_26_TONE, 17, false, false}, 8, 1}, // CC2
3131 {EhtRu::RuSpec{RuType::RU_26_TONE, 18, false, false}, 8, 1}, // CC2
3132 {EhtRu::RuSpec{RuType::RU_26_TONE, 20, false, false}, 8, 1}, // CC1
3133 {EhtRu::RuSpec{RuType::RU_26_TONE, 21, false, false}, 8, 1}, // CC1
3134 {EhtRu::RuSpec{RuType::RU_26_TONE, 22, false, false}, 8, 1}, // CC1
3135 {EhtRu::RuSpec{RuType::RU_26_TONE, 23, false, false}, 8, 1}, // CC1
3136 {EhtRu::RuSpec{RuType::RU_26_TONE, 24, false, false}, 8, 1}, // CC1
3137 {EhtRu::RuSpec{RuType::RU_26_TONE, 25, false, false}, 8, 1}, // CC1
3138 {EhtRu::RuSpec{RuType::RU_26_TONE, 26, false, false}, 8, 1}, // CC1
3139 {EhtRu::RuSpec{RuType::RU_26_TONE, 27, false, false}, 8, 1}, // CC1
3140 {EhtRu::RuSpec{RuType::RU_26_TONE, 28, false, false}, 8, 1}, // CC2
3141 {EhtRu::RuSpec{RuType::RU_26_TONE, 29, false, false}, 8, 1}, // CC2
3142 {EhtRu::RuSpec{RuType::RU_26_TONE, 30, false, false}, 8, 1}, // CC2
3143 {EhtRu::RuSpec{RuType::RU_26_TONE, 31, false, false}, 8, 1}, // CC2
3144 {EhtRu::RuSpec{RuType::RU_26_TONE, 32, false, false}, 8, 1}, // CC2
3145 {EhtRu::RuSpec{RuType::RU_26_TONE, 33, false, false}, 8, 1}, // CC2
3146 {EhtRu::RuSpec{RuType::RU_26_TONE, 34, false, false}, 8, 1}, // CC2
3147 {EhtRu::RuSpec{RuType::RU_26_TONE, 35, false, false}, 8, 1}, // CC2
3148 {EhtRu::RuSpec{RuType::RU_26_TONE, 36, false, false}, 8, 1}, // CC2
3149 {EhtRu::RuSpec{RuType::RU_26_TONE, 37, false, false}, 8, 1}}, // CC2
3151 MHz_u{320},
3152 0,
3154 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3155 std::make_pair(72,
3156 72), // 72 users in each content channel
3157 MicroSeconds(40)), // ten OFDM symbols
3158 TestCase::Duration::QUICK);
3159
3160 // 160 MHz band, OFDMA, 11ax single-user using 2x996 tones RU
3162 new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 8, 1}}, // CC1
3164 MHz_u{160},
3165 0,
3167 {208, 208, 208, 208, 208, 208, 208, 208},
3168 std::make_pair(1, 0), // one user in HE-SIG-B content channel 1
3169 MicroSeconds(4)), // one OFDM symbol;
3170 TestCase::Duration::QUICK);
3171
3172 // 160 MHz band, OFDMA, 11ax with primary80 is in the high 80 MHz band
3174 new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_996_TONE, 1, false}, 8, 1}, // CC2
3175 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 8, 1}}, // CC1
3177 MHz_u{160},
3178 4,
3180 {208, 115, 208, 115, 115, 208, 115, 208},
3181 std::make_pair(1, 1), // one user in each HE-SIG-B content channel
3182 MicroSeconds(4)), // one OFDM symbol;
3183 TestCase::Duration::QUICK);
3184
3185 // 40 MHz band, OFDMA, first 20 MHz is punctured
3187 new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 11, 1}}, // CC2
3189 MHz_u{40},
3190 1,
3192 {113, 192},
3193 std::make_pair(0, 1), // one user in HE-SIG-B content channel 1
3194 MicroSeconds(4)), // one OFDM symbol;
3195 TestCase::Duration::QUICK);
3196
3197 // 20 MHz band, MU-MIMO, 2 users
3198 AddTestCase(new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 11, 1}, // CC1
3199 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 10, 4}}, // CC1
3201 MHz_u{20},
3202 0,
3204 {192},
3205 std::make_pair(2, 0), // both users in content channel 1
3206 MicroSeconds(4)), // one OFDM symbol
3207 TestCase::Duration::QUICK);
3208
3209 // 20 MHz band, MU-MIMO, 3 users
3210 AddTestCase(new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 4, 3}, // CC1
3211 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 5, 2}, // CC1
3212 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 6, 1}}, // CC1
3214 MHz_u{20},
3215 0,
3217 {192},
3218 std::make_pair(3, 0), // all users in content channel 1
3219 MicroSeconds(4)), // one OFDM symbol
3220 TestCase::Duration::QUICK);
3221
3222 // 20 MHz band, MU-MIMO, 4 users
3223 AddTestCase(new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 4, 1}, // CC1
3224 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 5, 2}, // CC1
3225 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 6, 3}, // CC1
3226 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 7, 2}}, // CC1
3228 MHz_u{20},
3229 0,
3231 {192},
3232 std::make_pair(4, 0), // all users in content channel 1
3233 MicroSeconds(4)), // one OFDM symbol
3234 TestCase::Duration::QUICK);
3235
3236 // 20 MHz band, MU-MIMO, 6 users
3237 AddTestCase(new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 4, 1}, // CC1
3238 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 5, 1}, // CC1
3239 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 6, 2}, // CC1
3240 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 7, 2}, // CC1
3241 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 8, 1}, // CC1
3242 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 9, 1}}, // CC1
3244 MHz_u{20},
3245 0,
3247 {192},
3248 std::make_pair(6, 0), // all users in content channel 1
3249 MicroSeconds(4)), // one OFDM symbol
3250 TestCase::Duration::QUICK);
3251
3252 // 20 MHz band, MU-MIMO, 8 users
3253 AddTestCase(new MuSigDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 4, 1}, // CC1
3254 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 5, 1}, // CC1
3255 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 6, 1}, // CC1
3256 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 7, 1}, // CC1
3257 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 8, 1}, // CC1
3258 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 9, 1}, // CC1
3259 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 10, 1}, // CC1
3260 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 11, 1}}, // CC1
3262 MHz_u{20},
3263 0,
3265 {192},
3266 std::make_pair(8, 0), // all users in content channel 1
3267 MicroSeconds(8)), // two OFDM symbols
3268 TestCase::Duration::QUICK);
3269
3270 // 40 MHz band, MU-MIMO, 2 users
3272 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 11, 1}, // CC1
3273 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 10, 4}}, // CC2
3275 MHz_u{40},
3276 0,
3278 {200, 200},
3279 std::make_pair(1, 1), // users equally split between the two content channels
3280 MicroSeconds(4)), // one OFDM symbol
3281 TestCase::Duration::QUICK);
3282
3283 // 40 MHz band, MU-MIMO, 3 users
3286 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 4, 3}, // CC1
3287 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 5, 2}, // CC2
3288 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 6, 1}}, // CC1
3290 MHz_u{40},
3291 0,
3293 {200, 200},
3294 std::make_pair(2, 1), // 2 users in content channel 1 and 1 user in content channel 2
3295 MicroSeconds(4)), // one OFDM symbol
3296 TestCase::Duration::QUICK);
3297
3298 // 40 MHz band, MU-MIMO, 4 users
3300 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 4, 1}, // CC1
3301 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 5, 2}, // CC2
3302 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 6, 3}, // CC1
3303 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 7, 2}}, // CC2
3305 MHz_u{40},
3306 0,
3308 {200, 200},
3309 std::make_pair(2, 2), // users equally split between the two content channels
3310 MicroSeconds(4)), // one OFDM symbol
3311 TestCase::Duration::QUICK);
3312
3313 // 40 MHz band, MU-MIMO, 6 users
3315 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 4, 1}, // CC1
3316 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 5, 1}, // CC2
3317 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 6, 2}, // CC1
3318 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 7, 2}, // CC2
3319 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 8, 1}, // CC1
3320 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 9, 1}}, // CC2
3322 MHz_u{40},
3323 0,
3325 {200, 200},
3326 std::make_pair(3, 3), // users equally split between the two content channels
3327 MicroSeconds(4)), // one OFDM symbol
3328 TestCase::Duration::QUICK);
3329
3330 // 40 MHz band, MU-MIMO, 8 users
3332 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 4, 1}, // CC1
3333 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 5, 1}, // CC2
3334 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 6, 1}, // CC1
3335 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 7, 1}, // CC2
3336 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 8, 1}, // CC1
3337 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 9, 1}, // CC2
3338 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 10, 1}, // CC1
3339 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 11, 1}}, // CC2
3341 MHz_u{40},
3342 0,
3344 {200, 200},
3345 std::make_pair(4, 4), // users equally split between the two content channels
3346 MicroSeconds(4)), // one OFDM symbol
3347 TestCase::Duration::QUICK);
3348
3349 // 80 MHz band, MU-MIMO, 2 users
3351 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 11, 1}, // CC1
3352 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 10, 4}}, // CC2
3354 MHz_u{80},
3355 0,
3357 {208, 208, 208, 208},
3358 std::make_pair(1, 1), // users equally split between the two content channels
3359 MicroSeconds(4)), // one OFDM symbol
3360 TestCase::Duration::QUICK);
3361
3362 // 80 MHz band, MU-MIMO, 3 users
3365 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 4, 3}, // CC1
3366 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 5, 2}, // CC2
3367 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 6, 1}}, // CC1
3369 MHz_u{80},
3370 0,
3372 {208, 208, 208, 208},
3373 std::make_pair(2, 1), // 2 users in content channel 1 and 1 user in content channel 2
3374 MicroSeconds(4)), // one OFDM symbol
3375 TestCase::Duration::QUICK);
3376
3377 // 80 MHz band, MU-MIMO, 4 users
3379 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 4, 1}, // CC1
3380 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 5, 2}, // CC2
3381 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 6, 3}, // CC1
3382 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 7, 2}}, // CC2
3384 MHz_u{80},
3385 0,
3387 {208, 208, 208, 208},
3388 std::make_pair(2, 2), // users equally split between the two content channels
3389 MicroSeconds(4)), // one OFDM symbol
3390 TestCase::Duration::QUICK);
3391
3392 // 80 MHz band, MU-MIMO, 6 users
3394 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 4, 1}, // CC1
3395 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 5, 1}, // CC2
3396 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 6, 2}, // CC1
3397 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 7, 2}, // CC2
3398 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 8, 1}, // CC1
3399 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 9, 1}}, // CC2
3401 MHz_u{80},
3402 0,
3404 {208, 208, 208, 208},
3405 std::make_pair(3, 3), // users equally split between the two content channels
3406 MicroSeconds(4)), // one OFDM symbol
3407 TestCase::Duration::QUICK);
3408
3409 // 80 MHz band, MU-MIMO, 8 users
3411 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 4, 1}, // CC1
3412 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 5, 1}, // CC2
3413 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 6, 1}, // CC1
3414 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 7, 1}, // CC2
3415 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 8, 1}, // CC1
3416 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 9, 1}, // CC2
3417 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 10, 1}, // CC1
3418 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 11, 1}}, // CC2
3420 MHz_u{80},
3421 0,
3423 {208, 208, 208, 208},
3424 std::make_pair(4, 4), // users equally split between the two content channels
3425 MicroSeconds(4)), // one OFDM symbol
3426 TestCase::Duration::QUICK);
3427
3428 // 160 MHz band, MU-MIMO, 2 users
3430 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 11, 1}, // CC1
3431 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 10, 4}}, // CC2
3433 MHz_u{160},
3434 0,
3436 {208, 208, 208, 208, 208, 208, 208, 208},
3437 std::make_pair(1, 1), // users equally split between the two content channels
3438 MicroSeconds(4)), // one OFDM symbol
3439 TestCase::Duration::QUICK);
3440
3441 // 160 MHz band, MU-MIMO, 3 users
3444 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 4, 3}, // CC1
3445 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 5, 2}, // CC2
3446 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 6, 1}}, // CC1
3448 MHz_u{160},
3449 0,
3451 {208, 208, 208, 208, 208, 208, 208, 208},
3452 std::make_pair(2, 1), // 2 users in content channel 1 and 1 user in content channel 2
3453 MicroSeconds(4)), // one OFDM symbol
3454 TestCase::Duration::QUICK);
3455
3456 // 160 MHz band, MU-MIMO, 4 users
3458 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 4, 1}, // CC1
3459 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 5, 2}, // CC2
3460 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 6, 3}, // CC1
3461 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 7, 2}}, // CC2
3463 MHz_u{160},
3464 0,
3466 {208, 208, 208, 208, 208, 208, 208, 208},
3467 std::make_pair(2, 2), // users equally split between the two content channels
3468 MicroSeconds(4)), // one OFDM symbol
3469 TestCase::Duration::QUICK);
3470
3471 // 160 MHz band, MU-MIMO, 6 users
3473 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 4, 1}, // CC1
3474 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 5, 1}, // CC2
3475 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 6, 2}, // CC1
3476 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 7, 2}, // CC2
3477 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 8, 1}, // CC1
3478 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 9, 1}}, // CC2
3480 MHz_u{160},
3481 0,
3483 {208, 208, 208, 208, 208, 208, 208, 208},
3484 std::make_pair(3, 3), // users equally split between the two content channels
3485 MicroSeconds(4)), // one OFDM symbol
3486 TestCase::Duration::QUICK);
3487
3488 // 160 MHz band, MU-MIMO, 8 users
3490 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 4, 1}, // CC1
3491 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 5, 1}, // CC2
3492 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 6, 1}, // CC1
3493 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 7, 1}, // CC2
3494 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 8, 1}, // CC1
3495 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 9, 1}, // CC2
3496 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 10, 1}, // CC1
3497 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 11, 1}}, // CC2
3499 MHz_u{160},
3500 0,
3502 {208, 208, 208, 208, 208, 208, 208, 208},
3503 std::make_pair(4, 4), // users equally split between the two content channels
3504 MicroSeconds(4)), // one OFDM symbol
3505 TestCase::Duration::QUICK);
3506}
3507
HE-SIG-B/EHT-SIG duration test.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
MuType m_expectedMuType
Expected MU type (OFDMA or MU-MIMO)
WifiTxVector BuildTxVector() const
Build a TXVECTOR for HE MU or EHT MU.
WifiMode m_sigBMode
Mode used to transmit HE-SIG-B.
MuSigDurationTest(const std::list< HeMuUserInfo > &userInfos, const WifiMode &sigBMode, MHz_u channelWidth, uint8_t p20Index, MuType expectedMuType, const RuAllocation &expectedRuAllocation, const std::pair< std::size_t, std::size_t > &expectedNumUsersPerCc, Time expectedSigBDuration)
Constructor.
std::list< HeMuUserInfo > m_userInfos
HE MU specific per-user information.
MuType
OFDMA or MU-MIMO.
MHz_u m_channelWidth
Channel width.
Time m_expectedSigBDuration
Expected duration of the HE-SIG-B/EHT-SIG header.
RuAllocation m_expectedRuAllocation
Expected RuType::RU_ALLOCATION.
Ptr< YansWifiPhy > m_phy
the PHY under test
uint8_t m_p20Index
index of the primary20 channel
std::pair< std::size_t, std::size_t > m_expectedNumUsersPerCc
Expected number of users per content channel.
void DoRun() override
Implementation to actually run this TestCase.
PHY header sections consistency test.
void DoRun() override
Implementation to actually run this TestCase.
void CheckPhyHeaderSections(PhyEntity::PhyHeaderSections obtained, PhyEntity::PhyHeaderSections expected)
Check if map of PHY header sections returned by a given PHY entity corresponds to a known value.
Tx Duration Test.
~TxDurationTest() override
static Time CalculateTxDurationUsingList(std::list< uint32_t > sizes, std::list< uint16_t > staIds, WifiTxVector txVector, WifiPhyBand band)
Calculate the overall Tx duration returned by WifiPhy for list of sizes.
bool CheckTxDuration(uint32_t size, WifiMode payloadMode, MHz_u channelWidth, Time guardInterval, WifiPreamble preamble, Time knownDuration)
Check if the overall tx duration returned by the PHY corresponds to a known value.
static bool CheckMuTxDuration(std::list< uint32_t > sizes, std::list< HeMuUserInfo > userInfos, MHz_u channelWidth, Time guardInterval, WifiPreamble preamble, Time knownDuration)
Check if the overall Tx duration returned by WifiPhy for a MU PPDU corresponds to a known value.
void DoRun() override
Implementation to actually run this TestCase.
bool CheckPayloadDuration(uint32_t size, WifiMode payloadMode, MHz_u channelWidth, Time guardInterval, WifiPreamble preamble, Time knownDuration)
Check if the payload tx duration returned by the PHY corresponds to a known value.
Tx Duration Test Suite.
static WifiMode GetDsssRate5_5Mbps()
Return a WifiMode for HR/DSSS at 5.5 Mbps.
static WifiMode GetDsssRate1Mbps()
Return a WifiMode for DSSS at 1 Mbps.
static WifiMode GetDsssRate11Mbps()
Return a WifiMode for HR/DSSS at 11 Mbps.
static WifiMode GetDsssRate2Mbps()
Return a WifiMode for DSSS at 2 Mbps.
static WifiMode GetEhtMcs0()
Return MCS 0 from EHT MCS values.
static WifiMode GetEhtMcs13()
Return MCS 13 from EHT MCS values.
static WifiMode GetEhtMcs9()
Return MCS 9 from EHT MCS values.
RU Specification.
Definition eht-ru.h:34
static WifiMode GetErpOfdmRate(uint64_t rate)
Return a WifiMode for ERP-OFDM corresponding to the provided rate.
static WifiMode GetErpOfdmRate6Mbps()
Return a WifiMode for ERP-OFDM at 6 Mbps.
static WifiMode GetErpOfdmRate54Mbps()
Return a WifiMode for ERP-OFDM at 54 Mbps.
static WifiMode GetHeMcs9()
Return MCS 9 from HE MCS values.
static WifiMode GetHeMcs11()
Return MCS 11 from HE MCS values.
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
static std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(MHz_u channelWidth, WifiModulationClass mc, const RuAllocation &ruAllocation, std::optional< Center26ToneRuIndication > center26ToneRuIndication, bool sigBCompression, uint8_t numMuMimoUsers)
Get the number of STAs per HE-SIG-B content channel.
Definition he-ppdu.cc:552
static HeSigBContentChannels GetHeSigBContentChannels(const WifiTxVector &txVector, uint8_t p20Index)
Get the HE SIG-B content channels for a given PPDU IEEE 802.11ax-2021 27.3.11.8.2 HE-SIG-B content ch...
Definition he-ppdu.cc:663
RU Specification.
Definition he-ru.h:37
static WifiMode GetHtMcs0()
Return MCS 0 from HT MCS values.
static WifiMode GetHtMcs6()
Return MCS 6 from HT MCS values.
static WifiMode GetHtMcs7()
Return MCS 7 from HT MCS values.
void Dispose()
Dispose of this Object.
Definition object.cc:247
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6 Mbps.
static WifiMode GetOfdmRate54Mbps()
Return a WifiMode for OFDM at 54 Mbps.
static WifiMode GetOfdmRate(uint64_t rate, MHz_u bw=MHz_u{20})
Return a WifiMode for OFDM corresponding to the provided rate and the channel bandwidth (20,...
Definition ofdm-phy.cc:403
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
Definition phy-entity.h:294
Smart pointer class similar to boost::intrusive_ptr.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
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
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
static WifiMode GetVhtMcs5()
Return MCS 5 from VHT MCS values.
static WifiMode GetVhtMcs3()
Return MCS 3 from VHT MCS values.
static WifiMode GetVhtMcs1()
Return MCS 1 from VHT MCS values.
static WifiMode GetVhtMcs4()
Return MCS 4 from VHT MCS values.
static WifiMode GetVhtMcs9()
Return MCS 9 from VHT MCS values.
static WifiMode GetVhtMcs8()
Return MCS 8 from VHT MCS values.
static WifiMode GetVhtMcs7()
Return MCS 7 from VHT MCS values.
Implements the IEEE 802.11 MAC header.
uint32_t GetSerializedSize() const override
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
represent a single transmission mode
Definition wifi-mode.h:38
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:172
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
Definition wifi-mode.cc:110
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:937
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition wifi-phy.cc:997
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition wifi-phy.cc:1563
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition wifi-phy.cc:1057
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition wifi-phy.cc:769
void SetOperatingChannel(const WifiPhyOperatingChannel &channel)
If the standard for this object has not been set yet, store the channel settings corresponding to the...
Definition wifi-phy.cc:1123
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first frequency segment matching the specified parameters.
std::variant< HeRu::RuSpec, EhtRu::RuSpec > RuSpec
variant of the RU specification
Definition wifi-ru.h:27
static bool IsHe(RuSpec ru)
Get whether a given RU variant is a HE RU.
Definition wifi-ru.cc:248
static MHz_u GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition wifi-ru.cc:78
static RuType GetRuType(RuSpec ru)
Get the type of a given RU.
Definition wifi-ru.cc:45
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetRuAllocation(const RuAllocation &ruAlloc, uint8_t p20Index)
Set RU_ALLOCATION field.
void SetStbc(bool stbc)
Sets if STBC is being used.
void SetNess(uint8_t ness)
Sets the Ness number.
void SetEhtPpduType(uint8_t type)
Set the EHT_PPDU_TYPE parameter.
void SetGuardInterval(Time guardInterval)
Sets the guard interval duration (in nanoseconds)
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
void SetChannelWidth(MHz_u channelWidth)
Sets the selected channelWidth.
bool IsDlOfdma() const
Return true if this TX vector is used for a downlink multi-user transmission using OFDMA.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
void SetSigBMode(const WifiMode &mode)
Set the MCS used for SIG-B.
bool IsDlMuMimo() const
Return true if this TX vector is used for a downlink multi-user transmission using MU-MIMO.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetNss(uint8_t nss)
Sets the number of Nss.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:241
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPhyBand
Identifies the PHY band.
WifiPpduField
The type of PPDU field (grouped for convenience)
@ WIFI_STANDARD_80211be
@ WIFI_PREAMBLE_LONG
@ WIFI_PREAMBLE_EHT_TB
@ WIFI_PREAMBLE_HE_ER_SU
@ WIFI_PREAMBLE_HE_TB
@ WIFI_PREAMBLE_EHT_MU
@ WIFI_PREAMBLE_HE_MU
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PREAMBLE_VHT_MU
@ WIFI_PREAMBLE_VHT_SU
@ WIFI_PREAMBLE_SHORT
@ WIFI_PREAMBLE_HT_MF
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ OFDM_PHY_10_MHZ
Definition ofdm-phy.h:35
@ OFDM_PHY_DEFAULT
Definition ofdm-phy.h:34
@ OFDM_PHY_5_MHZ
Definition ofdm-phy.h:36
@ WIFI_PPDU_FIELD_SIG_B
SIG-B field.
@ WIFI_PPDU_FIELD_TRAINING
STF + LTF fields (excluding those in preamble for HT-GF)
@ WIFI_PPDU_FIELD_NON_HT_HEADER
PHY header field for DSSS or ERP, short PHY header field for HR/DSSS or ERP, field not present for HT...
@ WIFI_PPDU_FIELD_EHT_SIG
EHT-SIG field.
@ WIFI_PPDU_FIELD_HT_SIG
HT-SIG field.
@ WIFI_PPDU_FIELD_PREAMBLE
SYNC + SFD fields for DSSS or ERP, shortSYNC + shortSFD fields for HR/DSSS or ERP,...
@ WIFI_PPDU_FIELD_U_SIG
U-SIG field.
@ WIFI_PPDU_FIELD_SIG_A
SIG-A field.
WifiRu::RuSpec MakeRuSpec(RuType ruType, std::size_t index, bool primaryOrLow80MHz, std::optional< bool > primary160MHz=std::nullopt)
Create an HE or an EHT RU Specification.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsEht(WifiPreamble preamble)
Return true if a preamble corresponds to an EHT transmission.
RuType
The different Resource Unit (RU) types.
Definition wifi-types.h:99
@ WIFI_MAC_CTL_ACK
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
std::vector< uint16_t > RuAllocation
9 bits RU_ALLOCATION per 20 MHz
HE MU specific user transmission parameters.
static TxDurationTestSuite g_txDurationTestSuite
the test suite