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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Nicola Baldo <nbaldo@cttc.es>
18 * Sébastien Deronne <sebastien.deronne@gmail.com>
19 */
20
21#include "ns3/dsss-phy.h"
22#include "ns3/eht-phy.h" //includes OFDM, HT, VHT and HE
23#include "ns3/eht-ppdu.h" //includes OFDM, HT, VHT and HE
24#include "ns3/erp-ofdm-phy.h"
25#include "ns3/he-ru.h"
26#include "ns3/log.h"
27#include "ns3/packet.h"
28#include "ns3/simulator.h"
29#include "ns3/test.h"
30#include "ns3/wifi-psdu.h"
31#include "ns3/yans-wifi-phy.h"
32
33#include <list>
34#include <numeric>
35
36using namespace ns3;
37
38NS_LOG_COMPONENT_DEFINE("TxDurationTest");
39
47{
48 public:
50 ~TxDurationTest() override;
51 void DoRun() override;
52
53 private:
68 WifiMode payloadMode,
69 uint16_t channelWidth,
70 uint16_t guardInterval,
71 WifiPreamble preamble,
72 Time knownDuration);
73
87 bool CheckTxDuration(uint32_t size,
88 WifiMode payloadMode,
89 uint16_t channelWidth,
90 uint16_t guardInterval,
91 WifiPreamble preamble,
92 Time knownDuration);
93
107 static bool CheckMuTxDuration(std::list<uint32_t> sizes,
108 std::list<HeMuUserInfo> userInfos,
109 uint16_t channelWidth,
110 uint16_t guardInterval,
111 WifiPreamble preamble,
112 Time knownDuration);
113
128 static Time CalculateTxDurationUsingList(std::list<uint32_t> sizes,
129 std::list<uint16_t> staIds,
130 WifiTxVector txVector,
131 WifiPhyBand band);
132};
133
135 : TestCase("Wifi TX Duration")
136{
137}
138
140{
141}
142
143bool
145 WifiMode payloadMode,
146 uint16_t channelWidth,
147 uint16_t guardInterval,
148 WifiPreamble preamble,
149 Time knownDuration)
150{
151 WifiTxVector txVector;
152 txVector.SetMode(payloadMode);
153 txVector.SetPreambleType(preamble);
154 txVector.SetChannelWidth(channelWidth);
155 txVector.SetGuardInterval(guardInterval);
156 txVector.SetNss(1);
157 txVector.SetStbc(false);
158 txVector.SetNess(0);
159 std::list<WifiPhyBand> testedBands;
160 Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy>();
161 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM)
162 {
163 testedBands.push_back(WIFI_PHY_BAND_5GHZ);
164 }
165 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_HE)
166 {
167 testedBands.push_back(WIFI_PHY_BAND_6GHZ);
168 }
169 if (payloadMode.GetModulationClass() != WIFI_MOD_CLASS_VHT)
170 {
171 testedBands.push_back(WIFI_PHY_BAND_2_4GHZ);
172 }
173 for (auto& testedBand : testedBands)
174 {
175 if ((testedBand == WIFI_PHY_BAND_2_4GHZ) &&
176 (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM))
177 {
178 knownDuration +=
179 MicroSeconds(6); // 2.4 GHz band should be at the end of the bands to test
180 }
181 Time calculatedDuration = phy->GetPayloadDuration(size, txVector, testedBand);
182 if (calculatedDuration != knownDuration)
183 {
184 std::cerr << "size=" << size << " band=" << testedBand << " mode=" << payloadMode
185 << " channelWidth=" << channelWidth << " guardInterval=" << guardInterval
186 << " datarate=" << payloadMode.GetDataRate(channelWidth, guardInterval, 1)
187 << " known=" << knownDuration << " calculated=" << calculatedDuration
188 << std::endl;
189 return false;
190 }
191 }
192 return true;
193}
194
195bool
197 WifiMode payloadMode,
198 uint16_t channelWidth,
199 uint16_t guardInterval,
200 WifiPreamble preamble,
201 Time knownDuration)
202{
203 WifiTxVector txVector;
204 txVector.SetMode(payloadMode);
205 txVector.SetPreambleType(preamble);
206 txVector.SetChannelWidth(channelWidth);
207 txVector.SetGuardInterval(guardInterval);
208 txVector.SetNss(1);
209 txVector.SetStbc(false);
210 txVector.SetNess(0);
211 std::list<WifiPhyBand> testedBands;
212 Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy>();
213 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM)
214 {
215 testedBands.push_back(WIFI_PHY_BAND_5GHZ);
216 }
217 if (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_HE)
218 {
219 testedBands.push_back(WIFI_PHY_BAND_6GHZ);
220 }
221 if (payloadMode.GetModulationClass() != WIFI_MOD_CLASS_VHT)
222 {
223 testedBands.push_back(WIFI_PHY_BAND_2_4GHZ);
224 }
225 for (auto& testedBand : testedBands)
226 {
227 if ((testedBand == WIFI_PHY_BAND_2_4GHZ) &&
228 (payloadMode.GetModulationClass() >= WIFI_MOD_CLASS_OFDM))
229 {
230 knownDuration +=
231 MicroSeconds(6); // 2.4 GHz band should be at the end of the bands to test
232 }
233 Time calculatedDuration = phy->CalculateTxDuration(size, txVector, testedBand);
234 Time calculatedDurationUsingList =
235 CalculateTxDurationUsingList(std::list<uint32_t>{size},
236 std::list<uint16_t>{SU_STA_ID},
237 txVector,
238 testedBand);
239 if (calculatedDuration != knownDuration ||
240 calculatedDuration != calculatedDurationUsingList)
241 {
242 std::cerr << "size=" << size << " band=" << testedBand << " mode=" << payloadMode
243 << " channelWidth=" << +channelWidth << " guardInterval=" << guardInterval
244 << " datarate=" << payloadMode.GetDataRate(channelWidth, guardInterval, 1)
245 << " preamble=" << preamble << " known=" << knownDuration
246 << " calculated=" << calculatedDuration
247 << " calculatedUsingList=" << calculatedDurationUsingList << std::endl;
248 return false;
249 }
250 }
251 return true;
252}
253
254bool
255TxDurationTest::CheckMuTxDuration(std::list<uint32_t> sizes,
256 std::list<HeMuUserInfo> userInfos,
257 uint16_t channelWidth,
258 uint16_t guardInterval,
259 WifiPreamble preamble,
260 Time knownDuration)
261{
262 NS_ASSERT(sizes.size() == userInfos.size() && sizes.size() > 1);
264 channelWidth < std::accumulate(
265 std::begin(userInfos),
266 std::end(userInfos),
267 0,
268 [](const uint16_t prevBw, const HeMuUserInfo& info) {
269 return prevBw + HeRu::GetBandwidth(info.ru.GetRuType());
270 }),
271 "Cannot accommodate all the RUs in the provided band"); // MU-MIMO (for which allocations
272 // use the same RU) is not supported
273 WifiTxVector txVector;
274 txVector.SetPreambleType(preamble);
275 txVector.SetChannelWidth(channelWidth);
276 txVector.SetGuardInterval(guardInterval);
277 txVector.SetStbc(false);
278 txVector.SetNess(0);
279 if (IsEht(preamble))
280 {
281 txVector.SetEhtPpduType(0);
282 }
283 std::list<uint16_t> staIds;
284
285 uint16_t staId = 1;
286 for (const auto& userInfo : userInfos)
287 {
288 txVector.SetHeMuUserInfo(staId, userInfo);
289 staIds.push_back(staId++);
290 }
292 txVector.SetRuAllocation({192, 192}, 0);
293
294 Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy>();
295 std::list<WifiPhyBand> testedBands{
298 WIFI_PHY_BAND_2_4GHZ}; // Durations vary depending on frequency; test also 2.4 GHz (bug
299 // 1971)
300 for (auto& testedBand : testedBands)
301 {
302 if (testedBand == WIFI_PHY_BAND_2_4GHZ)
303 {
304 knownDuration +=
305 MicroSeconds(6); // 2.4 GHz band should be at the end of the bands to test
306 }
307 Time calculatedDuration = NanoSeconds(0);
308 uint32_t longestSize = 0;
309 auto iterStaId = staIds.begin();
310 for (auto& size : sizes)
311 {
312 Time ppduDurationForSta =
313 phy->CalculateTxDuration(size, txVector, testedBand, *iterStaId);
314 if (ppduDurationForSta > calculatedDuration)
315 {
316 calculatedDuration = ppduDurationForSta;
317 staId = *iterStaId;
318 longestSize = size;
319 }
320 ++iterStaId;
321 }
322 Time calculatedDurationUsingList =
323 CalculateTxDurationUsingList(sizes, staIds, txVector, testedBand);
324 if (calculatedDuration != knownDuration ||
325 calculatedDuration != calculatedDurationUsingList)
326 {
327 std::cerr << "size=" << longestSize << " band=" << testedBand << " staId=" << staId
328 << " nss=" << +txVector.GetNss(staId) << " mode=" << txVector.GetMode(staId)
329 << " channelWidth=" << channelWidth << " guardInterval=" << guardInterval
330 << " datarate="
331 << txVector.GetMode(staId).GetDataRate(channelWidth,
332 guardInterval,
333 txVector.GetNss(staId))
334 << " known=" << knownDuration << " calculated=" << calculatedDuration
335 << " calculatedUsingList=" << calculatedDurationUsingList << std::endl;
336 return false;
337 }
338 }
339 return true;
340}
341
342Time
344 std::list<uint16_t> staIds,
345 WifiTxVector txVector,
346 WifiPhyBand band)
347{
348 NS_ASSERT(sizes.size() == staIds.size());
349 WifiConstPsduMap psduMap;
350 auto itStaId = staIds.begin();
351 WifiMacHeader hdr;
352 hdr.SetType(WIFI_MAC_CTL_ACK); // so that size may not be empty while being as short as possible
353 for (auto& size : sizes)
354 {
355 // MAC header and FCS are to deduce from size
356 psduMap[*itStaId++] =
357 Create<WifiPsdu>(Create<Packet>(size - hdr.GetSerializedSize() - 4), hdr);
358 }
359 return WifiPhy::CalculateTxDuration(psduMap, txVector, band);
360}
361
362void
364{
365 bool retval = true;
366
367 // IEEE Std 802.11-2007 Table 18-2 "Example of LENGTH calculations for CCK"
368 retval = retval &&
371 22,
372 800,
374 MicroSeconds(744)) &&
377 22,
378 800,
380 MicroSeconds(745)) &&
383 22,
384 800,
386 MicroSeconds(746)) &&
389 22,
390 800,
392 MicroSeconds(747));
393
394 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11b CCK duration failed");
395
396 // Similar, but we add PHY preamble and header durations
397 // and we test different rates.
398 // The payload durations for modes other than 11mbb have been
399 // calculated by hand according to IEEE Std 802.11-2007 18.2.3.5
400 retval = retval &&
401 CheckTxDuration(1023,
403 22,
404 800,
406 MicroSeconds(744 + 96)) &&
407 CheckTxDuration(1024,
409 22,
410 800,
412 MicroSeconds(745 + 96)) &&
413 CheckTxDuration(1025,
415 22,
416 800,
418 MicroSeconds(746 + 96)) &&
419 CheckTxDuration(1026,
421 22,
422 800,
424 MicroSeconds(747 + 96)) &&
425 CheckTxDuration(1023,
427 22,
428 800,
430 MicroSeconds(744 + 192)) &&
431 CheckTxDuration(1024,
433 22,
434 800,
436 MicroSeconds(745 + 192)) &&
437 CheckTxDuration(1025,
439 22,
440 800,
442 MicroSeconds(746 + 192)) &&
443 CheckTxDuration(1026,
445 22,
446 800,
448 MicroSeconds(747 + 192)) &&
449 CheckTxDuration(1023,
451 22,
452 800,
454 MicroSeconds(1488 + 96)) &&
455 CheckTxDuration(1024,
457 22,
458 800,
460 MicroSeconds(1490 + 96)) &&
461 CheckTxDuration(1025,
463 22,
464 800,
466 MicroSeconds(1491 + 96)) &&
467 CheckTxDuration(1026,
469 22,
470 800,
472 MicroSeconds(1493 + 96)) &&
473 CheckTxDuration(1023,
475 22,
476 800,
478 MicroSeconds(1488 + 192)) &&
479 CheckTxDuration(1024,
481 22,
482 800,
484 MicroSeconds(1490 + 192)) &&
485 CheckTxDuration(1025,
487 22,
488 800,
490 MicroSeconds(1491 + 192)) &&
491 CheckTxDuration(1026,
493 22,
494 800,
496 MicroSeconds(1493 + 192)) &&
497 CheckTxDuration(1023,
499 22,
500 800,
502 MicroSeconds(4092 + 96)) &&
503 CheckTxDuration(1024,
505 22,
506 800,
508 MicroSeconds(4096 + 96)) &&
509 CheckTxDuration(1025,
511 22,
512 800,
514 MicroSeconds(4100 + 96)) &&
515 CheckTxDuration(1026,
517 22,
518 800,
520 MicroSeconds(4104 + 96)) &&
521 CheckTxDuration(1023,
523 22,
524 800,
526 MicroSeconds(4092 + 192)) &&
527 CheckTxDuration(1024,
529 22,
530 800,
532 MicroSeconds(4096 + 192)) &&
533 CheckTxDuration(1025,
535 22,
536 800,
538 MicroSeconds(4100 + 192)) &&
539 CheckTxDuration(1026,
541 22,
542 800,
544 MicroSeconds(4104 + 192)) &&
545 CheckTxDuration(1023,
547 22,
548 800,
550 MicroSeconds(8184 + 192)) &&
551 CheckTxDuration(1024,
553 22,
554 800,
556 MicroSeconds(8192 + 192)) &&
557 CheckTxDuration(1025,
559 22,
560 800,
562 MicroSeconds(8200 + 192)) &&
563 CheckTxDuration(1026,
565 22,
566 800,
568 MicroSeconds(8208 + 192)) &&
569 CheckTxDuration(1023,
571 22,
572 800,
574 MicroSeconds(8184 + 192)) &&
575 CheckTxDuration(1024,
577 22,
578 800,
580 MicroSeconds(8192 + 192)) &&
581 CheckTxDuration(1025,
583 22,
584 800,
586 MicroSeconds(8200 + 192)) &&
587 CheckTxDuration(1026,
589 22,
590 800,
592 MicroSeconds(8208 + 192));
593
594 // values from http://mailman.isi.edu/pipermail/ns-developers/2009-July/006226.html
595 retval = retval && CheckTxDuration(14,
597 22,
598 800,
600 MicroSeconds(304));
601
602 // values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
603 retval = retval &&
604 CheckTxDuration(1536,
606 22,
607 800,
609 MicroSeconds(1310)) &&
612 22,
613 800,
615 MicroSeconds(248)) &&
618 22,
619 800,
621 MicroSeconds(203));
622
623 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11b duration failed");
624
625 // 802.11a durations
626 // values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
627 retval = retval &&
628 CheckTxDuration(1536,
630 20,
631 800,
633 MicroSeconds(248)) &&
636 20,
637 800,
639 MicroSeconds(32)) &&
642 20,
643 800,
645 MicroSeconds(24));
646
647 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11a duration failed");
648
649 // 802.11g durations are same as 802.11a durations but with 6 us signal extension
650 retval = retval &&
651 CheckTxDuration(1536,
653 20,
654 800,
656 MicroSeconds(254)) &&
659 20,
660 800,
662 MicroSeconds(38)) &&
665 20,
666 800,
668 MicroSeconds(30));
669
670 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11g duration failed");
671
672 // 802.11n durations
673 retval =
674 retval &&
675 CheckTxDuration(1536,
677 20,
678 800,
680 MicroSeconds(228)) &&
683 CheckTxDuration(1536,
685 20,
686 400,
688 NanoSeconds(1742400)) &&
691 CheckTxDuration(1536,
693 20,
694 400,
696 NanoSeconds(226800)) &&
699 CheckTxDuration(1536,
701 40,
702 800,
704 MicroSeconds(128)) &&
707 CheckTxDuration(1536,
709 40,
710 400,
712 NanoSeconds(118800)) &&
715
716 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11n duration failed");
717
718 // 802.11ac durations
719 retval = retval &&
720 CheckTxDuration(1536,
722 20,
723 800,
725 MicroSeconds(196)) &&
728 20,
729 800,
731 MicroSeconds(48)) &&
734 20,
735 800,
737 MicroSeconds(40)) &&
738 CheckTxDuration(1536,
740 20,
741 400,
743 MicroSeconds(180)) &&
746 20,
747 400,
749 NanoSeconds(46800)) &&
752 20,
753 400,
755 NanoSeconds(39600)) &&
756 CheckTxDuration(1536,
758 40,
759 800,
761 MicroSeconds(108)) &&
764 40,
765 800,
767 MicroSeconds(40)) &&
770 40,
771 800,
773 MicroSeconds(40)) &&
774 CheckTxDuration(1536,
776 40,
777 400,
779 NanoSeconds(100800)) &&
782 40,
783 400,
785 NanoSeconds(39600)) &&
788 40,
789 400,
791 NanoSeconds(39600)) &&
792 CheckTxDuration(1536,
794 80,
795 800,
797 MicroSeconds(460)) &&
800 80,
801 800,
803 MicroSeconds(60)) &&
806 80,
807 800,
809 MicroSeconds(44)) &&
810 CheckTxDuration(1536,
812 80,
813 400,
815 NanoSeconds(417600)) &&
818 80,
819 400,
821 NanoSeconds(57600)) &&
824 80,
825 400,
827 NanoSeconds(43200)) &&
828 CheckTxDuration(1536,
830 80,
831 800,
833 MicroSeconds(68)) &&
836 80,
837 800,
839 MicroSeconds(40)) &&
842 80,
843 800,
845 MicroSeconds(40)) &&
846 CheckTxDuration(1536,
848 80,
849 400,
851 NanoSeconds(64800)) &&
854 80,
855 400,
857 NanoSeconds(39600)) &&
860 80,
861 400,
863 NanoSeconds(39600)) &&
864 CheckTxDuration(1536,
866 160,
867 800,
869 MicroSeconds(56)) &&
872 160,
873 800,
875 MicroSeconds(40)) &&
878 160,
879 800,
881 MicroSeconds(40)) &&
882 CheckTxDuration(1536,
884 160,
885 400,
887 MicroSeconds(54)) &&
890 160,
891 400,
893 NanoSeconds(39600)) &&
896 160,
897 400,
899 NanoSeconds(39600));
900
901 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11ac duration failed");
902
903 // 802.11ax SU durations
904 retval =
905 retval &&
906 CheckTxDuration(1536,
908 20,
909 800,
911 NanoSeconds(1485600)) &&
914 20,
915 800,
917 NanoSeconds(125600)) &&
919 CheckTxDuration(1536,
921 40,
922 800,
924 NanoSeconds(764800)) &&
927 CheckTxDuration(1536,
929 80,
930 800,
932 NanoSeconds(397600)) &&
935 CheckTxDuration(1536,
937 160,
938 800,
940 NanoSeconds(220800)) &&
943 160,
944 800,
946 NanoSeconds(57600)) &&
949 160,
950 800,
952 NanoSeconds(57600)) &&
953 CheckTxDuration(1536,
955 20,
956 1600,
958 NanoSeconds(1570400)) &&
961 20,
962 1600,
964 NanoSeconds(130400)) &&
967 20,
968 1600,
970 NanoSeconds(72800)) &&
971 CheckTxDuration(1536,
973 40,
974 1600,
976 NanoSeconds(807200)) &&
979 40,
980 1600,
982 NanoSeconds(87200)) &&
985 40,
986 1600,
988 NanoSeconds(58400)) &&
989 CheckTxDuration(1536,
991 80,
992 1600,
994 NanoSeconds(418400)) &&
997 80,
998 1600,
1000 NanoSeconds(72800)) &&
1001 CheckTxDuration(14,
1003 80,
1004 1600,
1006 NanoSeconds(58400)) &&
1007 CheckTxDuration(1536,
1009 160,
1010 1600,
1012 NanoSeconds(231200)) &&
1013 CheckTxDuration(76,
1015 160,
1016 1600,
1018 NanoSeconds(58400)) &&
1019 CheckTxDuration(14,
1021 160,
1022 1600,
1024 NanoSeconds(58400)) &&
1025 CheckTxDuration(1536,
1027 20,
1028 3200,
1030 MicroSeconds(1740)) &&
1033 CheckTxDuration(1536,
1035 40,
1036 3200,
1038 MicroSeconds(892)) &&
1041 CheckTxDuration(1536,
1043 80,
1044 3200,
1046 MicroSeconds(460)) &&
1049 CheckTxDuration(1536,
1051 160,
1052 3200,
1054 MicroSeconds(252)) &&
1057 CheckTxDuration(1536,
1059 20,
1060 800,
1062 NanoSeconds(139200)) &&
1063 CheckTxDuration(76,
1065 20,
1066 800,
1068 NanoSeconds(57600)) &&
1069 CheckTxDuration(14,
1071 20,
1072 800,
1074 NanoSeconds(57600)) &&
1075 CheckTxDuration(1536,
1077 40,
1078 800,
1080 NanoSeconds(98400)) &&
1081 CheckTxDuration(76,
1083 40,
1084 800,
1086 NanoSeconds(57600)) &&
1087 CheckTxDuration(14,
1089 40,
1090 800,
1092 NanoSeconds(57600)) &&
1093 CheckTxDuration(1536,
1095 80,
1096 800,
1098 NanoSeconds(71200)) &&
1099 CheckTxDuration(76,
1101 80,
1102 800,
1104 NanoSeconds(57600)) &&
1105 CheckTxDuration(14,
1107 80,
1108 800,
1110 NanoSeconds(57600)) &&
1111 CheckTxDuration(1536,
1113 160,
1114 800,
1116 NanoSeconds(57600)) &&
1117 CheckTxDuration(76,
1119 160,
1120 800,
1122 NanoSeconds(57600)) &&
1123 CheckTxDuration(14,
1125 160,
1126 800,
1128 NanoSeconds(57600)) &&
1129 CheckTxDuration(1536,
1131 20,
1132 1600,
1134 NanoSeconds(144800)) &&
1135 CheckTxDuration(76,
1137 20,
1138 1600,
1140 NanoSeconds(58400)) &&
1141 CheckTxDuration(14,
1143 20,
1144 1600,
1146 NanoSeconds(58400)) &&
1147 CheckTxDuration(1536,
1149 40,
1150 1600,
1152 NanoSeconds(101600)) &&
1153 CheckTxDuration(76,
1155 40,
1156 1600,
1158 NanoSeconds(58400)) &&
1159 CheckTxDuration(14,
1161 40,
1162 1600,
1164 NanoSeconds(58400)) &&
1165 CheckTxDuration(1536,
1167 80,
1168 1600,
1170 NanoSeconds(72800)) &&
1171 CheckTxDuration(76,
1173 80,
1174 1600,
1176 NanoSeconds(58400)) &&
1177 CheckTxDuration(14,
1179 80,
1180 1600,
1182 NanoSeconds(58400)) &&
1183 CheckTxDuration(1536,
1185 160,
1186 1600,
1188 NanoSeconds(58400)) &&
1189 CheckTxDuration(76,
1191 160,
1192 1600,
1194 NanoSeconds(58400)) &&
1195 CheckTxDuration(14,
1197 160,
1198 1600,
1200 NanoSeconds(58400)) &&
1201 CheckTxDuration(1536,
1203 20,
1204 3200,
1206 MicroSeconds(156)) &&
1209 CheckTxDuration(1536,
1211 40,
1212 3200,
1214 MicroSeconds(108)) &&
1217 CheckTxDuration(1536,
1219 80,
1220 3200,
1222 MicroSeconds(76)) &&
1225 CheckTxDuration(1536,
1227 160,
1228 3200,
1230 MicroSeconds(60)) &&
1231 CheckTxDuration(76,
1233 160,
1234 3200,
1236 MicroSeconds(60)) &&
1238
1239 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11ax SU duration failed");
1240
1241 // 802.11ax MU durations
1242 retval = retval &&
1244 std::list<uint32_t>{1536, 1536},
1245 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1, true}, 0, 1},
1246 {{HeRu::RU_242_TONE, 2, true}, 0, 1}},
1247 40,
1248 800,
1251 1493600)) // equivalent to HE_SU for 20 MHz with 2 extra HE-SIG-B (i.e. 8 us)
1252 && CheckMuTxDuration(std::list<uint32_t>{1536, 1536},
1253 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1, true}, 1, 1},
1254 {{HeRu::RU_242_TONE, 2, true}, 0, 1}},
1255 40,
1256 800,
1258 NanoSeconds(1493600)) // shouldn't change if first PSDU is shorter
1259 && CheckMuTxDuration(std::list<uint32_t>{1536, 76},
1260 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1, true}, 0, 1},
1261 {{HeRu::RU_242_TONE, 2, true}, 0, 1}},
1262 40,
1263 800,
1265 NanoSeconds(1493600));
1266
1267 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11ax MU duration failed");
1268
1269 // 802.11be MU durations
1270 retval = retval &&
1271 CheckMuTxDuration(std::list<uint32_t>{1536, 1536},
1272 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1, true}, 0, 1},
1273 {{HeRu::RU_242_TONE, 2, true}, 0, 1}},
1274 40,
1275 800,
1277 NanoSeconds(1493600)) // equivalent to 802.11ax MU
1278 && CheckMuTxDuration(std::list<uint32_t>{1536, 1536},
1279 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1, true}, 1, 1},
1280 {{HeRu::RU_242_TONE, 2, true}, 0, 1}},
1281 40,
1282 800,
1284 NanoSeconds(1493600)) // shouldn't change if first PSDU is shorter
1285 && CheckMuTxDuration(std::list<uint32_t>{1536, 76},
1286 std::list<HeMuUserInfo>{{{HeRu::RU_242_TONE, 1, true}, 0, 1},
1287 {{HeRu::RU_242_TONE, 2, true}, 0, 1}},
1288 40,
1289 800,
1291 NanoSeconds(1493600));
1292
1293 NS_TEST_EXPECT_MSG_EQ(retval, true, "an 802.11be MU duration failed");
1294
1296}
1297
1305{
1306 public:
1311 {
1313 MU_MIMO
1315
1327 HeSigBDurationTest(const std::list<HeMuUserInfo>& userInfos,
1328 const WifiMode& sigBMode,
1329 uint16_t channelWidth,
1330 MuType expectedMuType,
1331 const RuAllocation& expectedRuAllocation,
1332 const std::pair<std::size_t, std::size_t>& expectedNumUsersPerCc,
1333 Time expectedSigBDuration);
1334
1335 private:
1336 void DoRun() override;
1337
1344
1345 std::list<HeMuUserInfo> m_userInfos;
1350 std::pair<std::size_t, std::size_t>
1353};
1354
1356 const std::list<HeMuUserInfo>& userInfos,
1357 const WifiMode& sigBMode,
1358 uint16_t channelWidth,
1359 MuType expectedMuType,
1360 const RuAllocation& expectedRuAllocation,
1361 const std::pair<std::size_t, std::size_t>& expectedNumUsersPerCc,
1362 Time expectedSigBDuration)
1363 : TestCase{"Check HE-SIG-B duration computation"},
1364 m_userInfos{userInfos},
1365 m_sigBMode{sigBMode},
1366 m_channelWidth{channelWidth},
1367 m_expectedMuType{expectedMuType},
1368 m_expectedRuAllocation{expectedRuAllocation},
1369 m_expectedNumUsersPerCc{expectedNumUsersPerCc},
1370 m_expectedSigBDuration{expectedSigBDuration}
1371{
1372}
1373
1376{
1377 WifiTxVector txVector;
1380 txVector.SetGuardInterval(3200);
1381 txVector.SetStbc(false);
1382 txVector.SetNess(0);
1383 std::list<uint16_t> staIds;
1384 uint16_t staId = 1;
1385 for (const auto& userInfo : m_userInfos)
1386 {
1387 txVector.SetHeMuUserInfo(staId, userInfo);
1388 staIds.push_back(staId++);
1389 }
1390 txVector.SetSigBMode(m_sigBMode);
1391 NS_ASSERT(m_expectedMuType == OFDMA ? txVector.IsDlOfdma() : txVector.IsDlMuMimo());
1392 return txVector;
1393}
1394
1395void
1397{
1399 const auto& txVector = BuildTxVector();
1400
1401 // Verify mode for HE-SIG-B field
1402 NS_TEST_EXPECT_MSG_EQ(hePhy->GetSigMode(WIFI_PPDU_FIELD_SIG_B, txVector),
1403 m_sigBMode,
1404 "Incorrect mode used to send HE-SIG-B");
1405
1406 // Verify RU_ALLOCATION in TXVECTOR
1407 NS_TEST_EXPECT_MSG_EQ((txVector.GetRuAllocation(0) == m_expectedRuAllocation),
1408 true,
1409 "Incorrect RU_ALLOCATION");
1410
1411 // Verify number of users for content channels 1 and 2
1412 const auto& numUsersPerCc = HePpdu::GetNumRusPerHeSigBContentChannel(
1413 txVector.GetChannelWidth(),
1414 txVector.GetRuAllocation(0),
1415 txVector.IsSigBCompression(),
1416 txVector.IsSigBCompression() ? txVector.GetHeMuUserInfoMap().size() : 0);
1417 const auto contentChannels = HePpdu::GetHeSigBContentChannels(txVector, 0);
1418 NS_TEST_EXPECT_MSG_EQ(numUsersPerCc.first,
1420 "Incorrect number of users in HE-SIG-B content channel 1");
1421 NS_TEST_EXPECT_MSG_EQ(numUsersPerCc.second,
1423 "Incorrect number of users in HE-SIG-B content channel 2");
1424 NS_TEST_EXPECT_MSG_EQ(contentChannels.at(0).size(),
1426 "Incorrect number of users in HE-SIG-B content channel 1");
1427 NS_TEST_EXPECT_MSG_EQ((contentChannels.size() > 1 ? contentChannels.at(1).size() : 0),
1429 "Incorrect number of users in HE-SIG-B content channel 2");
1430
1431 // Verify total HE-SIG-B duration
1432 NS_TEST_EXPECT_MSG_EQ(hePhy->GetDuration(WIFI_PPDU_FIELD_SIG_B, txVector),
1434 "Incorrect duration for HE-SIG-B");
1435}
1436
1444{
1445 public:
1447 ~PhyHeaderSectionsTest() override;
1448 void DoRun() override;
1449
1450 private:
1460};
1461
1463 : TestCase("PHY header sections consistency")
1464{
1465}
1466
1468{
1469}
1470
1471void
1474{
1475 NS_ASSERT_MSG(obtained.size() == expected.size(),
1476 "The expected map size (" << expected.size() << ") was not obtained ("
1477 << obtained.size() << ")");
1478
1479 auto itObtained = obtained.begin();
1480 auto itExpected = expected.begin();
1481 for (; itObtained != obtained.end() || itExpected != expected.end();)
1482 {
1483 WifiPpduField field = itObtained->first;
1484 auto window = itObtained->second.first;
1485 auto mode = itObtained->second.second;
1486
1487 WifiPpduField fieldRef = itExpected->first;
1488 auto windowRef = itExpected->second.first;
1489 auto modeRef = itExpected->second.second;
1490
1492 fieldRef,
1493 "The expected PPDU field (" << fieldRef << ") was not obtained ("
1494 << field << ")");
1495 NS_TEST_EXPECT_MSG_EQ(window.first,
1496 windowRef.first,
1497 "The expected start time (" << windowRef.first
1498 << ") was not obtained (" << window.first
1499 << ")");
1500 NS_TEST_EXPECT_MSG_EQ(window.second,
1501 windowRef.second,
1502 "The expected stop time (" << windowRef.second
1503 << ") was not obtained (" << window.second
1504 << ")");
1506 modeRef,
1507 "The expected mode (" << modeRef << ") was not obtained (" << mode
1508 << ")");
1509 ++itObtained;
1510 ++itExpected;
1511 }
1512}
1513
1514void
1516{
1517 Time ppduStart = Seconds(1.0);
1518 Ptr<PhyEntity> phyEntity;
1520 WifiTxVector txVector;
1521 WifiMode nonHtMode;
1522
1523 // ==================================================================================
1524 // 11b (HR/DSSS)
1525 phyEntity = Create<DsssPhy>();
1527 txVector.SetChannelWidth(22);
1528
1529 // -> long PPDU format
1531 nonHtMode = DsssPhy::GetDsssRate1Mbps();
1532 sections = {
1533 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(144)}, nonHtMode}},
1535 {{ppduStart + MicroSeconds(144), ppduStart + MicroSeconds(192)}, nonHtMode}},
1536 };
1537 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1538
1539 // -> long PPDU format if data rate is 1 Mbps (even if preamble is tagged short)
1541 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1542
1543 // -> short PPDU format
1545 nonHtMode = DsssPhy::GetDsssRate2Mbps();
1547 sections = {
1548 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(72)}, nonHtMode}},
1550 {{ppduStart + MicroSeconds(72), ppduStart + MicroSeconds(96)}, nonHtMode}},
1551 };
1552 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1553
1554 // ==================================================================================
1555 // 11a (OFDM)
1557
1558 // -> one iteration per variant: default, 10 MHz, and 5 MHz
1559 std::map<OfdmPhyVariant, std::size_t> variants{
1560 // number to use to deduce rate and BW info for each variant
1561 {OFDM_PHY_DEFAULT, 1},
1562 {OFDM_PHY_10_MHZ, 2},
1563 {OFDM_PHY_5_MHZ, 4},
1564 };
1565 for (auto variant : variants)
1566 {
1567 phyEntity = Create<OfdmPhy>(variant.first);
1568 std::size_t ratio = variant.second;
1569 uint16_t bw = 20 / ratio; // MHz
1570 txVector.SetChannelWidth(bw);
1571 txVector.SetMode(OfdmPhy::GetOfdmRate(12000000 / ratio, bw));
1572 nonHtMode = OfdmPhy::GetOfdmRate(6000000 / ratio, bw);
1573 sections = {
1575 {{ppduStart, ppduStart + MicroSeconds(16 * ratio)}, nonHtMode}},
1577 {{ppduStart + MicroSeconds(16 * ratio), ppduStart + MicroSeconds(20 * ratio)},
1578 nonHtMode}},
1579 };
1580 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1581 }
1582
1583 // ==================================================================================
1584 // 11g (ERP-OFDM)
1585 phyEntity = Create<ErpOfdmPhy>();
1586 txVector.SetChannelWidth(20);
1587 txVector.SetMode(ErpOfdmPhy::GetErpOfdmRate(54000000));
1588 nonHtMode = ErpOfdmPhy::GetErpOfdmRate6Mbps();
1589 sections = {
1590 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
1592 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(20)}, nonHtMode}},
1593 };
1594 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1595
1596 // ==================================================================================
1597 // 11n (HT)
1598 phyEntity = Create<HtPhy>(4);
1599 txVector.SetChannelWidth(20);
1600 txVector.SetMode(HtPhy::GetHtMcs6());
1601 nonHtMode = OfdmPhy::GetOfdmRate6Mbps();
1602 WifiMode htSigMode = nonHtMode;
1603
1604 // -> HT-mixed format for 2 SS and no ESS
1606 txVector.SetNss(2);
1607 txVector.SetNess(0);
1608 sections = {
1609 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
1611 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(20)}, nonHtMode}},
1613 {{ppduStart + MicroSeconds(20), ppduStart + MicroSeconds(28)}, htSigMode}},
1615 {{ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(40)}, // 1 HT-STF + 2 HT-LTFs
1616 htSigMode}},
1617 };
1618 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1619 txVector.SetChannelWidth(20); // shouldn't have any impact
1620 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1621
1622 // -> HT-mixed format for 3 SS and 1 ESS
1623 txVector.SetNss(3);
1624 txVector.SetNess(1);
1625 sections[WIFI_PPDU_FIELD_TRAINING] = {
1626 {ppduStart + MicroSeconds(28),
1627 ppduStart + MicroSeconds(52)}, // 1 HT-STF + 5 HT-LTFs (4 data + 1 extension)
1628 htSigMode};
1629 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1630
1631 // ==================================================================================
1632 // 11ac (VHT)
1633 phyEntity = Create<VhtPhy>();
1634 txVector.SetChannelWidth(20);
1635 txVector.SetNess(0);
1636 txVector.SetMode(VhtPhy::GetVhtMcs7());
1637 WifiMode sigAMode = nonHtMode;
1638 WifiMode sigBMode = VhtPhy::GetVhtMcs0();
1639
1640 // -> VHT SU format for 5 SS
1642 txVector.SetNss(5);
1643 sections = {
1644 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
1646 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(20)}, nonHtMode}},
1648 {{ppduStart + MicroSeconds(20), ppduStart + MicroSeconds(28)}, sigAMode}},
1650 {{ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(56)}, // 1 VHT-STF + 6 VHT-LTFs
1651 sigAMode}},
1652 };
1653 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1654
1655 // -> VHT SU format for 7 SS
1656 txVector.SetNss(7);
1657 sections[WIFI_PPDU_FIELD_TRAINING] = {
1658 {ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(64)}, // 1 VHT-STF + 8 VHT-LTFs
1659 sigAMode};
1660 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1661
1662 // -> VHT MU format for 3 SS
1664 txVector.SetNss(3);
1665 sections[WIFI_PPDU_FIELD_TRAINING] = {
1666 {ppduStart + MicroSeconds(28), ppduStart + MicroSeconds(48)}, // 1 VHT-STF + 4 VHT-LTFs
1667 sigAMode};
1668 sections[WIFI_PPDU_FIELD_SIG_B] = {{ppduStart + MicroSeconds(48), ppduStart + MicroSeconds(52)},
1669 sigBMode};
1670 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1671 txVector.SetChannelWidth(80); // shouldn't have any impact
1672 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1673
1674 // ==================================================================================
1675 // 11ax (HE)
1676 phyEntity = Create<HePhy>();
1677 txVector.SetChannelWidth(20);
1678 txVector.SetNss(2); // HE-LTF duration assumed to be always 8 us for the time being (see note in
1679 // HePhy::GetTrainingDuration)
1680 txVector.SetMode(HePhy::GetHeMcs9());
1681 std::map<uint16_t, HeMuUserInfo> userInfoMap = {{1, {{HeRu::RU_106_TONE, 1, true}, 4, 2}},
1682 {2, {{HeRu::RU_106_TONE, 1, true}, 9, 1}}};
1683 sigAMode = HePhy::GetVhtMcs0();
1684 sigBMode = HePhy::GetVhtMcs4(); // because of first user info map
1685
1686 // -> HE SU format
1688 sections = {
1689 {WIFI_PPDU_FIELD_PREAMBLE, {{ppduStart, ppduStart + MicroSeconds(16)}, nonHtMode}},
1691 {{ppduStart + MicroSeconds(16), ppduStart + MicroSeconds(24)}, // L-SIG + RL-SIG
1692 nonHtMode}},
1694 {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)}, sigAMode}},
1696 {{ppduStart + MicroSeconds(32),
1697 ppduStart + MicroSeconds(52)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
1698 sigAMode}},
1699 };
1700 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1701
1702 // -> HE ER SU format
1704 sections[WIFI_PPDU_FIELD_SIG_A] = {
1705 {ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(40)}, // 16 us HE-SIG-A
1706 sigAMode};
1707 sections[WIFI_PPDU_FIELD_TRAINING] = {
1708 {ppduStart + MicroSeconds(40),
1709 ppduStart + MicroSeconds(60)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
1710 sigAMode};
1711 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1712
1713 // -> HE TB format
1715 txVector.SetHeMuUserInfo(1, userInfoMap.at(1));
1716 txVector.SetHeMuUserInfo(2, userInfoMap.at(2));
1717 sections[WIFI_PPDU_FIELD_SIG_A] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
1718 sigAMode};
1719 sections[WIFI_PPDU_FIELD_TRAINING] = {
1720 {ppduStart + MicroSeconds(32),
1721 ppduStart + MicroSeconds(56)}, // 1 HE-STF (@ 8 us) + 2 HE-LTFs (@ 8 us)
1722 sigAMode};
1723 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1724
1725 // -> HE MU format
1727 txVector.SetSigBMode(sigBMode);
1728 txVector.SetRuAllocation({96}, 0);
1729 sections[WIFI_PPDU_FIELD_SIG_A] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
1730 sigAMode};
1731 sections[WIFI_PPDU_FIELD_SIG_B] = {
1732 {ppduStart + MicroSeconds(32), ppduStart + MicroSeconds(36)}, // only one symbol
1733 sigBMode};
1734 sections[WIFI_PPDU_FIELD_TRAINING] = {
1735 {ppduStart + MicroSeconds(36),
1736 ppduStart + MicroSeconds(56)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
1737 sigBMode};
1738 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1739 txVector.SetChannelWidth(160); // shouldn't have any impact
1740 txVector.SetRuAllocation({96, 113, 113, 113, 113, 113, 113, 113}, 0);
1741
1742 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1743
1744 // ==================================================================================
1745 // 11be (EHT)
1746 sections.erase(WIFI_PPDU_FIELD_SIG_A); // FIXME: do we keep using separate type for 11be?
1747 sections.erase(WIFI_PPDU_FIELD_SIG_B); // FIXME: do we keep using separate type for 11be?
1748 phyEntity = Create<EhtPhy>();
1749 txVector.SetChannelWidth(20);
1750 txVector.SetNss(2); // EHT-LTF duration assumed to be always 8 us for the time being (see note
1751 // in HePhy::GetTrainingDuration)
1752 txVector.SetMode(EhtPhy::GetEhtMcs9());
1753 userInfoMap = {{1, {{HeRu::RU_106_TONE, 1, true}, 4, 2}},
1754 {2, {{HeRu::RU_106_TONE, 1, true}, 9, 1}}};
1755 WifiMode uSigMode = EhtPhy::GetVhtMcs0();
1756 WifiMode ehtSigMode = EhtPhy::GetVhtMcs4(); // because of first user info map
1757
1758 // -> EHT TB format
1760 txVector.SetHeMuUserInfo(1, userInfoMap.at(1));
1761 txVector.SetHeMuUserInfo(2, userInfoMap.at(2));
1762 sections[WIFI_PPDU_FIELD_U_SIG] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
1763 uSigMode};
1764 sections[WIFI_PPDU_FIELD_TRAINING] = {
1765 {ppduStart + MicroSeconds(32),
1766 ppduStart + MicroSeconds(56)}, // 1 EHT-STF (@ 8 us) + 2 EHT-LTFs (@ 8 us)
1767 uSigMode};
1768 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1769
1770 // -> EHT MU format
1772 txVector.SetEhtPpduType(0); // EHT MU transmission
1773 txVector.SetRuAllocation({96}, 0);
1774 sections[WIFI_PPDU_FIELD_U_SIG] = {{ppduStart + MicroSeconds(24), ppduStart + MicroSeconds(32)},
1775 uSigMode};
1776 sections[WIFI_PPDU_FIELD_EHT_SIG] = {
1777 {ppduStart + MicroSeconds(32), ppduStart + MicroSeconds(36)}, // only one symbol
1778 ehtSigMode};
1779 sections[WIFI_PPDU_FIELD_TRAINING] = {
1780 {ppduStart + MicroSeconds(36),
1781 ppduStart + MicroSeconds(56)}, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
1782 ehtSigMode};
1783 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1784 txVector.SetChannelWidth(160); // shouldn't have any impact
1785 txVector.SetRuAllocation({96, 113, 113, 113, 113, 113, 113, 113}, 0);
1786
1787 CheckPhyHeaderSections(phyEntity->GetPhyHeaderSections(txVector, ppduStart), sections);
1788}
1789
1797{
1798 public:
1800};
1801
1803 : TestSuite("wifi-devices-tx-duration", UNIT)
1804{
1806
1808
1809 // 20 MHz band, HeSigBDurationTest::OFDMA, even number of users per HE-SIG-B content channel
1811 {{{HeRu::RU_106_TONE, 1, true}, 11, 1}, {{HeRu::RU_106_TONE, 2, true}, 10, 4}},
1813 20,
1815 {96},
1816 std::make_pair(2, 0), // both users in HE-SIG-B content channel 1
1817 MicroSeconds(4)), // one OFDM symbol;
1819
1820 // 40 MHz band, HeSigBDurationTest::OFDMA, even number of users per HE-SIG-B content channel
1822 new HeSigBDurationTest({{{HeRu::RU_106_TONE, 1, true}, 11, 1},
1823 {{HeRu::RU_106_TONE, 2, true}, 10, 4},
1824 {{HeRu::RU_52_TONE, 5, true}, 4, 1},
1825 {{HeRu::RU_52_TONE, 6, true}, 6, 2},
1826 {{HeRu::RU_52_TONE, 7, true}, 5, 3},
1827 {{HeRu::RU_52_TONE, 8, true}, 6, 2}},
1829 40,
1831 {96, 112},
1832 std::make_pair(2, 4), // two users in HE-SIG-B content channel 1 and
1833 // four users in HE-SIG-B content channel 2
1834 MicroSeconds(4)), // one OFDM symbol;
1836
1837 // 40 MHz band, HeSigBDurationTest::OFDMA, odd number of users per HE-SIG-B content channel
1839 new HeSigBDurationTest({{{HeRu::RU_106_TONE, 1, true}, 11, 1},
1840 {{HeRu::RU_106_TONE, 2, true}, 10, 4},
1841 {{HeRu::RU_52_TONE, 5, true}, 4, 1},
1842 {{HeRu::RU_52_TONE, 6, true}, 6, 2},
1843 {{HeRu::RU_52_TONE, 7, true}, 5, 3},
1844 {{HeRu::RU_52_TONE, 8, true}, 6, 2},
1845 {{HeRu::RU_26_TONE, 14, true}, 3, 1}},
1847 40,
1849 {96, 15},
1850 std::make_pair(2, 5), // two users in HE-SIG-B content channel 1 and
1851 // five users in HE-SIG-B content channel 2
1852 MicroSeconds(8)), // two OFDM symbols
1854
1855 // 80 MHz band, OFDMA
1857 new HeSigBDurationTest({{{HeRu::RU_106_TONE, 1, true}, 11, 1},
1858 {{HeRu::RU_106_TONE, 2, true}, 10, 4},
1859 {{HeRu::RU_52_TONE, 5, true}, 4, 1},
1860 {{HeRu::RU_52_TONE, 6, true}, 6, 2},
1861 {{HeRu::RU_52_TONE, 7, true}, 5, 3},
1862 {{HeRu::RU_52_TONE, 8, true}, 6, 2},
1863 {{HeRu::RU_26_TONE, 14, true}, 3, 1},
1864 {{HeRu::RU_242_TONE, 3, true}, 1, 1},
1865 {{HeRu::RU_242_TONE, 4, true}, 4, 1}},
1867 80,
1869 {96, 15, 192, 192},
1870 std::make_pair(3, 6), // three users in HE-SIG-B content channel 1
1871 // and six users in HE-SIG-B content channel 2
1872 MicroSeconds(16)), // four OFDM symbols
1874
1875 // 160 MHz band, OFDMA
1877 new HeSigBDurationTest({{{HeRu::RU_106_TONE, 1, true}, 11, 1},
1878 {{HeRu::RU_106_TONE, 2, true}, 10, 4},
1879 {{HeRu::RU_52_TONE, 5, true}, 4, 1},
1880 {{HeRu::RU_52_TONE, 6, true}, 6, 2},
1881 {{HeRu::RU_52_TONE, 7, true}, 5, 3},
1882 {{HeRu::RU_52_TONE, 8, true}, 6, 2},
1883 {{HeRu::RU_26_TONE, 14, true}, 3, 1},
1884 {{HeRu::RU_242_TONE, 3, true}, 1, 1},
1885 {{HeRu::RU_242_TONE, 4, true}, 4, 1},
1886 {{HeRu::RU_996_TONE, 1, false}, 1, 1}},
1888 160,
1890 {96, 15, 192, 192, 208, 208, 208, 208},
1891 std::make_pair(4, 7), // four users in HE-SIG-B content channel 1 and
1892 // seven users in HE-SIG-B content channel 2
1893 MicroSeconds(20)), // five OFDM symbols
1895
1896 // 20 MHz band, HeSigBDurationTest::OFDMA, one unallocated RU at the middle
1898 new HeSigBDurationTest({{{HeRu::RU_26_TONE, 1, true}, 11, 1},
1899 {{HeRu::RU_26_TONE, 2, true}, 11, 1},
1900 {{HeRu::RU_26_TONE, 3, true}, 11, 1},
1901 {{HeRu::RU_26_TONE, 4, true}, 11, 1},
1902 {{HeRu::RU_26_TONE, 6, true}, 11, 1},
1903 {{HeRu::RU_26_TONE, 7, true}, 11, 1},
1904 {{HeRu::RU_26_TONE, 8, true}, 11, 1},
1905 {{HeRu::RU_26_TONE, 9, true}, 11, 1}},
1907 20,
1909 {0},
1910 std::make_pair(9, 0), // 9 users in HE-SIG-B content channel 1
1911 MicroSeconds(8)), // two OFDM symbols
1913
1914 // 40 MHz band, HeSigBDurationTest::OFDMA, unallocated RUs at the begin and at the end of the
1915 // first 20 MHz subband and in the middle of the second 20 MHz subband
1917 new HeSigBDurationTest({{{HeRu::RU_52_TONE, 2, true}, 10, 1},
1918 {{HeRu::RU_52_TONE, 3, true}, 10, 2},
1919 {{HeRu::RU_52_TONE, 5, true}, 11, 1},
1920 {{HeRu::RU_52_TONE, 8, true}, 11, 2}},
1922 40,
1924 {112, 112},
1925 std::make_pair(4, 4), // 4 users in both HE-SIG-B content channels
1926 MicroSeconds(4)), // two OFDM symbols
1928
1929 // 40 MHz band, HeSigBDurationTest::OFDMA, one unallocated RUs in the first 20 MHz subband and
1930 // two unallocated RUs in second 20 MHz subband
1932 new HeSigBDurationTest({{{HeRu::RU_52_TONE, 1, true}, 10, 1},
1933 {{HeRu::RU_52_TONE, 2, true}, 10, 2},
1934 {{HeRu::RU_52_TONE, 3, true}, 11, 1},
1935 {{HeRu::RU_52_TONE, 5, true}, 11, 2},
1936 {{HeRu::RU_52_TONE, 6, true}, 11, 3}},
1938 40,
1940 {112, 112},
1941 std::make_pair(4, 4), // 4 users in both HE-SIG-B content channels
1942 MicroSeconds(4)), // two OFDM symbols
1944
1945 // 20 MHz band, MU-MIMO, 2 users
1947 {{{HeRu::RU_242_TONE, 1, true}, 11, 1}, {{HeRu::RU_242_TONE, 1, true}, 10, 4}},
1949 20,
1951 {192},
1952 std::make_pair(2, 0), // both users in HE-SIG-B content channel 1
1953 MicroSeconds(4)), // one OFDM symbol
1955
1956 // 20 MHz band, MU-MIMO, 3 users
1958 new HeSigBDurationTest({{{HeRu::RU_242_TONE, 1, true}, 4, 3},
1959 {{HeRu::RU_242_TONE, 1, true}, 5, 2},
1960 {{HeRu::RU_242_TONE, 1, true}, 6, 1}},
1962 20,
1964 {192},
1965 std::make_pair(3, 0), // all users in HE-SIG-B content channel 1
1966 MicroSeconds(4)), // one OFDM symbol
1968
1969 // 20 MHz band, MU-MIMO, 4 users
1971 new HeSigBDurationTest({{{HeRu::RU_242_TONE, 1, true}, 4, 1},
1972 {{HeRu::RU_242_TONE, 1, true}, 5, 2},
1973 {{HeRu::RU_242_TONE, 1, true}, 6, 3},
1974 {{HeRu::RU_242_TONE, 1, true}, 7, 2}},
1976 20,
1978 {192},
1979 std::make_pair(4, 0), // all users in HE-SIG-B content channel 1
1980 MicroSeconds(4)), // one OFDM symbol
1982
1983 // 20 MHz band, MU-MIMO, 6 users
1985 new HeSigBDurationTest({{{HeRu::RU_242_TONE, 1, true}, 4, 1},
1986 {{HeRu::RU_242_TONE, 1, true}, 5, 1},
1987 {{HeRu::RU_242_TONE, 1, true}, 6, 2},
1988 {{HeRu::RU_242_TONE, 1, true}, 7, 2},
1989 {{HeRu::RU_242_TONE, 1, true}, 8, 1},
1990 {{HeRu::RU_242_TONE, 1, true}, 9, 1}},
1992 20,
1994 {192},
1995 std::make_pair(6, 0), // all users in HE-SIG-B content channel 1
1996 MicroSeconds(4)), // one OFDM symbol
1998
1999 // 20 MHz band, MU-MIMO, 8 users
2001 new HeSigBDurationTest({{{HeRu::RU_242_TONE, 1, true}, 4, 1},
2002 {{HeRu::RU_242_TONE, 1, true}, 5, 1},
2003 {{HeRu::RU_242_TONE, 1, true}, 6, 1},
2004 {{HeRu::RU_242_TONE, 1, true}, 7, 1},
2005 {{HeRu::RU_242_TONE, 1, true}, 8, 1},
2006 {{HeRu::RU_242_TONE, 1, true}, 9, 1},
2007 {{HeRu::RU_242_TONE, 1, true}, 10, 1},
2008 {{HeRu::RU_242_TONE, 1, true}, 11, 1}},
2010 20,
2012 {192},
2013 std::make_pair(8, 0), // all users in HE-SIG-B content channel 1
2014 MicroSeconds(8)), // two OFDM symbols
2016
2017 // 40 MHz band, MU-MIMO, 2 users
2019 {{{HeRu::RU_484_TONE, 1, true}, 11, 1}, {{HeRu::RU_484_TONE, 1, true}, 10, 4}},
2021 40,
2023 {200, 200},
2024 std::make_pair(1, 1), // users equally split between the two content channels
2025 MicroSeconds(4)), // one OFDM symbol
2027
2028 // 40 MHz band, MU-MIMO, 3 users
2031 {{{HeRu::RU_484_TONE, 1, true}, 4, 3},
2032 {{HeRu::RU_484_TONE, 1, true}, 5, 2},
2033 {{HeRu::RU_484_TONE, 1, true}, 6, 1}},
2035 40,
2037 {200, 200},
2038 std::make_pair(2, 1), // 2 users in content channel 1 and 1 user in content channel 2
2039 MicroSeconds(4)), // one OFDM symbol
2041
2042 // 40 MHz band, MU-MIMO, 4 users
2044 {{{HeRu::RU_484_TONE, 1, true}, 4, 1},
2045 {{HeRu::RU_484_TONE, 1, true}, 5, 2},
2046 {{HeRu::RU_484_TONE, 1, true}, 6, 3},
2047 {{HeRu::RU_484_TONE, 1, true}, 7, 2}},
2049 40,
2051 {200, 200},
2052 std::make_pair(2, 2), // users equally split between the two content channels
2053 MicroSeconds(4)), // one OFDM symbol
2055
2056 // 40 MHz band, MU-MIMO, 6 users
2058 {{{HeRu::RU_484_TONE, 1, true}, 4, 1},
2059 {{HeRu::RU_484_TONE, 1, true}, 5, 1},
2060 {{HeRu::RU_484_TONE, 1, true}, 6, 2},
2061 {{HeRu::RU_484_TONE, 1, true}, 7, 2},
2062 {{HeRu::RU_484_TONE, 1, true}, 8, 1},
2063 {{HeRu::RU_484_TONE, 1, true}, 9, 1}},
2065 40,
2067 {200, 200},
2068 std::make_pair(3, 3), // users equally split between the two content channels
2069 MicroSeconds(4)), // one OFDM symbol
2071
2072 // 40 MHz band, MU-MIMO, 8 users
2074 {{{HeRu::RU_484_TONE, 1, true}, 4, 1},
2075 {{HeRu::RU_484_TONE, 1, true}, 5, 1},
2076 {{HeRu::RU_484_TONE, 1, true}, 6, 1},
2077 {{HeRu::RU_484_TONE, 1, true}, 7, 1},
2078 {{HeRu::RU_484_TONE, 1, true}, 8, 1},
2079 {{HeRu::RU_484_TONE, 1, true}, 9, 1},
2080 {{HeRu::RU_484_TONE, 1, true}, 10, 1},
2081 {{HeRu::RU_484_TONE, 1, true}, 11, 1}},
2083 40,
2085 {200, 200},
2086 std::make_pair(4, 4), // users equally split between the two content channels
2087 MicroSeconds(4)), // one OFDM symbol
2089
2090 // 80 MHz band, MU-MIMO, 2 users
2092 {{{HeRu::RU_996_TONE, 1, true}, 11, 1}, {{HeRu::RU_996_TONE, 1, true}, 10, 4}},
2094 80,
2096 {208, 208, 208, 208},
2097 std::make_pair(1, 1), // users equally split between the two content channels
2098 MicroSeconds(4)), // one OFDM symbol
2100
2101 // 80 MHz band, MU-MIMO, 3 users
2104 {{{HeRu::RU_996_TONE, 1, true}, 4, 3},
2105 {{HeRu::RU_996_TONE, 1, true}, 5, 2},
2106 {{HeRu::RU_996_TONE, 1, true}, 6, 1}},
2108 80,
2110 {208, 208, 208, 208},
2111 std::make_pair(2, 1), // 2 users in content channel 1 and 1 user in content channel 2
2112 MicroSeconds(4)), // one OFDM symbol
2114
2115 // 80 MHz band, MU-MIMO, 4 users
2117 {{{HeRu::RU_996_TONE, 1, true}, 4, 1},
2118 {{HeRu::RU_996_TONE, 1, true}, 5, 2},
2119 {{HeRu::RU_996_TONE, 1, true}, 6, 3},
2120 {{HeRu::RU_996_TONE, 1, true}, 7, 2}},
2122 80,
2124 {208, 208, 208, 208},
2125 std::make_pair(2, 2), // users equally split between the two content channels
2126 MicroSeconds(4)), // one OFDM symbol
2128
2129 // 80 MHz band, MU-MIMO, 6 users
2131 {{{HeRu::RU_996_TONE, 1, true}, 4, 1},
2132 {{HeRu::RU_996_TONE, 1, true}, 5, 1},
2133 {{HeRu::RU_996_TONE, 1, true}, 6, 2},
2134 {{HeRu::RU_996_TONE, 1, true}, 7, 2},
2135 {{HeRu::RU_996_TONE, 1, true}, 8, 1},
2136 {{HeRu::RU_996_TONE, 1, true}, 9, 1}},
2138 80,
2140 {208, 208, 208, 208},
2141 std::make_pair(3, 3), // users equally split between the two content channels
2142 MicroSeconds(4)), // one OFDM symbol
2144
2145 // 80 MHz band, MU-MIMO, 8 users
2147 {{{HeRu::RU_996_TONE, 1, true}, 4, 1},
2148 {{HeRu::RU_996_TONE, 1, true}, 5, 1},
2149 {{HeRu::RU_996_TONE, 1, true}, 6, 1},
2150 {{HeRu::RU_996_TONE, 1, true}, 7, 1},
2151 {{HeRu::RU_996_TONE, 1, true}, 8, 1},
2152 {{HeRu::RU_996_TONE, 1, true}, 9, 1},
2153 {{HeRu::RU_996_TONE, 1, true}, 10, 1},
2154 {{HeRu::RU_996_TONE, 1, true}, 11, 1}},
2156 80,
2158 {208, 208, 208, 208},
2159 std::make_pair(4, 4), // users equally split between the two content channels
2160 MicroSeconds(4)), // one OFDM symbol
2162
2163 // 160 MHz band, MU-MIMO, 2 users
2166 {{{HeRu::RU_2x996_TONE, 1, true}, 11, 1}, {{HeRu::RU_2x996_TONE, 1, true}, 10, 4}},
2168 160,
2170 {208, 208, 208, 208, 208, 208, 208, 208},
2171 std::make_pair(1, 1), // users equally split between the two content channels
2172 MicroSeconds(4)), // one OFDM symbol
2174
2175 // 160 MHz band, MU-MIMO, 3 users
2178 {{{HeRu::RU_2x996_TONE, 1, true}, 4, 3},
2179 {{HeRu::RU_2x996_TONE, 1, true}, 5, 2},
2180 {{HeRu::RU_2x996_TONE, 1, true}, 6, 1}},
2182 160,
2184 {208, 208, 208, 208, 208, 208, 208, 208},
2185 std::make_pair(2, 1), // 2 users in content channel 1 and 1 user in content channel 2
2186 MicroSeconds(4)), // one OFDM symbol
2188
2189 // 160 MHz band, MU-MIMO, 4 users
2191 {{{HeRu::RU_2x996_TONE, 1, true}, 4, 1},
2192 {{HeRu::RU_2x996_TONE, 1, true}, 5, 2},
2193 {{HeRu::RU_2x996_TONE, 1, true}, 6, 3},
2194 {{HeRu::RU_2x996_TONE, 1, true}, 7, 2}},
2196 160,
2198 {208, 208, 208, 208, 208, 208, 208, 208},
2199 std::make_pair(2, 2), // users equally split between the two content channels
2200 MicroSeconds(4)), // one OFDM symbol
2202
2203 // 160 MHz band, MU-MIMO, 6 users
2205 {{{HeRu::RU_2x996_TONE, 1, true}, 4, 1},
2206 {{HeRu::RU_2x996_TONE, 1, true}, 5, 1},
2207 {{HeRu::RU_2x996_TONE, 1, true}, 6, 2},
2208 {{HeRu::RU_2x996_TONE, 1, true}, 7, 2},
2209 {{HeRu::RU_2x996_TONE, 1, true}, 8, 1},
2210 {{HeRu::RU_2x996_TONE, 1, true}, 9, 1}},
2212 160,
2214 {208, 208, 208, 208, 208, 208, 208, 208},
2215 std::make_pair(3, 3), // users equally split between the two content channels
2216 MicroSeconds(4)), // one OFDM symbol
2218
2219 // 160 MHz band, MU-MIMO, 8 users
2221 {{{HeRu::RU_2x996_TONE, 1, true}, 4, 1},
2222 {{HeRu::RU_2x996_TONE, 1, true}, 5, 1},
2223 {{HeRu::RU_2x996_TONE, 1, true}, 6, 1},
2224 {{HeRu::RU_2x996_TONE, 1, true}, 7, 1},
2225 {{HeRu::RU_2x996_TONE, 1, true}, 8, 1},
2226 {{HeRu::RU_2x996_TONE, 1, true}, 9, 1},
2227 {{HeRu::RU_2x996_TONE, 1, true}, 10, 1},
2228 {{HeRu::RU_2x996_TONE, 1, true}, 11, 1}},
2230 160,
2232 {208, 208, 208, 208, 208, 208, 208, 208},
2233 std::make_pair(4, 4), // users equally split between the two content channels
2234 MicroSeconds(4)), // one OFDM symbol
2236}
2237
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)
HeSigBDurationTest(const std::list< HeMuUserInfo > &userInfos, const WifiMode &sigBMode, uint16_t channelWidth, MuType expectedMuType, const RuAllocation &expectedRuAllocation, const std::pair< std::size_t, std::size_t > &expectedNumUsersPerCc, Time expectedSigBDuration)
Constructor.
RuAllocation m_expectedRuAllocation
Expected RU_ALLOCATION.
Time m_expectedSigBDuration
Expected duration of the HE-SIG-B header.
WifiMode m_sigBMode
Mode used to transmit HE-SIG-B.
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.
uint16_t m_channelWidth
Channel width in MHz.
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.
static bool CheckMuTxDuration(std::list< uint32_t > sizes, std::list< HeMuUserInfo > userInfos, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration)
Check if the overall Tx duration returned by WifiPhy for a MU PPDU corresponds to a known value.
bool CheckTxDuration(uint32_t size, WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration)
Check if the overall tx duration returned by InterferenceHelper corresponds to a known value.
bool CheckPayloadDuration(uint32_t size, WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration)
Check if the payload tx duration returned by InterferenceHelper corresponds to a known value.
void DoRun() override
Implementation to actually run this TestCase.
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 std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(uint16_t channelWidth, const RuAllocation &ruAllocation, bool sigBCompression, uint8_t numMuMimoUsers)
Get the number of STAs per HE-SIG-B content channel.
Definition: he-ppdu.cc:486
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:554
RuType GetRuType() const
Get the RU type.
Definition: he-ru.cc:454
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:763
@ RU_26_TONE
Definition: he-ru.h:42
@ RU_484_TONE
Definition: he-ru.h:46
@ RU_996_TONE
Definition: he-ru.h:47
@ RU_106_TONE
Definition: he-ru.h:44
@ RU_52_TONE
Definition: he-ru.h:43
@ RU_242_TONE
Definition: he-ru.h:45
@ RU_2x996_TONE
Definition: he-ru.h:48
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.
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, uint16_t bw=20)
Return a WifiMode for OFDM corresponding to the provided rate and the channel bandwidth (20,...
Definition: ofdm-phy.cc:411
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
Definition: phy-entity.h:326
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
encapsulates test code
Definition: test.h:1060
@ QUICK
Fast test.
Definition: test.h:1065
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
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:51
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1496
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:704
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 SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetGuardInterval(uint16_t 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.
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:66
#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:86
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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:251
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1349
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1361
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1325
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
WifiPpduField
The type of PPDU field (grouped for convenience)
@ 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.
Definition: wifi-phy-band.h:39
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
@ 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:46
@ OFDM_PHY_DEFAULT
Definition: ofdm-phy.h:45
@ OFDM_PHY_5_MHZ
Definition: ofdm-phy.h:47
@ 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.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
bool IsEht(WifiPreamble preamble)
Return true if a preamble corresponds to an EHT transmission.
@ WIFI_MAC_CTL_ACK
std::vector< uint8_t > RuAllocation
8 bit RU_ALLOCATION per 20 MHz
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
HE MU specific user transmission parameters.
HeRu::RuSpec ru
RU specification.
static TxDurationTestSuite g_txDurationTestSuite
the test suite