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
29/**
30 * @ingroup wifi-test
31 * @ingroup tests
32 *
33 * @brief Tx Duration Test
34 */
36{
37 public:
39 ~TxDurationTest() override;
40 void DoRun() override;
41
42 private:
43 /**
44 * Check if the payload tx duration returned by InterferenceHelper
45 * corresponds to a known value
46 *
47 * @param size size of payload in octets (includes everything after the PHY header)
48 * @param payloadMode the WifiMode used for the transmission
49 * @param channelWidth the channel width used for the transmission
50 * @param guardInterval the guard interval duration used for the transmission
51 * @param preamble the WifiPreamble used for the transmission
52 * @param knownDuration the known duration value of the transmission
53 *
54 * @return true if values correspond, false otherwise
55 */
57 WifiMode payloadMode,
58 MHz_u channelWidth,
59 Time guardInterval,
60 WifiPreamble preamble,
61 Time knownDuration);
62
63 /**
64 * Check if the overall tx duration returned by InterferenceHelper
65 * corresponds to a known value
66 *
67 * @param size size of payload in octets (includes everything after the PHY header)
68 * @param payloadMode the WifiMode used for the transmission
69 * @param channelWidth the channel width used for the transmission
70 * @param guardInterval the guard interval duration used for the transmission
71 * @param preamble the WifiPreamble used for the transmission
72 * @param knownDuration the known duration value of the transmission
73 *
74 * @return true if values correspond, false otherwise
75 */
76 bool CheckTxDuration(uint32_t size,
77 WifiMode payloadMode,
78 MHz_u channelWidth,
79 Time guardInterval,
80 WifiPreamble preamble,
81 Time knownDuration);
82
83 /**
84 * Check if the overall Tx duration returned by WifiPhy for a MU PPDU
85 * corresponds to a known value
86 *
87 * @param sizes the list of PSDU sizes for each station in octets
88 * @param userInfos the list of HE MU specific user transmission parameters
89 * @param channelWidth the channel width used for the transmission
90 * @param guardInterval the guard interval duration used for the transmission
91 * @param preamble the WifiPreamble used for the transmission
92 * @param knownDuration the known duration value of the transmission
93 *
94 * @return true if values correspond, false otherwise
95 */
96 static bool CheckMuTxDuration(std::list<uint32_t> sizes,
97 std::list<HeMuUserInfo> userInfos,
98 MHz_u channelWidth,
99 Time guardInterval,
100 WifiPreamble preamble,
101 Time knownDuration);
102
103 /**
104 * Calculate the overall Tx duration returned by WifiPhy for list of sizes.
105 * A map of WifiPsdu indexed by STA-ID is built using the provided lists
106 * and handed over to the corresponding SU/MU WifiPhy Tx duration computing
107 * method.
108 * Note that provided lists should be of same size.
109 *
110 * @param sizes the list of PSDU sizes for each station in octets
111 * @param staIds the list of STA-IDs of each station
112 * @param txVector the TXVECTOR used for the transmission of the PPDU
113 * @param band the selected wifi PHY band
114 *
115 * @return the overall Tx duration for the list of sizes (SU or MU PPDU)
116 */
117 static Time CalculateTxDurationUsingList(std::list<uint32_t> sizes,
118 std::list<uint16_t> staIds,
119 WifiTxVector txVector,
120 WifiPhyBand band);
121};
122
124 : TestCase("Wifi TX Duration")
125{
126}
127
131
132bool
134 WifiMode payloadMode,
135 MHz_u channelWidth,
136 Time guardInterval,
137 WifiPreamble preamble,
138 Time knownDuration)
139{
140 WifiTxVector txVector;
141 txVector.SetMode(payloadMode);
142 txVector.SetPreambleType(preamble);
143 txVector.SetChannelWidth(channelWidth);
144 txVector.SetGuardInterval(guardInterval);
145 txVector.SetNss(1);
146 txVector.SetStbc(false);
147 txVector.SetNess(0);
148 std::list<WifiPhyBand> testedBands;
150 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM)
151 {
152 testedBands.push_back(WIFI_PHY_BAND_5GHZ);
153 }
154 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_HE)
155 {
156 testedBands.push_back(WIFI_PHY_BAND_6GHZ);
157 }
158 if (payloadMode.GetModulationClass() != WIFI_MOD_CLASS_VHT)
159 {
160 testedBands.push_back(WIFI_PHY_BAND_2_4GHZ);
161 }
162 for (auto& testedBand : testedBands)
163 {
164 if ((testedBand == WIFI_PHY_BAND_2_4GHZ) &&
165 (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM))
166 {
167 knownDuration +=
168 MicroSeconds(6); // 2.4 GHz band should be at the end of the bands to test
169 }
170 Time calculatedDuration = YansWifiPhy::GetPayloadDuration(size, txVector, testedBand);
171 if (calculatedDuration != knownDuration)
172 {
173 std::cerr << "size=" << size << " band=" << testedBand << " mode=" << payloadMode
174 << " channelWidth=" << channelWidth << " guardInterval=" << guardInterval
175 << " datarate=" << payloadMode.GetDataRate(channelWidth, guardInterval, 1)
176 << " known=" << knownDuration << " calculated=" << calculatedDuration
177 << std::endl;
178 return false;
179 }
180 }
181 return true;
182}
183
184bool
186 WifiMode payloadMode,
187 MHz_u channelWidth,
188 Time guardInterval,
189 WifiPreamble preamble,
190 Time knownDuration)
191{
192 WifiTxVector txVector;
193 txVector.SetMode(payloadMode);
194 txVector.SetPreambleType(preamble);
195 txVector.SetChannelWidth(channelWidth);
196 txVector.SetGuardInterval(guardInterval);
197 txVector.SetNss(1);
198 txVector.SetStbc(false);
199 txVector.SetNess(0);
200 std::list<WifiPhyBand> testedBands;
202 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM)
203 {
204 testedBands.push_back(WIFI_PHY_BAND_5GHZ);
205 }
206 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_HE)
207 {
208 testedBands.push_back(WIFI_PHY_BAND_6GHZ);
209 }
210 if (payloadMode.GetModulationClass() != WIFI_MOD_CLASS_VHT)
211 {
212 testedBands.push_back(WIFI_PHY_BAND_2_4GHZ);
213 }
214 for (auto& testedBand : testedBands)
215 {
216 if ((testedBand == WIFI_PHY_BAND_2_4GHZ) &&
217 (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM))
218 {
219 knownDuration +=
220 MicroSeconds(6); // 2.4 GHz band should be at the end of the bands to test
221 }
222 Time calculatedDuration = YansWifiPhy::CalculateTxDuration(size, txVector, testedBand);
223 Time calculatedDurationUsingList =
224 CalculateTxDurationUsingList(std::list<uint32_t>{size},
225 std::list<uint16_t>{SU_STA_ID},
226 txVector,
227 testedBand);
228 if (calculatedDuration != knownDuration ||
229 calculatedDuration != calculatedDurationUsingList)
230 {
231 std::cerr << "size=" << size << " band=" << testedBand << " mode=" << payloadMode
232 << " channelWidth=" << +channelWidth << " guardInterval=" << guardInterval
233 << " datarate=" << payloadMode.GetDataRate(channelWidth, guardInterval, 1)
234 << " preamble=" << preamble << " known=" << knownDuration
235 << " calculated=" << calculatedDuration
236 << " calculatedUsingList=" << calculatedDurationUsingList << std::endl;
237 return false;
238 }
239 }
240 return true;
241}
242
243bool
244TxDurationTest::CheckMuTxDuration(std::list<uint32_t> sizes,
245 std::list<HeMuUserInfo> userInfos,
246 MHz_u channelWidth,
247 Time guardInterval,
248 WifiPreamble preamble,
249 Time knownDuration)
250{
251 NS_ASSERT(sizes.size() == userInfos.size() && sizes.size() > 1);
253 channelWidth < std::accumulate(
254 std::begin(userInfos),
255 std::end(userInfos),
256 MHz_u{0},
257 [](const MHz_u prevBw, const HeMuUserInfo& info) {
258 return prevBw + WifiRu::GetBandwidth(WifiRu::GetRuType(info.ru));
259 }),
260 "Cannot accommodate all the RUs in the provided band"); // MU-MIMO (for which allocations
261 // use the same RU) is not supported
262 WifiTxVector txVector;
263 txVector.SetPreambleType(preamble);
264 txVector.SetChannelWidth(channelWidth);
265 txVector.SetGuardInterval(guardInterval);
266 txVector.SetStbc(false);
267 txVector.SetNess(0);
268 if (IsEht(preamble))
269 {
270 txVector.SetEhtPpduType(0);
271 }
272 std::list<uint16_t> staIds;
273
274 uint16_t staId = 1;
275 for (const auto& userInfo : userInfos)
276 {
277 txVector.SetHeMuUserInfo(staId, userInfo);
278 staIds.push_back(staId++);
279 }
281 txVector.SetRuAllocation({192, 192}, 0);
282
284 std::list<WifiPhyBand> testedBands{
287 WIFI_PHY_BAND_2_4GHZ}; // Durations vary depending on frequency; test also 2.4 GHz (bug
288 // 1971)
289 for (auto& testedBand : testedBands)
290 {
291 if (testedBand == WIFI_PHY_BAND_2_4GHZ)
292 {
293 knownDuration +=
294 MicroSeconds(6); // 2.4 GHz band should be at the end of the bands to test
295 }
296 Time calculatedDuration;
297 uint32_t longestSize = 0;
298 auto iterStaId = staIds.begin();
299 for (auto& size : sizes)
300 {
301 Time ppduDurationForSta =
302 YansWifiPhy::CalculateTxDuration(size, txVector, testedBand, *iterStaId);
303 if (ppduDurationForSta > calculatedDuration)
304 {
305 calculatedDuration = ppduDurationForSta;
306 staId = *iterStaId;
307 longestSize = size;
308 }
309 ++iterStaId;
310 }
311 Time calculatedDurationUsingList =
312 CalculateTxDurationUsingList(sizes, staIds, txVector, testedBand);
313 if (calculatedDuration != knownDuration ||
314 calculatedDuration != calculatedDurationUsingList)
315 {
316 std::cerr << "size=" << longestSize << " band=" << testedBand << " staId=" << staId
317 << " nss=" << +txVector.GetNss(staId) << " mode=" << txVector.GetMode(staId)
318 << " channelWidth=" << channelWidth << " guardInterval=" << guardInterval
319 << " datarate="
320 << txVector.GetMode(staId).GetDataRate(channelWidth,
321 guardInterval,
322 txVector.GetNss(staId))
323 << " known=" << knownDuration << " calculated=" << calculatedDuration
324 << " calculatedUsingList=" << calculatedDurationUsingList << std::endl;
325 return false;
326 }
327 }
328 return true;
329}
330
331Time
333 std::list<uint16_t> staIds,
334 WifiTxVector txVector,
335 WifiPhyBand band)
336{
337 NS_ASSERT(sizes.size() == staIds.size());
338 WifiConstPsduMap psduMap;
339 auto itStaId = staIds.begin();
340 WifiMacHeader hdr;
341 hdr.SetType(WIFI_MAC_CTL_ACK); // so that size may not be empty while being as short as possible
342 for (auto& size : sizes)
343 {
344 // MAC header and FCS are to deduce from size
345 psduMap[*itStaId++] =
346 Create<WifiPsdu>(Create<Packet>(size - hdr.GetSerializedSize() - 4), hdr);
347 }
348 return WifiPhy::CalculateTxDuration(psduMap, txVector, band);
349}
350
351void
353{
354 bool retval = true;
355
356 // IEEE Std 802.11-2007 Table 18-2 "Example of LENGTH calculations for CCK"
357 retval = retval &&
360 MHz_u{22},
361 NanoSeconds(800),
363 MicroSeconds(744)) &&
366 MHz_u{22},
367 NanoSeconds(800),
369 MicroSeconds(745)) &&
372 MHz_u{22},
373 NanoSeconds(800),
375 MicroSeconds(746)) &&
378 MHz_u{22},
379 NanoSeconds(800),
381 MicroSeconds(747));
382
383 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11b CCK duration failed");
384
385 // Similar, but we add PHY preamble and header durations
386 // and we test different rates.
387 // The payload durations for modes other than 11mbb have been
388 // calculated by hand according to IEEE Std 802.11-2007 18.2.3.5
389 retval = retval &&
390 CheckTxDuration(1023,
392 MHz_u{22},
393 NanoSeconds(800),
395 MicroSeconds(744 + 96)) &&
396 CheckTxDuration(1024,
398 MHz_u{22},
399 NanoSeconds(800),
401 MicroSeconds(745 + 96)) &&
402 CheckTxDuration(1025,
404 MHz_u{22},
405 NanoSeconds(800),
407 MicroSeconds(746 + 96)) &&
408 CheckTxDuration(1026,
410 MHz_u{22},
411 NanoSeconds(800),
413 MicroSeconds(747 + 96)) &&
414 CheckTxDuration(1023,
416 MHz_u{22},
417 NanoSeconds(800),
419 MicroSeconds(744 + 192)) &&
420 CheckTxDuration(1024,
422 MHz_u{22},
423 NanoSeconds(800),
425 MicroSeconds(745 + 192)) &&
426 CheckTxDuration(1025,
428 MHz_u{22},
429 NanoSeconds(800),
431 MicroSeconds(746 + 192)) &&
432 CheckTxDuration(1026,
434 MHz_u{22},
435 NanoSeconds(800),
437 MicroSeconds(747 + 192)) &&
438 CheckTxDuration(1023,
440 MHz_u{22},
441 NanoSeconds(800),
443 MicroSeconds(1488 + 96)) &&
444 CheckTxDuration(1024,
446 MHz_u{22},
447 NanoSeconds(800),
449 MicroSeconds(1490 + 96)) &&
450 CheckTxDuration(1025,
452 MHz_u{22},
453 NanoSeconds(800),
455 MicroSeconds(1491 + 96)) &&
456 CheckTxDuration(1026,
458 MHz_u{22},
459 NanoSeconds(800),
461 MicroSeconds(1493 + 96)) &&
462 CheckTxDuration(1023,
464 MHz_u{22},
465 NanoSeconds(800),
467 MicroSeconds(1488 + 192)) &&
468 CheckTxDuration(1024,
470 MHz_u{22},
471 NanoSeconds(800),
473 MicroSeconds(1490 + 192)) &&
474 CheckTxDuration(1025,
476 MHz_u{22},
477 NanoSeconds(800),
479 MicroSeconds(1491 + 192)) &&
480 CheckTxDuration(1026,
482 MHz_u{22},
483 NanoSeconds(800),
485 MicroSeconds(1493 + 192)) &&
486 CheckTxDuration(1023,
488 MHz_u{22},
489 NanoSeconds(800),
491 MicroSeconds(4092 + 96)) &&
492 CheckTxDuration(1024,
494 MHz_u{22},
495 NanoSeconds(800),
497 MicroSeconds(4096 + 96)) &&
498 CheckTxDuration(1025,
500 MHz_u{22},
501 NanoSeconds(800),
503 MicroSeconds(4100 + 96)) &&
504 CheckTxDuration(1026,
506 MHz_u{22},
507 NanoSeconds(800),
509 MicroSeconds(4104 + 96)) &&
510 CheckTxDuration(1023,
512 MHz_u{22},
513 NanoSeconds(800),
515 MicroSeconds(4092 + 192)) &&
516 CheckTxDuration(1024,
518 MHz_u{22},
519 NanoSeconds(800),
521 MicroSeconds(4096 + 192)) &&
522 CheckTxDuration(1025,
524 MHz_u{22},
525 NanoSeconds(800),
527 MicroSeconds(4100 + 192)) &&
528 CheckTxDuration(1026,
530 MHz_u{22},
531 NanoSeconds(800),
533 MicroSeconds(4104 + 192)) &&
534 CheckTxDuration(1023,
536 MHz_u{22},
537 NanoSeconds(800),
539 MicroSeconds(8184 + 192)) &&
540 CheckTxDuration(1024,
542 MHz_u{22},
543 NanoSeconds(800),
545 MicroSeconds(8192 + 192)) &&
546 CheckTxDuration(1025,
548 MHz_u{22},
549 NanoSeconds(800),
551 MicroSeconds(8200 + 192)) &&
552 CheckTxDuration(1026,
554 MHz_u{22},
555 NanoSeconds(800),
557 MicroSeconds(8208 + 192)) &&
558 CheckTxDuration(1023,
560 MHz_u{22},
561 NanoSeconds(800),
563 MicroSeconds(8184 + 192)) &&
564 CheckTxDuration(1024,
566 MHz_u{22},
567 NanoSeconds(800),
569 MicroSeconds(8192 + 192)) &&
570 CheckTxDuration(1025,
572 MHz_u{22},
573 NanoSeconds(800),
575 MicroSeconds(8200 + 192)) &&
576 CheckTxDuration(1026,
578 MHz_u{22},
579 NanoSeconds(800),
581 MicroSeconds(8208 + 192));
582
583 // values from
584 // https://web.archive.org/web/20100711002639/http://mailman.isi.edu/pipermail/ns-developers/2009-July/006226.html
585 retval = retval && CheckTxDuration(14,
587 MHz_u{22},
588 NanoSeconds(800),
590 MicroSeconds(304));
591
592 // values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
593 retval = retval &&
594 CheckTxDuration(1536,
596 MHz_u{22},
597 NanoSeconds(800),
599 MicroSeconds(1310)) &&
602 MHz_u{22},
603 NanoSeconds(800),
605 MicroSeconds(248)) &&
608 MHz_u{22},
609 NanoSeconds(800),
611 MicroSeconds(203));
612
613 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11b duration failed");
614
615 // 802.11a durations
616 // values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
617 retval = retval &&
618 CheckTxDuration(1536,
620 MHz_u{20},
621 NanoSeconds(800),
623 MicroSeconds(248)) &&
626 MHz_u{20},
627 NanoSeconds(800),
629 MicroSeconds(32)) &&
632 MHz_u{20},
633 NanoSeconds(800),
635 MicroSeconds(24));
636
637 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11a duration failed");
638
639 // 802.11g durations are same as 802.11a durations but with 6 us signal extension
640 retval = retval &&
641 CheckTxDuration(1536,
643 MHz_u{20},
644 NanoSeconds(800),
646 MicroSeconds(254)) &&
649 MHz_u{20},
650 NanoSeconds(800),
652 MicroSeconds(38)) &&
655 MHz_u{20},
656 NanoSeconds(800),
658 MicroSeconds(30));
659
660 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11g duration failed");
661
662 // 802.11n durations
663 retval = retval &&
664 CheckTxDuration(1536,
666 MHz_u{20},
667 NanoSeconds(800),
669 MicroSeconds(228)) &&
672 MHz_u{20},
673 NanoSeconds(800),
675 MicroSeconds(48)) &&
678 MHz_u{20},
679 NanoSeconds(800),
681 MicroSeconds(40)) &&
682 CheckTxDuration(1536,
684 MHz_u{20},
685 NanoSeconds(400),
687 NanoSeconds(1742400)) &&
690 MHz_u{20},
691 NanoSeconds(400),
693 MicroSeconds(126)) &&
696 MHz_u{20},
697 NanoSeconds(400),
699 NanoSeconds(57600)) &&
700 CheckTxDuration(1536,
702 MHz_u{20},
703 NanoSeconds(400),
705 NanoSeconds(226800)) &&
708 MHz_u{20},
709 NanoSeconds(400),
711 NanoSeconds(46800)) &&
714 MHz_u{20},
715 NanoSeconds(400),
717 NanoSeconds(39600)) &&
718 CheckTxDuration(1536,
720 MHz_u{40},
721 NanoSeconds(800),
723 MicroSeconds(128)) &&
726 MHz_u{40},
727 NanoSeconds(800),
729 MicroSeconds(44)) &&
732 MHz_u{40},
733 NanoSeconds(800),
735 MicroSeconds(40)) &&
736 CheckTxDuration(1536,
738 MHz_u{40},
739 NanoSeconds(400),
741 NanoSeconds(118800)) &&
744 MHz_u{40},
745 NanoSeconds(400),
747 NanoSeconds(43200)) &&
750 MHz_u{40},
751 NanoSeconds(400),
753 NanoSeconds(39600));
754
755 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11n duration failed");
756
757 // 802.11ac durations
758 retval = retval &&
759 CheckTxDuration(1536,
761 MHz_u{20},
762 NanoSeconds(800),
764 MicroSeconds(196)) &&
767 MHz_u{20},
768 NanoSeconds(800),
770 MicroSeconds(48)) &&
773 MHz_u{20},
774 NanoSeconds(800),
776 MicroSeconds(40)) &&
777 CheckTxDuration(1536,
779 MHz_u{20},
780 NanoSeconds(400),
782 MicroSeconds(180)) &&
785 MHz_u{20},
786 NanoSeconds(400),
788 NanoSeconds(46800)) &&
791 MHz_u{20},
792 NanoSeconds(400),
794 NanoSeconds(39600)) &&
795 CheckTxDuration(1536,
797 MHz_u{40},
798 NanoSeconds(800),
800 MicroSeconds(108)) &&
803 MHz_u{40},
804 NanoSeconds(800),
806 MicroSeconds(40)) &&
809 MHz_u{40},
810 NanoSeconds(800),
812 MicroSeconds(40)) &&
813 CheckTxDuration(1536,
815 MHz_u{40},
816 NanoSeconds(400),
818 NanoSeconds(100800)) &&
821 MHz_u{40},
822 NanoSeconds(400),
824 NanoSeconds(39600)) &&
827 MHz_u{40},
828 NanoSeconds(400),
830 NanoSeconds(39600)) &&
831 CheckTxDuration(1536,
833 MHz_u{80},
834 NanoSeconds(800),
836 MicroSeconds(460)) &&
839 MHz_u{80},
840 NanoSeconds(800),
842 MicroSeconds(60)) &&
845 MHz_u{80},
846 NanoSeconds(800),
848 MicroSeconds(44)) &&
849 CheckTxDuration(1536,
851 MHz_u{80},
852 NanoSeconds(400),
854 NanoSeconds(417600)) &&
857 MHz_u{80},
858 NanoSeconds(400),
860 NanoSeconds(57600)) &&
863 MHz_u{80},
864 NanoSeconds(400),
866 NanoSeconds(43200)) &&
867 CheckTxDuration(1536,
869 MHz_u{80},
870 NanoSeconds(800),
872 MicroSeconds(68)) &&
875 MHz_u{80},
876 NanoSeconds(800),
878 MicroSeconds(40)) &&
881 MHz_u{80},
882 NanoSeconds(800),
884 MicroSeconds(40)) &&
885 CheckTxDuration(1536,
887 MHz_u{80},
888 NanoSeconds(400),
890 NanoSeconds(64800)) &&
893 MHz_u{80},
894 NanoSeconds(400),
896 NanoSeconds(39600)) &&
899 MHz_u{80},
900 NanoSeconds(400),
902 NanoSeconds(39600)) &&
903 CheckTxDuration(1536,
905 MHz_u{160},
906 NanoSeconds(800),
908 MicroSeconds(56)) &&
911 MHz_u{160},
912 NanoSeconds(800),
914 MicroSeconds(40)) &&
917 MHz_u{160},
918 NanoSeconds(800),
920 MicroSeconds(40)) &&
921 CheckTxDuration(1536,
923 MHz_u{160},
924 NanoSeconds(400),
926 MicroSeconds(54)) &&
929 MHz_u{160},
930 NanoSeconds(400),
932 NanoSeconds(39600)) &&
935 MHz_u{160},
936 NanoSeconds(400),
938 NanoSeconds(39600));
939
940 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11ac duration failed");
941
942 // 802.11ax SU durations
943 retval = retval &&
944 CheckTxDuration(1536,
946 MHz_u{20},
947 NanoSeconds(800),
949 NanoSeconds(1485600)) &&
952 MHz_u{20},
953 NanoSeconds(800),
955 NanoSeconds(125600)) &&
958 MHz_u{20},
959 NanoSeconds(800),
961 NanoSeconds(71200)) &&
962 CheckTxDuration(1536,
964 MHz_u{40},
965 NanoSeconds(800),
967 NanoSeconds(764800)) &&
970 MHz_u{40},
971 NanoSeconds(800),
973 NanoSeconds(84800)) &&
976 MHz_u{40},
977 NanoSeconds(800),
979 NanoSeconds(57600)) &&
980 CheckTxDuration(1536,
982 MHz_u{80},
983 NanoSeconds(800),
985 NanoSeconds(397600)) &&
988 MHz_u{80},
989 NanoSeconds(800),
991 NanoSeconds(71200)) &&
994 MHz_u{80},
995 NanoSeconds(800),
997 NanoSeconds(57600)) &&
998 CheckTxDuration(1536,
1000 MHz_u{160},
1001 NanoSeconds(800),
1003 NanoSeconds(220800)) &&
1004 CheckTxDuration(76,
1006 MHz_u{160},
1007 NanoSeconds(800),
1009 NanoSeconds(57600)) &&
1010 CheckTxDuration(14,
1012 MHz_u{160},
1013 NanoSeconds(800),
1015 NanoSeconds(57600)) &&
1016 CheckTxDuration(1536,
1018 MHz_u{20},
1019 NanoSeconds(1600),
1021 NanoSeconds(1570400)) &&
1022 CheckTxDuration(76,
1024 MHz_u{20},
1025 NanoSeconds(1600),
1027 NanoSeconds(130400)) &&
1028 CheckTxDuration(14,
1030 MHz_u{20},
1031 NanoSeconds(1600),
1033 NanoSeconds(72800)) &&
1034 CheckTxDuration(1536,
1036 MHz_u{40},
1037 NanoSeconds(1600),
1039 NanoSeconds(807200)) &&
1040 CheckTxDuration(76,
1042 MHz_u{40},
1043 NanoSeconds(1600),
1045 NanoSeconds(87200)) &&
1046 CheckTxDuration(14,
1048 MHz_u{40},
1049 NanoSeconds(1600),
1051 NanoSeconds(58400)) &&
1052 CheckTxDuration(1536,
1054 MHz_u{80},
1055 NanoSeconds(1600),
1057 NanoSeconds(418400)) &&
1058 CheckTxDuration(76,
1060 MHz_u{80},
1061 NanoSeconds(1600),
1063 NanoSeconds(72800)) &&
1064 CheckTxDuration(14,
1066 MHz_u{80},
1067 NanoSeconds(1600),
1069 NanoSeconds(58400)) &&
1070 CheckTxDuration(1536,
1072 MHz_u{160},
1073 NanoSeconds(1600),
1075 NanoSeconds(231200)) &&
1076 CheckTxDuration(76,
1078 MHz_u{160},
1079 NanoSeconds(1600),
1081 NanoSeconds(58400)) &&
1082 CheckTxDuration(14,
1084 MHz_u{160},
1085 NanoSeconds(1600),
1087 NanoSeconds(58400)) &&
1088 CheckTxDuration(1536,
1090 MHz_u{20},
1091 NanoSeconds(3200),
1093 MicroSeconds(1740)) &&
1094 CheckTxDuration(76,
1096 MHz_u{20},
1097 NanoSeconds(3200),
1099 MicroSeconds(140)) &&
1100 CheckTxDuration(14,
1102 MHz_u{20},
1103 NanoSeconds(3200),
1105 MicroSeconds(76)) &&
1106 CheckTxDuration(1536,
1108 MHz_u{40},
1109 NanoSeconds(3200),
1111 MicroSeconds(892)) &&
1112 CheckTxDuration(76,
1114 MHz_u{40},
1115 NanoSeconds(3200),
1117 MicroSeconds(92)) &&
1118 CheckTxDuration(14,
1120 MHz_u{40},
1121 NanoSeconds(3200),
1123 MicroSeconds(60)) &&
1124 CheckTxDuration(1536,
1126 MHz_u{80},
1127 NanoSeconds(3200),
1129 MicroSeconds(460)) &&
1130 CheckTxDuration(76,
1132 MHz_u{80},
1133 NanoSeconds(3200),
1135 MicroSeconds(76)) &&
1136 CheckTxDuration(14,
1138 MHz_u{80},
1139 NanoSeconds(3200),
1141 MicroSeconds(60)) &&
1142 CheckTxDuration(1536,
1144 MHz_u{160},
1145 NanoSeconds(3200),
1147 MicroSeconds(252)) &&
1148 CheckTxDuration(76,
1150 MHz_u{160},
1151 NanoSeconds(3200),
1153 MicroSeconds(60)) &&
1154 CheckTxDuration(14,
1156 MHz_u{160},
1157 NanoSeconds(3200),
1159 MicroSeconds(60)) &&
1160 CheckTxDuration(1536,
1162 MHz_u{20},
1163 NanoSeconds(800),
1165 NanoSeconds(139200)) &&
1166 CheckTxDuration(76,
1168 MHz_u{20},
1169 NanoSeconds(800),
1171 NanoSeconds(57600)) &&
1172 CheckTxDuration(14,
1174 MHz_u{20},
1175 NanoSeconds(800),
1177 NanoSeconds(57600)) &&
1178 CheckTxDuration(1536,
1180 MHz_u{40},
1181 NanoSeconds(800),
1183 NanoSeconds(98400)) &&
1184 CheckTxDuration(76,
1186 MHz_u{40},
1187 NanoSeconds(800),
1189 NanoSeconds(57600)) &&
1190 CheckTxDuration(14,
1192 MHz_u{40},
1193 NanoSeconds(800),
1195 NanoSeconds(57600)) &&
1196 CheckTxDuration(1536,
1198 MHz_u{80},
1199 NanoSeconds(800),
1201 NanoSeconds(71200)) &&
1202 CheckTxDuration(76,
1204 MHz_u{80},
1205 NanoSeconds(800),
1207 NanoSeconds(57600)) &&
1208 CheckTxDuration(14,
1210 MHz_u{80},
1211 NanoSeconds(800),
1213 NanoSeconds(57600)) &&
1214 CheckTxDuration(1536,
1216 MHz_u{160},
1217 NanoSeconds(800),
1219 NanoSeconds(57600)) &&
1220 CheckTxDuration(76,
1222 MHz_u{160},
1223 NanoSeconds(800),
1225 NanoSeconds(57600)) &&
1226 CheckTxDuration(14,
1228 MHz_u{160},
1229 NanoSeconds(800),
1231 NanoSeconds(57600)) &&
1232 CheckTxDuration(1536,
1234 MHz_u{20},
1235 NanoSeconds(1600),
1237 NanoSeconds(144800)) &&
1238 CheckTxDuration(76,
1240 MHz_u{20},
1241 NanoSeconds(1600),
1243 NanoSeconds(58400)) &&
1244 CheckTxDuration(14,
1246 MHz_u{20},
1247 NanoSeconds(1600),
1249 NanoSeconds(58400)) &&
1250 CheckTxDuration(1536,
1252 MHz_u{40},
1253 NanoSeconds(1600),
1255 NanoSeconds(101600)) &&
1256 CheckTxDuration(76,
1258 MHz_u{40},
1259 NanoSeconds(1600),
1261 NanoSeconds(58400)) &&
1262 CheckTxDuration(14,
1264 MHz_u{40},
1265 NanoSeconds(1600),
1267 NanoSeconds(58400)) &&
1268 CheckTxDuration(1536,
1270 MHz_u{80},
1271 NanoSeconds(1600),
1273 NanoSeconds(72800)) &&
1274 CheckTxDuration(76,
1276 MHz_u{80},
1277 NanoSeconds(1600),
1279 NanoSeconds(58400)) &&
1280 CheckTxDuration(14,
1282 MHz_u{80},
1283 NanoSeconds(1600),
1285 NanoSeconds(58400)) &&
1286 CheckTxDuration(1536,
1288 MHz_u{160},
1289 NanoSeconds(1600),
1291 NanoSeconds(58400)) &&
1292 CheckTxDuration(76,
1294 MHz_u{160},
1295 NanoSeconds(1600),
1297 NanoSeconds(58400)) &&
1298 CheckTxDuration(14,
1300 MHz_u{160},
1301 NanoSeconds(1600),
1303 NanoSeconds(58400)) &&
1304 CheckTxDuration(1536,
1306 MHz_u{20},
1307 NanoSeconds(3200),
1309 MicroSeconds(156)) &&
1310 CheckTxDuration(76,
1312 MHz_u{20},
1313 NanoSeconds(3200),
1315 MicroSeconds(60)) &&
1316 CheckTxDuration(14,
1318 MHz_u{20},
1319 NanoSeconds(3200),
1321 MicroSeconds(60)) &&
1322 CheckTxDuration(1536,
1324 MHz_u{40},
1325 NanoSeconds(3200),
1327 MicroSeconds(108)) &&
1328 CheckTxDuration(76,
1330 MHz_u{40},
1331 NanoSeconds(3200),
1333 MicroSeconds(60)) &&
1334 CheckTxDuration(14,
1336 MHz_u{40},
1337 NanoSeconds(3200),
1339 MicroSeconds(60)) &&
1340 CheckTxDuration(1536,
1342 MHz_u{80},
1343 NanoSeconds(3200),
1345 MicroSeconds(76)) &&
1346 CheckTxDuration(76,
1348 MHz_u{80},
1349 NanoSeconds(3200),
1351 MicroSeconds(60)) &&
1352 CheckTxDuration(14,
1354 MHz_u{80},
1355 NanoSeconds(3200),
1357 MicroSeconds(60)) &&
1358 CheckTxDuration(1536,
1360 MHz_u{160},
1361 NanoSeconds(3200),
1363 MicroSeconds(60)) &&
1364 CheckTxDuration(76,
1366 MHz_u{160},
1367 NanoSeconds(3200),
1369 MicroSeconds(60)) &&
1370 CheckTxDuration(14,
1372 MHz_u{160},
1373 NanoSeconds(3200),
1375 MicroSeconds(60));
1376
1377 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11ax SU duration failed");
1378
1379 // 802.11ax MU durations
1380 retval = retval &&
1382 std::list<uint32_t>{1536, 1536},
1383 std::list<HeMuUserInfo>{{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 0, 1},
1384 {HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 0, 1}},
1385 MHz_u{40},
1386 NanoSeconds(800),
1389 1493600)) // equivalent to HE_SU for 20 MHz with 2 extra HE-SIG-B (i.e. 8 us)
1391 std::list<uint32_t>{1536, 1536},
1392 std::list<HeMuUserInfo>{{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 1, 1},
1393 {HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 0, 1}},
1394 MHz_u{40},
1395 NanoSeconds(800),
1397 NanoSeconds(1493600)) // shouldn't change if first PSDU is shorter
1399 std::list<uint32_t>{1536, 76},
1400 std::list<HeMuUserInfo>{{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 0, 1},
1401 {HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 0, 1}},
1402 MHz_u{40},
1403 NanoSeconds(800),
1405 NanoSeconds(1493600));
1406
1407 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11ax MU duration failed");
1408
1409 // 802.11be MU durations
1410 retval = retval &&
1412 std::list<uint32_t>{1536, 1536},
1413 std::list<HeMuUserInfo>{{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 0, 1},
1414 {HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 0, 1}},
1415 MHz_u{40},
1416 NanoSeconds(800),
1418 NanoSeconds(1493600)) // equivalent to 802.11ax MU
1420 std::list<uint32_t>{1536, 1536},
1421 std::list<HeMuUserInfo>{{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 1, 1},
1422 {HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 0, 1}},
1423 MHz_u{40},
1424 NanoSeconds(800),
1426 NanoSeconds(1493600)) // shouldn't change if first PSDU is shorter
1428 std::list<uint32_t>{1536, 76},
1429 std::list<HeMuUserInfo>{{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 0, 1},
1430 {HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 0, 1}},
1431 MHz_u{40},
1432 NanoSeconds(800),
1434 NanoSeconds(1493600));
1435
1436 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11be MU duration failed");
1437
1439}
1440
1441/**
1442 * @ingroup wifi-test
1443 * @ingroup tests
1444 *
1445 * @brief HE-SIG-B duration test
1446 */
1448{
1449 public:
1450 /**
1451 * OFDMA or MU-MIMO
1452 */
1454 {
1456 MU_MIMO
1458
1459 /**
1460 * Constructor
1461 *
1462 * @param userInfos the HE MU specific per-user information to use for the test
1463 * @param sigBMode the mode to transmit HE-SIG-B for the test
1464 * @param channelWidth the channel width to select for the test
1465 * @param p20Index the index of the primary20 channel
1466 * @param expectedMuType the expected MU type (OFDMA or MU-MIMO)
1467 * @param expectedRuAllocation the expected RuType::RU_ALLOCATION
1468 * @param expectedNumUsersPerCc the expected number of users per content channel
1469 * @param expectedSigBDuration the expected duration of the HE-SIG-B header
1470 */
1471 HeSigBDurationTest(const std::list<HeMuUserInfo>& userInfos,
1472 const WifiMode& sigBMode,
1473 MHz_u channelWidth,
1474 uint8_t p20Index,
1475 MuType expectedMuType,
1476 const RuAllocation& expectedRuAllocation,
1477 const std::pair<std::size_t, std::size_t>& expectedNumUsersPerCc,
1478 Time expectedSigBDuration);
1479
1480 private:
1481 void DoRun() override;
1482 void DoTeardown() override;
1483
1484 /**
1485 * Build a TXVECTOR for HE MU.
1486 *
1487 * @return the configured HE MU TXVECTOR
1488 */
1490
1491 Ptr<YansWifiPhy> m_phy; ///< the PHY under test
1492
1493 std::list<HeMuUserInfo> m_userInfos; ///< HE MU specific per-user information
1494 WifiMode m_sigBMode; ///< Mode used to transmit HE-SIG-B
1495 MHz_u m_channelWidth; ///< Channel width
1496 uint8_t m_p20Index; ///< index of the primary20 channel
1497 MuType m_expectedMuType; ///< Expected MU type (OFDMA or MU-MIMO)
1498 RuAllocation m_expectedRuAllocation; ///< Expected RuType::RU_ALLOCATION
1499 std::pair<std::size_t, std::size_t>
1500 m_expectedNumUsersPerCc; ///< Expected number of users per content channel
1501 Time m_expectedSigBDuration; ///< Expected duration of the HE-SIG-B header
1502};
1503
1505 const std::list<HeMuUserInfo>& userInfos,
1506 const WifiMode& sigBMode,
1507 MHz_u channelWidth,
1508 uint8_t p20Index,
1509 MuType expectedMuType,
1510 const RuAllocation& expectedRuAllocation,
1511 const std::pair<std::size_t, std::size_t>& expectedNumUsersPerCc,
1512 Time expectedSigBDuration)
1513 : TestCase{"Check HE-SIG-B duration computation"},
1514 m_userInfos{userInfos},
1515 m_sigBMode{sigBMode},
1516 m_channelWidth{channelWidth},
1517 m_p20Index{p20Index},
1518 m_expectedMuType{expectedMuType},
1519 m_expectedRuAllocation{expectedRuAllocation},
1520 m_expectedNumUsersPerCc{expectedNumUsersPerCc},
1521 m_expectedSigBDuration{expectedSigBDuration}
1522{
1523}
1524
1527{
1528 WifiTxVector txVector;
1531 txVector.SetGuardInterval(NanoSeconds(3200));
1532 txVector.SetStbc(false);
1533 txVector.SetNess(0);
1534 std::list<uint16_t> staIds;
1535 uint16_t staId = 1;
1536 for (const auto& userInfo : m_userInfos)
1537 {
1538 txVector.SetHeMuUserInfo(staId, userInfo);
1539 staIds.push_back(staId++);
1540 }
1541 txVector.SetSigBMode(m_sigBMode);
1542 NS_ASSERT(m_expectedMuType == OFDMA ? txVector.IsDlOfdma() : txVector.IsDlMuMimo());
1543 return txVector;
1544}
1545
1546void
1548{
1550 auto channelNum = WifiPhyOperatingChannel::FindFirst(0,
1551 MHz_u{0},
1552 MHz_u{160},
1555 ->number;
1559
1560 const auto& txVector = BuildTxVector();
1561 const auto& hePhy = m_phy->GetPhyEntity(WIFI_MOD_CLASS_HE);
1562
1563 // Verify mode for HE-SIG-B field
1564 NS_TEST_EXPECT_MSG_EQ(hePhy->GetSigMode(WIFI_PPDU_FIELD_SIG_B, txVector),
1565 m_sigBMode,
1566 "Incorrect mode used to send HE-SIG-B");
1567
1568 // Verify RuType::RU_ALLOCATION in TXVECTOR
1569 NS_TEST_EXPECT_MSG_EQ((txVector.GetRuAllocation(0) == m_expectedRuAllocation),
1570 true,
1571 "Incorrect RuType::RU_ALLOCATION");
1572
1573 // Verify number of users for content channels 1 and 2
1574 const auto& numUsersPerCc = HePpdu::GetNumRusPerHeSigBContentChannel(
1575 txVector.GetChannelWidth(),
1576 txVector.GetRuAllocation(m_p20Index),
1577 txVector.GetCenter26ToneRuIndication(),
1578 txVector.IsSigBCompression(),
1579 txVector.IsSigBCompression() ? txVector.GetHeMuUserInfoMap().size() : 0);
1580 const auto contentChannels = HePpdu::GetHeSigBContentChannels(txVector, 0);
1581 NS_TEST_EXPECT_MSG_EQ(numUsersPerCc.first,
1583 "Incorrect number of users in HE-SIG-B content channel 1");
1584 NS_TEST_EXPECT_MSG_EQ(numUsersPerCc.second,
1586 "Incorrect number of users in HE-SIG-B content channel 2");
1587 NS_TEST_EXPECT_MSG_EQ(contentChannels.at(0).size(),
1589 "Incorrect number of users in HE-SIG-B content channel 1");
1590 NS_TEST_EXPECT_MSG_EQ((contentChannels.size() > 1 ? contentChannels.at(1).size() : 0),
1592 "Incorrect number of users in HE-SIG-B content channel 2");
1593
1594 // Verify total HE-SIG-B duration
1595 NS_TEST_EXPECT_MSG_EQ(hePhy->GetDuration(WIFI_PPDU_FIELD_SIG_B, txVector),
1597 "Incorrect duration for HE-SIG-B");
1598
1599 // Verify user infos in reconstructed TX vector
1600 WifiConstPsduMap psdus;
1601 Time ppduDuration;
1602 for (std::size_t i = 0; i < m_userInfos.size(); ++i)
1603 {
1604 WifiMacHeader hdr;
1605 auto psdu = Create<WifiPsdu>(Create<Packet>(1000), hdr);
1606 ppduDuration = std::max(
1607 ppduDuration,
1608 WifiPhy::CalculateTxDuration(psdu->GetSize(), txVector, m_phy->GetPhyBand(), i + 1));
1609 psdus.insert(std::make_pair(i, psdu));
1610 }
1611 auto ppdu = hePhy->BuildPpdu(psdus, txVector, ppduDuration);
1612 ppdu->ResetTxVector();
1613 const auto& rxVector = ppdu->GetTxVector();
1614 NS_TEST_EXPECT_MSG_EQ((txVector.GetHeMuUserInfoMap() == rxVector.GetHeMuUserInfoMap()),
1615 true,
1616 "Incorrect user infos in reconstructed TXVECTOR");
1617
1619}
1620
1621void
1623{
1624 m_phy->Dispose();
1625 m_phy = nullptr;
1626}
1627
1628/**
1629 * @ingroup wifi-test
1630 * @ingroup tests
1631 *
1632 * @brief PHY header sections consistency test
1633 */
1635{
1636 public:
1638 ~PhyHeaderSectionsTest() override;
1639 void DoRun() override;
1640
1641 private:
1642 /**
1643 * Check if map of PHY header sections returned by a given PHY entity
1644 * corresponds to a known value
1645 *
1646 * @param obtained the map of PHY header sections to check
1647 * @param expected the expected map of PHY header sections
1648 */
1651};
1652
1654 : TestCase("PHY header sections consistency")
1655{
1656}
1657
1661
1662void
1665{
1666 NS_ASSERT_MSG(obtained.size() == expected.size(),
1667 "The expected map size (" << expected.size() << ") was not obtained ("
1668 << obtained.size() << ")");
1669
1670 auto itObtained = obtained.begin();
1671 auto itExpected = expected.begin();
1672 for (; itObtained != obtained.end() || itExpected != expected.end();)
1673 {
1674 WifiPpduField field = itObtained->first;
1675 auto window = itObtained->second.first;
1676 auto mode = itObtained->second.second;
1677
1678 WifiPpduField fieldRef = itExpected->first;
1679 auto windowRef = itExpected->second.first;
1680 auto modeRef = itExpected->second.second;
1681
1683 fieldRef,
1684 "The expected PPDU field (" << fieldRef << ") was not obtained ("
1685 << field << ")");
1686 NS_TEST_EXPECT_MSG_EQ(window.first,
1687 windowRef.first,
1688 "The expected start time (" << windowRef.first
1689 << ") was not obtained (" << window.first
1690 << ")");
1691 NS_TEST_EXPECT_MSG_EQ(window.second,
1692 windowRef.second,
1693 "The expected stop time (" << windowRef.second
1694 << ") was not obtained (" << window.second
1695 << ")");
1697 modeRef,
1698 "The expected mode (" << modeRef << ") was not obtained (" << mode
1699 << ")");
1700 ++itObtained;
1701 ++itExpected;
1702 }
1703}
1704
1705void
1707{
1708 Time ppduStart = Seconds(1);
1709 Ptr<PhyEntity> phyEntity;
1711 WifiTxVector txVector;
1712 WifiMode nonHtMode;
1713
1714 // ==================================================================================
1715 // 11b (HR/DSSS)
1716 phyEntity = Create<DsssPhy>();
1718 txVector.SetChannelWidth(MHz_u{22});
1719
1720 // -> long PPDU format
1722 nonHtMode = DsssPhy::GetDsssRate1Mbps();
1723 sections = {
1724 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(144)}, nonHtMode}},
1726 {{ppduStart + MicroSeconds(144), ppduStart + MicroSeconds(192)}, nonHtMode}},
1727 };
1728 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1729
1730 // -> long PPDU format if data rate is 1 Mbps (even if preamble is tagged short)
1732 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1733
1734 // -> short PPDU format
1736 nonHtMode = DsssPhy::GetDsssRate2Mbps();
1738 sections = {
1739 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(72)}, nonHtMode}},
1741 {{ppduStart + MicroSeconds(72), ppduStart + MicroSeconds(96)}, nonHtMode}},
1742 };
1743 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1744
1745 // ==================================================================================
1746 // 11a (OFDM)
1748
1749 // -> one iteration per variant: default, 10 MHz, and 5 MHz
1750 std::map<OfdmPhyVariant, std::size_t> variants{
1751 // number to use to deduce rate and BW info for each variant
1752 {OFDM_PHY_DEFAULT, 1},
1753 {OFDM_PHY_10_MHZ, 2},
1754 {OFDM_PHY_5_MHZ, 4},
1755 };
1756 for (auto variant : variants)
1757 {
1758 phyEntity = Create<OfdmPhy>(variant.first);
1759 std::size_t ratio = variant.second;
1760 const auto bw = MHz_u{20} / ratio;
1761 txVector.SetChannelWidth(bw);
1762 txVector.SetMode(OfdmPhy::GetOfdmRate(12000000 / ratio, bw));
1763 nonHtMode = OfdmPhy::GetOfdmRate(6000000 / ratio, bw);
1764 sections = {
1766 {{ppduStart, ppduStart + MicroSeconds(16 * ratio)}, nonHtMode}},
1768 {{ppduStart + MicroSeconds(16 * ratio), ppduStart + MicroSeconds(20 * ratio)},
1769 nonHtMode}},
1770 };
1771 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1772 }
1773
1774 // ==================================================================================
1775 // 11g (ERP-OFDM)
1776 phyEntity = Create<ErpOfdmPhy>();
1777 txVector.SetChannelWidth(MHz_u{20});
1778 txVector.SetMode(ErpOfdmPhy::GetErpOfdmRate(54000000));
1779 nonHtMode = ErpOfdmPhy::GetErpOfdmRate6Mbps();
1780 sections = {
1781 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
1783 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(20)}, nonHtMode}},
1784 };
1785 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1786
1787 // ==================================================================================
1788 // 11n (HT)
1789 phyEntity = Create<HtPhy>(4);
1790 txVector.SetChannelWidth(MHz_u{20});
1791 txVector.SetMode(HtPhy::GetHtMcs6());
1792 nonHtMode = OfdmPhy::GetOfdmRate6Mbps();
1793 WifiMode htSigMode = nonHtMode;
1794
1795 // -> HT-mixed format for 2 SS and no ESS
1797 txVector.SetNss(2);
1798 txVector.SetNess(0);
1799 sections = {
1800 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
1802 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(20)}, nonHtMode}},
1804 {{ppduStart + MicroSeconds(20), ppduStart + MicroSeconds(28)}, htSigMode}},
1806 {{ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(40)}, // 1 HT-STF + 2 HT-LTFs
1807 htSigMode}},
1808 };
1809 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1810 txVector.SetChannelWidth(MHz_u{20}); // shouldn't have any impact
1811 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1812
1813 // -> HT-mixed format for 3 SS and 1 ESS
1814 txVector.SetNss(3);
1815 txVector.SetNess(1);
1816 sections[WIFI_PPDU_FIELD_TRAINING] = {
1817 {ppduStart + MicroSeconds(28),
1818 ppduStart + MicroSeconds(52)}, // 1 HT-STF + 5 HT-LTFs (4 data + 1 extension)
1819 htSigMode};
1820 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1821
1822 // ==================================================================================
1823 // 11ac (VHT)
1824 phyEntity = Create<VhtPhy>();
1825 txVector.SetChannelWidth(MHz_u{20});
1826 txVector.SetNess(0);
1827 txVector.SetMode(VhtPhy::GetVhtMcs7());
1828 WifiMode sigAMode = nonHtMode;
1829 WifiMode sigBMode = VhtPhy::GetVhtMcs0();
1830
1831 // -> VHT SU format for 5 SS
1833 txVector.SetNss(5);
1834 sections = {
1835 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
1837 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(20)}, nonHtMode}},
1839 {{ppduStart + MicroSeconds(20), ppduStart + MicroSeconds(28)}, sigAMode}},
1841 {{ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(56)}, // 1 VHT-STF + 6 VHT-LTFs
1842 sigAMode}},
1843 };
1844 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1845
1846 // -> VHT SU format for 7 SS
1847 txVector.SetNss(7);
1848 sections[WIFI_PPDU_FIELD_TRAINING] = {
1849 {ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(64)}, // 1 VHT-STF + 8 VHT-LTFs
1850 sigAMode};
1851 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1852
1853 // -> VHT MU format for 3 SS
1855 txVector.SetNss(3);
1856 sections[WIFI_PPDU_FIELD_TRAINING] = {
1857 {ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(48)}, // 1 VHT-STF + 4 VHT-LTFs
1858 sigAMode};
1859 sections[WIFI_PPDU_FIELD_SIG_B] = {{ppduStart + MicroSeconds(48), ppduStart + MicroSeconds(52)},
1860 sigBMode};
1861 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1862 txVector.SetChannelWidth(MHz_u{80}); // shouldn't have any impact
1863 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1864
1865 // ==================================================================================
1866 // 11ax (HE)
1867 phyEntity = Create<HePhy>();
1868 txVector.SetChannelWidth(MHz_u{20});
1869 txVector.SetNss(2); // HE-LTF duration assumed to be always 8 us for the time being (see note in
1870 // HePhy::GetTrainingDuration)
1871 txVector.SetMode(HePhy::GetHeMcs9());
1872 std::map<uint16_t, HeMuUserInfo> userInfoMap = {
1873 {1, {HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 4, 2}},
1874 {2, {HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 9, 1}}};
1875 sigAMode = HePhy::GetVhtMcs0();
1876 sigBMode = HePhy::GetVhtMcs4(); // because of first user info map
1877
1878 // -> HE SU format
1880 sections = {
1881 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
1883 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(24)}, // L-SIG + RL-SIG
1884 nonHtMode}},
1886 {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)}, sigAMode}},
1888 {{ppduStart + MicroSeconds(32),
1889 ppduStart + MicroSeconds(52)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
1890 sigAMode}},
1891 };
1892 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1893
1894 // -> HE ER SU format
1896 sections[WIFI_PPDU_FIELD_SIG_A] = {
1897 {ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(40)}, // 16 us HE-SIG-A
1898 sigAMode};
1899 sections[WIFI_PPDU_FIELD_TRAINING] = {
1900 {ppduStart + MicroSeconds(40),
1901 ppduStart + MicroSeconds(60)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
1902 sigAMode};
1903 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1904
1905 // -> HE TB format
1907 txVector.SetHeMuUserInfo(1, userInfoMap.at(1));
1908 txVector.SetHeMuUserInfo(2, userInfoMap.at(2));
1909 sections[WIFI_PPDU_FIELD_SIG_A] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
1910 sigAMode};
1911 sections[WIFI_PPDU_FIELD_TRAINING] = {
1912 {ppduStart + MicroSeconds(32),
1913 ppduStart + MicroSeconds(56)}, // 1 HE-STF (@ 8 us) + 2 HE-LTFs (@ 8 us)
1914 sigAMode};
1915 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1916
1917 // -> HE MU format
1919 txVector.SetSigBMode(sigBMode);
1920 txVector.SetRuAllocation({96}, 0);
1921 sections[WIFI_PPDU_FIELD_SIG_A] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
1922 sigAMode};
1923 sections[WIFI_PPDU_FIELD_SIG_B] = {
1924 {ppduStart + MicroSeconds(32), ppduStart + MicroSeconds(36)}, // only one symbol
1925 sigBMode};
1926 sections[WIFI_PPDU_FIELD_TRAINING] = {
1927 {ppduStart + MicroSeconds(36),
1928 ppduStart + MicroSeconds(56)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
1929 sigBMode};
1930 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1931 txVector.SetChannelWidth(MHz_u{160}); // shouldn't have any impact
1932 txVector.SetRuAllocation({96, 113, 113, 113, 113, 113, 113, 113}, 0);
1933
1934 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1935
1936 // ==================================================================================
1937 // 11be (EHT)
1938 sections.erase(WIFI_PPDU_FIELD_SIG_A); // FIXME: do we keep using separate type for 11be?
1939 sections.erase(WIFI_PPDU_FIELD_SIG_B); // FIXME: do we keep using separate type for 11be?
1940 phyEntity = Create<EhtPhy>();
1941 txVector.SetChannelWidth(MHz_u{20});
1942 txVector.SetNss(2); // EHT-LTF duration assumed to be always 8 us for the time being (see note
1943 // in HePhy::GetTrainingDuration)
1944 txVector.SetMode(EhtPhy::GetEhtMcs9());
1945 userInfoMap = {{1, {HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 4, 2}},
1946 {2, {HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 9, 1}}};
1947 WifiMode uSigMode = EhtPhy::GetVhtMcs0();
1948 WifiMode ehtSigMode = EhtPhy::GetVhtMcs4(); // because of first user info map
1949
1950 // -> EHT TB format
1952 txVector.SetHeMuUserInfo(1, userInfoMap.at(1));
1953 txVector.SetHeMuUserInfo(2, userInfoMap.at(2));
1954 sections[WIFI_PPDU_FIELD_U_SIG] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
1955 uSigMode};
1956 sections[WIFI_PPDU_FIELD_TRAINING] = {
1957 {ppduStart + MicroSeconds(32),
1958 ppduStart + MicroSeconds(56)}, // 1 EHT-STF (@ 8 us) + 2 EHT-LTFs (@ 8 us)
1959 uSigMode};
1960 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1961
1962 // -> EHT MU format
1964 txVector.SetEhtPpduType(0); // EHT MU transmission
1965 txVector.SetRuAllocation({96}, 0);
1966 sections[WIFI_PPDU_FIELD_U_SIG] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
1967 uSigMode};
1968 sections[WIFI_PPDU_FIELD_EHT_SIG] = {
1969 {ppduStart + MicroSeconds(32), ppduStart + MicroSeconds(36)}, // only one symbol
1970 ehtSigMode};
1971 sections[WIFI_PPDU_FIELD_TRAINING] = {
1972 {ppduStart + MicroSeconds(36),
1973 ppduStart + MicroSeconds(56)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
1974 ehtSigMode};
1975 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1976 txVector.SetChannelWidth(MHz_u{160}); // shouldn't have any impact
1977 txVector.SetRuAllocation({96, 113, 113, 113, 113, 113, 113, 113}, 0);
1978
1979 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1980}
1981
1982/**
1983 * @ingroup wifi-test
1984 * @ingroup tests
1985 *
1986 * @brief Tx Duration Test Suite
1987 */
1989{
1990 public:
1992};
1993
1995 : TestSuite("wifi-devices-tx-duration", Type::UNIT)
1996{
1997 AddTestCase(new TxDurationTest, TestCase::Duration::QUICK);
1998
1999 AddTestCase(new PhyHeaderSectionsTest, TestCase::Duration::QUICK);
2000
2001 // 20 MHz band, OFDMA, even number of users in HE-SIG-B content channel
2003 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1},
2004 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}},
2006 MHz_u{20},
2007 0,
2009 {96},
2010 std::make_pair(2, 0), // both users in HE-SIG-B content channel 1
2011 MicroSeconds(4)), // one OFDM symbol;
2012 TestCase::Duration::QUICK);
2013
2014 // 40 MHz band, OFDMA, even number of users per HE-SIG-B content channel
2016 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2017 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2018 {HeRu::RuSpec{RuType::RU_52_TONE, 5, true}, 4, 1}, // CC2
2019 {HeRu::RuSpec{RuType::RU_52_TONE, 6, true}, 6, 2}, // CC2
2020 {HeRu::RuSpec{RuType::RU_52_TONE, 7, true}, 5, 3}, // CC2
2021 {HeRu::RuSpec{RuType::RU_52_TONE, 8, true}, 6, 2}}, // CC2
2023 MHz_u{40},
2024 0,
2026 {96, 112},
2027 std::make_pair(2, 4), // two users in HE-SIG-B content channel 1 and
2028 // four users in HE-SIG-B content channel 2
2029 MicroSeconds(4)), // one OFDM symbol;
2030 TestCase::Duration::QUICK);
2031
2032 // 40 MHz band, OFDMA, odd number of users in second HE-SIG-B content channel
2034 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2035 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2036 {HeRu::RuSpec{RuType::RU_52_TONE, 5, true}, 4, 1}, // CC2
2037 {HeRu::RuSpec{RuType::RU_52_TONE, 6, true}, 6, 2}, // CC2
2038 {HeRu::RuSpec{RuType::RU_52_TONE, 7, true}, 5, 3}, // CC2
2039 {HeRu::RuSpec{RuType::RU_52_TONE, 8, true}, 6, 2}, // CC2
2040 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 3, 1}}, // CC2
2042 MHz_u{40},
2043 0,
2045 {96, 15},
2046 std::make_pair(2, 5), // two users in HE-SIG-B content channel 1 and
2047 // five users in HE-SIG-B content channel 2
2048 MicroSeconds(8)), // two OFDM symbols
2049 TestCase::Duration::QUICK);
2050
2051 // 80 MHz band, OFDMA
2053 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2054 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2055 {HeRu::RuSpec{RuType::RU_52_TONE, 5, true}, 4, 1}, // CC2
2056 {HeRu::RuSpec{RuType::RU_52_TONE, 6, true}, 6, 2}, // CC2
2057 {HeRu::RuSpec{RuType::RU_52_TONE, 7, true}, 5, 3}, // CC2
2058 {HeRu::RuSpec{RuType::RU_52_TONE, 8, true}, 6, 2}, // CC2
2059 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 3, 1}, // CC2
2060 {HeRu::RuSpec{RuType::RU_242_TONE, 3, true}, 1, 1}, // CC1
2061 {HeRu::RuSpec{RuType::RU_242_TONE, 4, true}, 4, 1}}, // CC2
2063 MHz_u{80},
2064 0,
2066 {96, 15, 192, 192},
2067 std::make_pair(3, 6), // three users in HE-SIG-B content channel 1
2068 // and six users in HE-SIG-B content channel 2
2069 MicroSeconds(16)), // four OFDM symbols
2070 TestCase::Duration::QUICK);
2071
2072 // 80 MHz band, OFDMA, no central 26-tones RU
2074 {{HeRu::RuSpec{RuType::RU_26_TONE, 1, true}, 8, 1}, // CC1
2075 {HeRu::RuSpec{RuType::RU_26_TONE, 2, true}, 8, 1}, // CC1
2076 {HeRu::RuSpec{RuType::RU_26_TONE, 3, true}, 8, 1}, // CC1
2077 {HeRu::RuSpec{RuType::RU_26_TONE, 4, true}, 8, 1}, // CC1
2078 {HeRu::RuSpec{RuType::RU_26_TONE, 5, true}, 8, 1}, // CC1
2079 {HeRu::RuSpec{RuType::RU_26_TONE, 6, true}, 8, 1}, // CC1
2080 {HeRu::RuSpec{RuType::RU_26_TONE, 7, true}, 8, 1}, // CC1
2081 {HeRu::RuSpec{RuType::RU_26_TONE, 8, true}, 8, 1}, // CC1
2082 {HeRu::RuSpec{RuType::RU_26_TONE, 9, true}, 8, 1}, // CC1
2083 {HeRu::RuSpec{RuType::RU_26_TONE, 10, true}, 8, 1}, // CC2
2084 {HeRu::RuSpec{RuType::RU_26_TONE, 11, true}, 8, 1}, // CC2
2085 {HeRu::RuSpec{RuType::RU_26_TONE, 12, true}, 8, 1}, // CC2
2086 {HeRu::RuSpec{RuType::RU_26_TONE, 13, true}, 8, 1}, // CC2
2087 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 8, 1}, // CC2
2088 {HeRu::RuSpec{RuType::RU_26_TONE, 15, true}, 8, 1}, // CC2
2089 {HeRu::RuSpec{RuType::RU_26_TONE, 16, true}, 8, 1}, // CC2
2090 {HeRu::RuSpec{RuType::RU_26_TONE, 17, true}, 8, 1}, // CC2
2091 {HeRu::RuSpec{RuType::RU_26_TONE, 18, true}, 8, 1}, // CC2
2092 {HeRu::RuSpec{RuType::RU_26_TONE, 20, true}, 8, 1}, // CC1
2093 {HeRu::RuSpec{RuType::RU_26_TONE, 21, true}, 8, 1}, // CC1
2094 {HeRu::RuSpec{RuType::RU_26_TONE, 22, true}, 8, 1}, // CC1
2095 {HeRu::RuSpec{RuType::RU_26_TONE, 23, true}, 8, 1}, // CC1
2096 {HeRu::RuSpec{RuType::RU_26_TONE, 24, true}, 8, 1}, // CC1
2097 {HeRu::RuSpec{RuType::RU_26_TONE, 25, true}, 8, 1}, // CC1
2098 {HeRu::RuSpec{RuType::RU_26_TONE, 26, true}, 8, 1}, // CC1
2099 {HeRu::RuSpec{RuType::RU_26_TONE, 27, true}, 8, 1}, // CC1
2100 {HeRu::RuSpec{RuType::RU_26_TONE, 28, true}, 8, 1}, // CC2
2101 {HeRu::RuSpec{RuType::RU_26_TONE, 29, true}, 8, 1}, // CC2
2102 {HeRu::RuSpec{RuType::RU_26_TONE, 30, true}, 8, 1}, // CC2
2103 {HeRu::RuSpec{RuType::RU_26_TONE, 31, true}, 8, 1}, // CC2
2104 {HeRu::RuSpec{RuType::RU_26_TONE, 32, true}, 8, 1}, // CC2
2105 {HeRu::RuSpec{RuType::RU_26_TONE, 33, true}, 8, 1}, // CC2
2106 {HeRu::RuSpec{RuType::RU_26_TONE, 34, true}, 8, 1}, // CC2
2107 {HeRu::RuSpec{RuType::RU_26_TONE, 35, true}, 8, 1}, // CC2
2108 {HeRu::RuSpec{RuType::RU_26_TONE, 36, true}, 8, 1}, // CC2
2109 {HeRu::RuSpec{RuType::RU_26_TONE, 37, true}, 8, 1}}, // CC2
2111 MHz_u{80},
2112 0,
2114 {0, 0, 0, 0},
2115 std::make_pair(18, 18), // 18 users users in each HE-SIG-B content channel
2116 MicroSeconds(12)), // three OFDM symbols
2117 TestCase::Duration::QUICK);
2118
2119 // 80 MHz band, OFDMA, central 26-tones RU
2122 {{HeRu::RuSpec{RuType::RU_26_TONE, 1, true}, 8, 1}, // CC1
2123 {HeRu::RuSpec{RuType::RU_26_TONE, 2, true}, 8, 1}, // CC1
2124 {HeRu::RuSpec{RuType::RU_26_TONE, 3, true}, 8, 1}, // CC1
2125 {HeRu::RuSpec{RuType::RU_26_TONE, 4, true}, 8, 1}, // CC1
2126 {HeRu::RuSpec{RuType::RU_26_TONE, 5, true}, 8, 1}, // CC1
2127 {HeRu::RuSpec{RuType::RU_26_TONE, 6, true}, 8, 1}, // CC1
2128 {HeRu::RuSpec{RuType::RU_26_TONE, 7, true}, 8, 1}, // CC1
2129 {HeRu::RuSpec{RuType::RU_26_TONE, 8, true}, 8, 1}, // CC1
2130 {HeRu::RuSpec{RuType::RU_26_TONE, 9, true}, 8, 1}, // CC1
2131 {HeRu::RuSpec{RuType::RU_26_TONE, 10, true}, 8, 1}, // CC2
2132 {HeRu::RuSpec{RuType::RU_26_TONE, 11, true}, 8, 1}, // CC2
2133 {HeRu::RuSpec{RuType::RU_26_TONE, 12, true}, 8, 1}, // CC2
2134 {HeRu::RuSpec{RuType::RU_26_TONE, 13, true}, 8, 1}, // CC2
2135 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 8, 1}, // CC2
2136 {HeRu::RuSpec{RuType::RU_26_TONE, 15, true}, 8, 1}, // CC2
2137 {HeRu::RuSpec{RuType::RU_26_TONE, 16, true}, 8, 1}, // CC2
2138 {HeRu::RuSpec{RuType::RU_26_TONE, 17, true}, 8, 1}, // CC2
2139 {HeRu::RuSpec{RuType::RU_26_TONE, 18, true}, 8, 1}, // CC2
2140 {HeRu::RuSpec{RuType::RU_26_TONE, 19, true}, 8, 1}, // CC1
2141 {HeRu::RuSpec{RuType::RU_26_TONE, 20, true}, 8, 1}, // CC1
2142 {HeRu::RuSpec{RuType::RU_26_TONE, 21, true}, 8, 1}, // CC1
2143 {HeRu::RuSpec{RuType::RU_26_TONE, 22, true}, 8, 1}, // CC1
2144 {HeRu::RuSpec{RuType::RU_26_TONE, 23, true}, 8, 1}, // CC1
2145 {HeRu::RuSpec{RuType::RU_26_TONE, 24, true}, 8, 1}, // CC1
2146 {HeRu::RuSpec{RuType::RU_26_TONE, 25, true}, 8, 1}, // CC1
2147 {HeRu::RuSpec{RuType::RU_26_TONE, 26, true}, 8, 1}, // CC1
2148 {HeRu::RuSpec{RuType::RU_26_TONE, 27, true}, 8, 1}, // CC1
2149 {HeRu::RuSpec{RuType::RU_26_TONE, 28, true}, 8, 1}, // CC2
2150 {HeRu::RuSpec{RuType::RU_26_TONE, 29, true}, 8, 1}, // CC2
2151 {HeRu::RuSpec{RuType::RU_26_TONE, 30, true}, 8, 1}, // CC2
2152 {HeRu::RuSpec{RuType::RU_26_TONE, 31, true}, 8, 1}, // CC2
2153 {HeRu::RuSpec{RuType::RU_26_TONE, 32, true}, 8, 1}, // CC2
2154 {HeRu::RuSpec{RuType::RU_26_TONE, 33, true}, 8, 1}, // CC2
2155 {HeRu::RuSpec{RuType::RU_26_TONE, 34, true}, 8, 1}, // CC2
2156 {HeRu::RuSpec{RuType::RU_26_TONE, 35, true}, 8, 1}, // CC2
2157 {HeRu::RuSpec{RuType::RU_26_TONE, 36, true}, 8, 1}, // CC2
2158 {HeRu::RuSpec{RuType::RU_26_TONE, 37, true}, 8, 1}}, // CC2
2160 MHz_u{80},
2161 0,
2163 {0, 0, 0, 0},
2164 std::make_pair(19,
2165 18), // 19 users (18 users + 1 central tones-RU user) in HE-SIG-B content
2166 // channel 1 and 18 users user in HE-SIG-B content channel 2
2167 MicroSeconds(12)), // three OFDM symbols
2168 TestCase::Duration::QUICK);
2169
2170 // 160 MHz band, OFDMA, no central 26-tones RU
2172 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2173 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2174 {HeRu::RuSpec{RuType::RU_52_TONE, 5, true}, 4, 1}, // CC2
2175 {HeRu::RuSpec{RuType::RU_52_TONE, 6, true}, 6, 2}, // CC2
2176 {HeRu::RuSpec{RuType::RU_52_TONE, 7, true}, 5, 3}, // CC2
2177 {HeRu::RuSpec{RuType::RU_52_TONE, 8, true}, 6, 2}, // CC2
2178 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 3, 1}, // CC2
2179 {HeRu::RuSpec{RuType::RU_242_TONE, 3, true}, 1, 1}, // CC1
2180 {HeRu::RuSpec{RuType::RU_242_TONE, 4, true}, 4, 1}, // CC2
2181 {HeRu::RuSpec{RuType::RU_996_TONE, 1, false},
2182 1,
2183 1}}, // CC1 or CC2 => CC1 for better split
2185 MHz_u{160},
2186 0,
2188 {96, 15, 192, 192, 208, 115, 208, 115},
2189 std::make_pair(4, 6), // four users in HE-SIG-B content channel 1 and
2190 // seven users in HE-SIG-B content channel 2
2191 MicroSeconds(16)), // four OFDM symbols
2192 TestCase::Duration::QUICK);
2193
2194 // 160 MHz band, OFDMA, central 26-tones RU in low 80 MHz
2196 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2197 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2198 {HeRu::RuSpec{RuType::RU_52_TONE, 5, true}, 4, 1}, // CC2
2199 {HeRu::RuSpec{RuType::RU_52_TONE, 6, true}, 6, 2}, // CC2
2200 {HeRu::RuSpec{RuType::RU_52_TONE, 7, true}, 5, 3}, // CC2
2201 {HeRu::RuSpec{RuType::RU_52_TONE, 8, true}, 6, 2}, // CC2
2202 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 3, 1}, // CC2
2203 {HeRu::RuSpec{RuType::RU_26_TONE, 19, true}, 8, 2}, // CC1
2204 {HeRu::RuSpec{RuType::RU_242_TONE, 3, true}, 1, 1}, // CC1
2205 {HeRu::RuSpec{RuType::RU_242_TONE, 4, true}, 4, 1}, // CC2
2206 {HeRu::RuSpec{RuType::RU_996_TONE, 1, false},
2207 1,
2208 1}}, // CC1 or CC2 => CC1 for better split
2210 MHz_u{160},
2211 0,
2213 {96, 15, 192, 192, 208, 115, 208, 115},
2214 std::make_pair(5, 6), // five users in HE-SIG-B content channel 1 and
2215 // seven users in HE-SIG-B content channel 2
2216 MicroSeconds(16)), // four OFDM symbols
2217 TestCase::Duration::QUICK);
2218
2219 // 160 MHz band, OFDMA, central 26-tones RU in high 80 MHz
2221 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2222 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2223 {HeRu::RuSpec{RuType::RU_106_TONE, 3, true}, 11, 1}, // CC2
2224 {HeRu::RuSpec{RuType::RU_106_TONE, 4, true}, 10, 4}, // CC2
2225 {HeRu::RuSpec{RuType::RU_242_TONE, 3, true}, 10, 1}, // CC1
2226 {HeRu::RuSpec{RuType::RU_242_TONE, 4, true}, 11, 1}, // CC2
2227 {HeRu::RuSpec{RuType::RU_484_TONE, 1, false}, 7, 1}, // CC1 or CC2
2228 {HeRu::RuSpec{RuType::RU_26_TONE, 19, false}, 8, 2}, // CC2
2229 {HeRu::RuSpec{RuType::RU_484_TONE, 2, false}, 9, 1}}, // CC1 or CC2
2231 MHz_u{160},
2232 0,
2234 {96, 96, 192, 192, 200, 114, 114, 200},
2235 std::make_pair(4, 5), // two users in HE-SIG-B content channel 1 and
2236 // one user in HE-SIG-B content channel 2
2237 MicroSeconds(4)), // two OFDM symbols
2238 TestCase::Duration::QUICK);
2239
2240 // 160 MHz band, OFDMA, central 26-tones RU in both 80 MHz
2242 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_106_TONE, 1, true}, 11, 1}, // CC1
2243 {HeRu::RuSpec{RuType::RU_106_TONE, 2, true}, 10, 4}, // CC1
2244 {HeRu::RuSpec{RuType::RU_106_TONE, 3, true}, 11, 1}, // CC2
2245 {HeRu::RuSpec{RuType::RU_106_TONE, 4, true}, 10, 4}, // CC2
2246 {HeRu::RuSpec{RuType::RU_26_TONE, 19, true}, 8, 2}, // CC1
2247 {HeRu::RuSpec{RuType::RU_242_TONE, 3, true}, 10, 1}, // CC1
2248 {HeRu::RuSpec{RuType::RU_242_TONE, 4, true}, 11, 1}, // CC2
2249 {HeRu::RuSpec{RuType::RU_484_TONE, 1, false}, 7, 1}, // CC1 or CC2
2250 {HeRu::RuSpec{RuType::RU_26_TONE, 19, false}, 8, 2}, // CC2
2251 {HeRu::RuSpec{RuType::RU_484_TONE, 2, false}, 9, 1}}, // CC1 or CC2
2253 MHz_u{160},
2254 0,
2256 {96, 96, 192, 192, 200, 114, 114, 200},
2257 std::make_pair(5, 5), // two users in HE-SIG-B content channel 1 and
2258 // one user in HE-SIG-B content channel 2
2259 MicroSeconds(4)), // two OFDM symbols
2260 TestCase::Duration::QUICK);
2261
2262 // 160 MHz band, OFDMA, maximum number of users
2264 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_26_TONE, 1, true}, 8, 1}, // CC1
2265 {HeRu::RuSpec{RuType::RU_26_TONE, 2, true}, 8, 1}, // CC1
2266 {HeRu::RuSpec{RuType::RU_26_TONE, 3, true}, 8, 1}, // CC1
2267 {HeRu::RuSpec{RuType::RU_26_TONE, 4, true}, 8, 1}, // CC1
2268 {HeRu::RuSpec{RuType::RU_26_TONE, 5, true}, 8, 1}, // CC1
2269 {HeRu::RuSpec{RuType::RU_26_TONE, 6, true}, 8, 1}, // CC1
2270 {HeRu::RuSpec{RuType::RU_26_TONE, 7, true}, 8, 1}, // CC1
2271 {HeRu::RuSpec{RuType::RU_26_TONE, 8, true}, 8, 1}, // CC1
2272 {HeRu::RuSpec{RuType::RU_26_TONE, 9, true}, 8, 1}, // CC1
2273 {HeRu::RuSpec{RuType::RU_26_TONE, 10, true}, 8, 1}, // CC2
2274 {HeRu::RuSpec{RuType::RU_26_TONE, 11, true}, 8, 1}, // CC2
2275 {HeRu::RuSpec{RuType::RU_26_TONE, 12, true}, 8, 1}, // CC2
2276 {HeRu::RuSpec{RuType::RU_26_TONE, 13, true}, 8, 1}, // CC2
2277 {HeRu::RuSpec{RuType::RU_26_TONE, 14, true}, 8, 1}, // CC2
2278 {HeRu::RuSpec{RuType::RU_26_TONE, 15, true}, 8, 1}, // CC2
2279 {HeRu::RuSpec{RuType::RU_26_TONE, 16, true}, 8, 1}, // CC2
2280 {HeRu::RuSpec{RuType::RU_26_TONE, 17, true}, 8, 1}, // CC2
2281 {HeRu::RuSpec{RuType::RU_26_TONE, 18, true}, 8, 1}, // CC2
2282 {HeRu::RuSpec{RuType::RU_26_TONE, 19, true}, 8, 1}, // CC1
2283 {HeRu::RuSpec{RuType::RU_26_TONE, 20, true}, 8, 1}, // CC1
2284 {HeRu::RuSpec{RuType::RU_26_TONE, 21, true}, 8, 1}, // CC1
2285 {HeRu::RuSpec{RuType::RU_26_TONE, 22, true}, 8, 1}, // CC1
2286 {HeRu::RuSpec{RuType::RU_26_TONE, 23, true}, 8, 1}, // CC1
2287 {HeRu::RuSpec{RuType::RU_26_TONE, 24, true}, 8, 1}, // CC1
2288 {HeRu::RuSpec{RuType::RU_26_TONE, 25, true}, 8, 1}, // CC1
2289 {HeRu::RuSpec{RuType::RU_26_TONE, 26, true}, 8, 1}, // CC1
2290 {HeRu::RuSpec{RuType::RU_26_TONE, 27, true}, 8, 1}, // CC1
2291 {HeRu::RuSpec{RuType::RU_26_TONE, 28, true}, 8, 1}, // CC2
2292 {HeRu::RuSpec{RuType::RU_26_TONE, 29, true}, 8, 1}, // CC2
2293 {HeRu::RuSpec{RuType::RU_26_TONE, 30, true}, 8, 1}, // CC2
2294 {HeRu::RuSpec{RuType::RU_26_TONE, 31, true}, 8, 1}, // CC2
2295 {HeRu::RuSpec{RuType::RU_26_TONE, 32, true}, 8, 1}, // CC2
2296 {HeRu::RuSpec{RuType::RU_26_TONE, 33, true}, 8, 1}, // CC2
2297 {HeRu::RuSpec{RuType::RU_26_TONE, 34, true}, 8, 1}, // CC2
2298 {HeRu::RuSpec{RuType::RU_26_TONE, 35, true}, 8, 1}, // CC2
2299 {HeRu::RuSpec{RuType::RU_26_TONE, 36, true}, 8, 1}, // CC2
2300 {HeRu::RuSpec{RuType::RU_26_TONE, 37, true}, 8, 1}, // CC2
2301 {HeRu::RuSpec{RuType::RU_26_TONE, 1, false}, 8, 1}, // CC1
2302 {HeRu::RuSpec{RuType::RU_26_TONE, 2, false}, 8, 1}, // CC1
2303 {HeRu::RuSpec{RuType::RU_26_TONE, 3, false}, 8, 1}, // CC1
2304 {HeRu::RuSpec{RuType::RU_26_TONE, 4, false}, 8, 1}, // CC1
2305 {HeRu::RuSpec{RuType::RU_26_TONE, 5, false}, 8, 1}, // CC1
2306 {HeRu::RuSpec{RuType::RU_26_TONE, 6, false}, 8, 1}, // CC1
2307 {HeRu::RuSpec{RuType::RU_26_TONE, 7, false}, 8, 1}, // CC1
2308 {HeRu::RuSpec{RuType::RU_26_TONE, 8, false}, 8, 1}, // CC1
2309 {HeRu::RuSpec{RuType::RU_26_TONE, 9, false}, 8, 1}, // CC1
2310 {HeRu::RuSpec{RuType::RU_26_TONE, 10, false}, 8, 1}, // CC2
2311 {HeRu::RuSpec{RuType::RU_26_TONE, 11, false}, 8, 1}, // CC2
2312 {HeRu::RuSpec{RuType::RU_26_TONE, 12, false}, 8, 1}, // CC2
2313 {HeRu::RuSpec{RuType::RU_26_TONE, 13, false}, 8, 1}, // CC2
2314 {HeRu::RuSpec{RuType::RU_26_TONE, 14, false}, 8, 1}, // CC2
2315 {HeRu::RuSpec{RuType::RU_26_TONE, 15, false}, 8, 1}, // CC2
2316 {HeRu::RuSpec{RuType::RU_26_TONE, 16, false}, 8, 1}, // CC2
2317 {HeRu::RuSpec{RuType::RU_26_TONE, 17, false}, 8, 1}, // CC2
2318 {HeRu::RuSpec{RuType::RU_26_TONE, 18, false}, 8, 1}, // CC2
2319 {HeRu::RuSpec{RuType::RU_26_TONE, 19, false}, 8, 1}, // CC1
2320 {HeRu::RuSpec{RuType::RU_26_TONE, 20, false}, 8, 1}, // CC1
2321 {HeRu::RuSpec{RuType::RU_26_TONE, 21, false}, 8, 1}, // CC1
2322 {HeRu::RuSpec{RuType::RU_26_TONE, 22, false}, 8, 1}, // CC1
2323 {HeRu::RuSpec{RuType::RU_26_TONE, 23, false}, 8, 1}, // CC1
2324 {HeRu::RuSpec{RuType::RU_26_TONE, 24, false}, 8, 1}, // CC1
2325 {HeRu::RuSpec{RuType::RU_26_TONE, 25, false}, 8, 1}, // CC1
2326 {HeRu::RuSpec{RuType::RU_26_TONE, 26, false}, 8, 1}, // CC1
2327 {HeRu::RuSpec{RuType::RU_26_TONE, 27, false}, 8, 1}, // CC1
2328 {HeRu::RuSpec{RuType::RU_26_TONE, 28, false}, 8, 1}, // CC2
2329 {HeRu::RuSpec{RuType::RU_26_TONE, 29, false}, 8, 1}, // CC2
2330 {HeRu::RuSpec{RuType::RU_26_TONE, 30, false}, 8, 1}, // CC2
2331 {HeRu::RuSpec{RuType::RU_26_TONE, 31, false}, 8, 1}, // CC2
2332 {HeRu::RuSpec{RuType::RU_26_TONE, 32, false}, 8, 1}, // CC2
2333 {HeRu::RuSpec{RuType::RU_26_TONE, 33, false}, 8, 1}, // CC2
2334 {HeRu::RuSpec{RuType::RU_26_TONE, 34, false}, 8, 1}, // CC2
2335 {HeRu::RuSpec{RuType::RU_26_TONE, 35, false}, 8, 1}, // CC2
2336 {HeRu::RuSpec{RuType::RU_26_TONE, 36, false}, 8, 1}, // CC2
2337 {HeRu::RuSpec{RuType::RU_26_TONE, 37, false}, 8, 1}}, // CC2
2339 MHz_u{160},
2340 0,
2342 {0, 0, 0, 0, 0, 0, 0, 0},
2343 std::make_pair(37,
2344 37), // 37 users (36 users + 1 central tones-RU user)
2345 // in each HE-SIG-B content channel
2346 MicroSeconds(20)), // five OFDM symbols
2347 TestCase::Duration::QUICK);
2348
2349 // 160 MHz band, OFDMA, single-user using 2x996 tones RU
2351 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 8, 1}}, // CC1
2353 MHz_u{160},
2354 0,
2356 {208, 208, 208, 208, 208, 208, 208, 208},
2357 std::make_pair(1, 0), // one user in HE-SIG-B content channel 1
2358 MicroSeconds(4)), // one OFDM symbol;
2359 TestCase::Duration::QUICK);
2360
2361 // 160 MHz band, OFDMA, primary80 is in the high 80 MHz band
2363 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_996_TONE, 1, false}, 8, 1}, // CC2
2364 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 8, 1}}, // CC1
2366 MHz_u{160},
2367 4,
2369 {208, 115, 208, 115, 115, 208, 115, 208},
2370 std::make_pair(1, 1), // one user in each HE-SIG-B content channel
2371 MicroSeconds(4)), // one OFDM symbol;
2372 TestCase::Duration::QUICK);
2373
2374 // 20 MHz band, OFDMA, one unallocated RU at the middle
2377 {{HeRu::RuSpec{RuType::RU_26_TONE, 1, true}, 11, 1}, // CC1
2378 {HeRu::RuSpec{RuType::RU_26_TONE, 2, true}, 11, 1}, // CC1
2379 {HeRu::RuSpec{RuType::RU_26_TONE, 3, true}, 11, 1}, // CC1
2380 {HeRu::RuSpec{RuType::RU_26_TONE, 4, true}, 11, 1}, // CC1
2381 {HeRu::RuSpec{RuType::RU_26_TONE, 6, true}, 11, 1}, // CC1
2382 {HeRu::RuSpec{RuType::RU_26_TONE, 7, true}, 11, 1}, // CC1
2383 {HeRu::RuSpec{RuType::RU_26_TONE, 8, true}, 11, 1}, // CC1
2384 {HeRu::RuSpec{RuType::RU_26_TONE, 9, true}, 11, 1}}, // CC1
2386 MHz_u{20},
2387 0,
2389 {0},
2390 std::make_pair(9, 0), // 9 users (8 users + 1 empty user) in HE-SIG-B content channel 1
2391 MicroSeconds(8)), // two OFDM symbols
2392 TestCase::Duration::QUICK);
2393
2394 // 40 MHz band, OFDMA, unallocated RUs at the begin and at the end of the
2395 // first 20 MHz subband and in the middle of the second 20 MHz subband
2398 {{HeRu::RuSpec{RuType::RU_52_TONE, 2, true}, 10, 1}, // CC1
2399 {HeRu::RuSpec{RuType::RU_52_TONE, 3, true}, 10, 2}, // CC1
2400 {HeRu::RuSpec{RuType::RU_52_TONE, 5, true}, 11, 1}, // CC2
2401 {HeRu::RuSpec{RuType::RU_52_TONE, 8, true}, 11, 2}}, // CC2
2403 MHz_u{40},
2404 0,
2406 {112, 112},
2407 std::make_pair(4,
2408 4), // 4 users (2 users + 2 empty users) in each HE-SIG-B content channel
2409 MicroSeconds(4)), // one OFDM symbol
2410 TestCase::Duration::QUICK);
2411
2412 // 40 MHz band, OFDMA, one unallocated RUs in the first 20 MHz subband and
2413 // two unallocated RUs in second 20 MHz subband
2416 {{HeRu::RuSpec{RuType::RU_52_TONE, 1, true}, 10, 1}, // CC1
2417 {HeRu::RuSpec{RuType::RU_52_TONE, 2, true}, 10, 2}, // CC1
2418 {HeRu::RuSpec{RuType::RU_52_TONE, 3, true}, 11, 1}, // CC1
2419 {HeRu::RuSpec{RuType::RU_52_TONE, 5, true}, 11, 2}, // CC2
2420 {HeRu::RuSpec{RuType::RU_52_TONE, 6, true}, 11, 3}}, // CC2
2422 MHz_u{40},
2423 0,
2425 {112, 112},
2426 std::make_pair(4,
2427 4), // 4 users (3 users + 1 empty user) in HE-SIG-B content channel 1 and
2428 // 4 users (2 users + 2 empty users) in HE-SIG-B content channel 2
2429 MicroSeconds(4)), // one OFDM symbol
2430 TestCase::Duration::QUICK);
2431
2432 // 40 MHz band, OFDMA, first 20 MHz is punctured
2434 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 2, true}, 11, 1}}, // CC2
2436 MHz_u{40},
2437 1,
2439 {113, 192},
2440 std::make_pair(0, 1), // one user in HE-SIG-B content channel 1
2441 MicroSeconds(4)), // one OFDM symbol;
2442 TestCase::Duration::QUICK);
2443
2444 // 20 MHz band, MU-MIMO, 2 users
2446 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 11, 1}, // CC1
2447 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 10, 4}}, // CC1
2449 MHz_u{20},
2450 0,
2452 {192},
2453 std::make_pair(2, 0), // both users in HE-SIG-B content channel 1
2454 MicroSeconds(4)), // one OFDM symbol
2455 TestCase::Duration::QUICK);
2456
2457 // 20 MHz band, MU-MIMO, 3 users
2459 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 4, 3}, // CC1
2460 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 5, 2}, // CC1
2461 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 6, 1}}, // CC1
2463 MHz_u{20},
2464 0,
2466 {192},
2467 std::make_pair(3, 0), // all users in HE-SIG-B content channel 1
2468 MicroSeconds(4)), // one OFDM symbol
2469 TestCase::Duration::QUICK);
2470
2471 // 20 MHz band, MU-MIMO, 4 users
2473 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 4, 1}, // CC1
2474 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 5, 2}, // CC1
2475 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 6, 3}, // CC1
2476 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 7, 2}}, // CC1
2478 MHz_u{20},
2479 0,
2481 {192},
2482 std::make_pair(4, 0), // all users in HE-SIG-B content channel 1
2483 MicroSeconds(4)), // one OFDM symbol
2484 TestCase::Duration::QUICK);
2485
2486 // 20 MHz band, MU-MIMO, 6 users
2488 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 4, 1}, // CC1
2489 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 5, 1}, // CC1
2490 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 6, 2}, // CC1
2491 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 7, 2}, // CC1
2492 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 8, 1}, // CC1
2493 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 9, 1}}, // CC1
2495 MHz_u{20},
2496 0,
2498 {192},
2499 std::make_pair(6, 0), // all users in HE-SIG-B content channel 1
2500 MicroSeconds(4)), // one OFDM symbol
2501 TestCase::Duration::QUICK);
2502
2503 // 20 MHz band, MU-MIMO, 8 users
2505 new HeSigBDurationTest({{HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 4, 1}, // CC1
2506 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 5, 1}, // CC1
2507 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 6, 1}, // CC1
2508 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 7, 1}, // CC1
2509 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 8, 1}, // CC1
2510 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 9, 1}, // CC1
2511 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 10, 1}, // CC1
2512 {HeRu::RuSpec{RuType::RU_242_TONE, 1, true}, 11, 1}}, // CC1
2514 MHz_u{20},
2515 0,
2517 {192},
2518 std::make_pair(8, 0), // all users in HE-SIG-B content channel 1
2519 MicroSeconds(8)), // two OFDM symbols
2520 TestCase::Duration::QUICK);
2521
2522 // 40 MHz band, MU-MIMO, 2 users
2524 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 11, 1}, // CC1
2525 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 10, 4}}, // CC2
2527 MHz_u{40},
2528 0,
2530 {200, 200},
2531 std::make_pair(1, 1), // users equally split between the two content channels
2532 MicroSeconds(4)), // one OFDM symbol
2533 TestCase::Duration::QUICK);
2534
2535 // 40 MHz band, MU-MIMO, 3 users
2538 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 4, 3}, // CC1
2539 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 5, 2}, // CC2
2540 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 6, 1}}, // CC1
2542 MHz_u{40},
2543 0,
2545 {200, 200},
2546 std::make_pair(2, 1), // 2 users in content channel 1 and 1 user in content channel 2
2547 MicroSeconds(4)), // one OFDM symbol
2548 TestCase::Duration::QUICK);
2549
2550 // 40 MHz band, MU-MIMO, 4 users
2552 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 4, 1}, // CC1
2553 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 5, 2}, // CC2
2554 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 6, 3}, // CC1
2555 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 7, 2}}, // CC2
2557 MHz_u{40},
2558 0,
2560 {200, 200},
2561 std::make_pair(2, 2), // users equally split between the two content channels
2562 MicroSeconds(4)), // one OFDM symbol
2563 TestCase::Duration::QUICK);
2564
2565 // 40 MHz band, MU-MIMO, 6 users
2567 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 4, 1}, // CC1
2568 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 5, 1}, // CC2
2569 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 6, 2}, // CC1
2570 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 7, 2}, // CC2
2571 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 8, 1}, // CC1
2572 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 9, 1}}, // CC2
2574 MHz_u{40},
2575 0,
2577 {200, 200},
2578 std::make_pair(3, 3), // users equally split between the two content channels
2579 MicroSeconds(4)), // one OFDM symbol
2580 TestCase::Duration::QUICK);
2581
2582 // 40 MHz band, MU-MIMO, 8 users
2584 {{HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 4, 1}, // CC1
2585 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 5, 1}, // CC2
2586 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 6, 1}, // CC1
2587 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 7, 1}, // CC2
2588 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 8, 1}, // CC1
2589 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 9, 1}, // CC2
2590 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 10, 1}, // CC1
2591 {HeRu::RuSpec{RuType::RU_484_TONE, 1, true}, 11, 1}}, // CC2
2593 MHz_u{40},
2594 0,
2596 {200, 200},
2597 std::make_pair(4, 4), // users equally split between the two content channels
2598 MicroSeconds(4)), // one OFDM symbol
2599 TestCase::Duration::QUICK);
2600
2601 // 80 MHz band, MU-MIMO, 2 users
2603 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 11, 1}, // CC1
2604 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 10, 4}}, // CC2
2606 MHz_u{80},
2607 0,
2609 {208, 208, 208, 208},
2610 std::make_pair(1, 1), // users equally split between the two content channels
2611 MicroSeconds(4)), // one OFDM symbol
2612 TestCase::Duration::QUICK);
2613
2614 // 80 MHz band, MU-MIMO, 3 users
2617 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 4, 3}, // CC1
2618 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 5, 2}, // CC2
2619 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 6, 1}}, // CC1
2621 MHz_u{80},
2622 0,
2624 {208, 208, 208, 208},
2625 std::make_pair(2, 1), // 2 users in content channel 1 and 1 user in content channel 2
2626 MicroSeconds(4)), // one OFDM symbol
2627 TestCase::Duration::QUICK);
2628
2629 // 80 MHz band, MU-MIMO, 4 users
2631 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 4, 1}, // CC1
2632 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 5, 2}, // CC2
2633 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 6, 3}, // CC1
2634 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 7, 2}}, // CC2
2636 MHz_u{80},
2637 0,
2639 {208, 208, 208, 208},
2640 std::make_pair(2, 2), // users equally split between the two content channels
2641 MicroSeconds(4)), // one OFDM symbol
2642 TestCase::Duration::QUICK);
2643
2644 // 80 MHz band, MU-MIMO, 6 users
2646 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 4, 1}, // CC1
2647 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 5, 1}, // CC2
2648 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 6, 2}, // CC1
2649 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 7, 2}, // CC2
2650 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 8, 1}, // CC1
2651 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 9, 1}}, // CC2
2653 MHz_u{80},
2654 0,
2656 {208, 208, 208, 208},
2657 std::make_pair(3, 3), // users equally split between the two content channels
2658 MicroSeconds(4)), // one OFDM symbol
2659 TestCase::Duration::QUICK);
2660
2661 // 80 MHz band, MU-MIMO, 8 users
2663 {{HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 4, 1}, // CC1
2664 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 5, 1}, // CC2
2665 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 6, 1}, // CC1
2666 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 7, 1}, // CC2
2667 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 8, 1}, // CC1
2668 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 9, 1}, // CC2
2669 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 10, 1}, // CC1
2670 {HeRu::RuSpec{RuType::RU_996_TONE, 1, true}, 11, 1}}, // CC2
2672 MHz_u{80},
2673 0,
2675 {208, 208, 208, 208},
2676 std::make_pair(4, 4), // users equally split between the two content channels
2677 MicroSeconds(4)), // one OFDM symbol
2678 TestCase::Duration::QUICK);
2679
2680 // 160 MHz band, MU-MIMO, 2 users
2682 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 11, 1}, // CC1
2683 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 10, 4}}, // CC2
2685 MHz_u{160},
2686 0,
2688 {208, 208, 208, 208, 208, 208, 208, 208},
2689 std::make_pair(1, 1), // users equally split between the two content channels
2690 MicroSeconds(4)), // one OFDM symbol
2691 TestCase::Duration::QUICK);
2692
2693 // 160 MHz band, MU-MIMO, 3 users
2696 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 4, 3}, // CC1
2697 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 5, 2}, // CC2
2698 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 6, 1}}, // CC1
2700 MHz_u{160},
2701 0,
2703 {208, 208, 208, 208, 208, 208, 208, 208},
2704 std::make_pair(2, 1), // 2 users in content channel 1 and 1 user in content channel 2
2705 MicroSeconds(4)), // one OFDM symbol
2706 TestCase::Duration::QUICK);
2707
2708 // 160 MHz band, MU-MIMO, 4 users
2710 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 4, 1}, // CC1
2711 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 5, 2}, // CC2
2712 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 6, 3}, // CC1
2713 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 7, 2}}, // CC2
2715 MHz_u{160},
2716 0,
2718 {208, 208, 208, 208, 208, 208, 208, 208},
2719 std::make_pair(2, 2), // users equally split between the two content channels
2720 MicroSeconds(4)), // one OFDM symbol
2721 TestCase::Duration::QUICK);
2722
2723 // 160 MHz band, MU-MIMO, 6 users
2725 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 4, 1}, // CC1
2726 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 5, 1}, // CC2
2727 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 6, 2}, // CC1
2728 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 7, 2}, // CC2
2729 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 8, 1}, // CC1
2730 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 9, 1}}, // CC2
2732 MHz_u{160},
2733 0,
2735 {208, 208, 208, 208, 208, 208, 208, 208},
2736 std::make_pair(3, 3), // users equally split between the two content channels
2737 MicroSeconds(4)), // one OFDM symbol
2738 TestCase::Duration::QUICK);
2739
2740 // 160 MHz band, MU-MIMO, 8 users
2742 {{HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 4, 1}, // CC1
2743 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 5, 1}, // CC2
2744 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 6, 1}, // CC1
2745 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 7, 1}, // CC2
2746 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 8, 1}, // CC1
2747 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 9, 1}, // CC2
2748 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 10, 1}, // CC1
2749 {HeRu::RuSpec{RuType::RU_2x996_TONE, 1, true}, 11, 1}}, // CC2
2751 MHz_u{160},
2752 0,
2754 {208, 208, 208, 208, 208, 208, 208, 208},
2755 std::make_pair(4, 4), // users equally split between the two content channels
2756 MicroSeconds(4)), // one OFDM symbol
2757 TestCase::Duration::QUICK);
2758}
2759
HE-SIG-B duration test.
std::list< HeMuUserInfo > m_userInfos
HE MU specific per-user information.
MuType
OFDMA or MU-MIMO.
MuType m_expectedMuType
Expected MU type (OFDMA or MU-MIMO)
uint8_t m_p20Index
index of the primary20 channel
Ptr< YansWifiPhy > m_phy
the PHY under test
RuAllocation m_expectedRuAllocation
Expected RuType::RU_ALLOCATION.
HeSigBDurationTest(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.
Time m_expectedSigBDuration
Expected duration of the HE-SIG-B header.
WifiMode m_sigBMode
Mode used to transmit HE-SIG-B.
MHz_u m_channelWidth
Channel width.
WifiTxVector BuildTxVector() const
Build a TXVECTOR for HE MU.
void DoRun() override
Implementation to actually run this TestCase.
std::pair< std::size_t, std::size_t > m_expectedNumUsersPerCc
Expected number of users per content channel.
void DoTeardown() override
Implementation to do any local setup required for 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 InterferenceHelper 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 InterferenceHelper 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 GetEhtMcs9()
Return MCS 9 from EHT MCS values.
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 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:655
static std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(MHz_u channelWidth, 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:544
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:404
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:40
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:173
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:940
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition wifi-phy.cc:1010
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition wifi-phy.cc:1588
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition wifi-phy.cc:1070
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition wifi-phy.cc:761
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:1136
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.
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_80211ax
@ 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.
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.
@ 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)
Definition wifi-mode.h:24
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