A Discrete-Event Network Simulator
API
tx-duration-test.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2009 CTTC
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Nicola Baldo <nbaldo@cttc.es>
19 * S├ębastien Deronne <sebastien.deronne@gmail.com>
20 */
21
22#include "ns3/log.h"
23#include "ns3/simulator.h"
24#include "ns3/test.h"
25#include "ns3/yans-wifi-phy.h"
26#include "ns3/he-ru.h"
27#include "ns3/wifi-psdu.h"
28#include "ns3/packet.h"
29#include "ns3/dsss-phy.h"
30#include "ns3/erp-ofdm-phy.h"
31#include "ns3/eht-phy.h" //includes OFDM, HT, VHT and HE
32#include <numeric>
33
34using namespace ns3;
35
36NS_LOG_COMPONENT_DEFINE ("InterferenceHelperTxDurationTest");
37
45{
46public:
48 virtual ~TxDurationTest ();
49 void DoRun (void) override;
50
51
52private:
66 bool CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration);
67
81 bool CheckTxDuration (uint32_t size, WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration);
82
96 static bool CheckMuTxDuration (std::list<uint32_t> sizes, std::list<HeMuUserInfo> userInfos,
97 uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble,
98 Time knownDuration);
99
114 static Time CalculateTxDurationUsingList (std::list<uint32_t> sizes, std::list<uint16_t> staIds,
115 WifiTxVector txVector, WifiPhyBand band);
116};
117
119 : TestCase ("Wifi TX Duration")
120{
121}
122
124{
125}
126
127bool
128TxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration)
129{
130 WifiTxVector txVector;
131 txVector.SetMode (payloadMode);
132 txVector.SetPreambleType (preamble);
133 txVector.SetChannelWidth (channelWidth);
134 txVector.SetGuardInterval (guardInterval);
135 txVector.SetNss (1);
136 txVector.SetStbc (0);
137 txVector.SetNess (0);
138 std::list<WifiPhyBand> testedBands;
139 Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy> ();
140 if (payloadMode.GetModulationClass () >= WIFI_MOD_CLASS_OFDM)
141 {
142 testedBands.push_back (WIFI_PHY_BAND_5GHZ);
143 }
144 if (payloadMode.GetModulationClass () >= WIFI_MOD_CLASS_HE)
145 {
146 testedBands.push_back (WIFI_PHY_BAND_6GHZ);
147 }
148 if (payloadMode.GetModulationClass () != WIFI_MOD_CLASS_VHT)
149 {
150 testedBands.push_back (WIFI_PHY_BAND_2_4GHZ);
151 }
152 for (auto & testedBand : testedBands)
153 {
154 if ((testedBand == WIFI_PHY_BAND_2_4GHZ) && (payloadMode.GetModulationClass () >= WIFI_MOD_CLASS_OFDM))
155 {
156 knownDuration += MicroSeconds (6); //2.4 GHz band should be at the end of the bands to test
157 }
158 Time calculatedDuration = phy->GetPayloadDuration (size, txVector, testedBand);
159 if (calculatedDuration != knownDuration)
160 {
161 std::cerr << "size=" << size
162 << " band=" << testedBand
163 << " mode=" << payloadMode
164 << " channelWidth=" << channelWidth
165 << " guardInterval=" << guardInterval
166 << " datarate=" << payloadMode.GetDataRate (channelWidth, guardInterval, 1)
167 << " known=" << knownDuration
168 << " calculated=" << calculatedDuration
169 << std::endl;
170 return false;
171 }
172 }
173 return true;
174}
175
176bool
177TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble, Time knownDuration)
178{
179 WifiTxVector txVector;
180 txVector.SetMode (payloadMode);
181 txVector.SetPreambleType (preamble);
182 txVector.SetChannelWidth (channelWidth);
183 txVector.SetGuardInterval (guardInterval);
184 txVector.SetNss (1);
185 txVector.SetStbc (0);
186 txVector.SetNess (0);
187 std::list<WifiPhyBand> testedBands;
188 Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy> ();
189 if (payloadMode.GetModulationClass () >= WIFI_MOD_CLASS_OFDM)
190 {
191 testedBands.push_back (WIFI_PHY_BAND_5GHZ);
192 }
193 if (payloadMode.GetModulationClass () >= WIFI_MOD_CLASS_HE)
194 {
195 testedBands.push_back (WIFI_PHY_BAND_6GHZ);
196 }
197 if (payloadMode.GetModulationClass () != WIFI_MOD_CLASS_VHT)
198 {
199 testedBands.push_back (WIFI_PHY_BAND_2_4GHZ);
200 }
201 for (auto & testedBand : testedBands)
202 {
203 if ((testedBand == WIFI_PHY_BAND_2_4GHZ) && (payloadMode.GetModulationClass () >= WIFI_MOD_CLASS_OFDM))
204 {
205 knownDuration += MicroSeconds (6); //2.4 GHz band should be at the end of the bands to test
206 }
207 Time calculatedDuration = phy->CalculateTxDuration (size, txVector, testedBand);
208 Time calculatedDurationUsingList = CalculateTxDurationUsingList (std::list<uint32_t> {size}, std::list<uint16_t> {SU_STA_ID},
209 txVector, testedBand);
210 if (calculatedDuration != knownDuration || calculatedDuration != calculatedDurationUsingList)
211 {
212 std::cerr << "size=" << size
213 << " band=" << testedBand
214 << " mode=" << payloadMode
215 << " channelWidth=" << +channelWidth
216 << " guardInterval=" << guardInterval
217 << " datarate=" << payloadMode.GetDataRate (channelWidth, guardInterval, 1)
218 << " preamble=" << preamble
219 << " known=" << knownDuration
220 << " calculated=" << calculatedDuration
221 << " calculatedUsingList=" << calculatedDurationUsingList
222 << std::endl;
223 return false;
224 }
225 }
226 return true;
227}
228
229bool
230TxDurationTest::CheckMuTxDuration (std::list<uint32_t> sizes, std::list<HeMuUserInfo> userInfos,
231 uint16_t channelWidth, uint16_t guardInterval, WifiPreamble preamble,
232 Time knownDuration)
233{
234 NS_ASSERT (sizes.size () == userInfos.size () && sizes.size () > 1);
235 NS_ABORT_MSG_IF (channelWidth < std::accumulate (std::begin (userInfos), std::end (userInfos), 0,
236 [](const uint16_t prevBw, const HeMuUserInfo &info)
237 { return prevBw + HeRu::GetBandwidth (info.ru.GetRuType ()); }),
238 "Cannot accommodate all the RUs in the provided band"); //MU-MIMO (for which allocations use the same RU) is not supported
239 WifiTxVector txVector;
240 txVector.SetPreambleType (preamble);
241 txVector.SetChannelWidth (channelWidth);
242 txVector.SetGuardInterval (guardInterval);
243 txVector.SetStbc (0);
244 txVector.SetNess (0);
245 std::list<uint16_t> staIds;
246 uint16_t staId = 1;
247 for (const auto & userInfo : userInfos)
248 {
249 txVector.SetHeMuUserInfo (staId, userInfo);
250 staIds.push_back (staId++);
251 }
252 Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy> ();
253 std::list<WifiPhyBand> testedBands {WIFI_PHY_BAND_5GHZ, WIFI_PHY_BAND_6GHZ, WIFI_PHY_BAND_2_4GHZ}; //Durations vary depending on frequency; test also 2.4 GHz (bug 1971)
254 for (auto & testedBand : testedBands)
255 {
256 if (testedBand == WIFI_PHY_BAND_2_4GHZ)
257 {
258 knownDuration += MicroSeconds (6); //2.4 GHz band should be at the end of the bands to test
259 }
260 Time calculatedDuration = NanoSeconds (0);
261 uint32_t longuestSize = 0;
262 auto iterStaId = staIds.begin ();
263 for (auto & size : sizes)
264 {
265 Time ppduDurationForSta = phy->CalculateTxDuration (size, txVector, testedBand, *iterStaId);
266 if (ppduDurationForSta > calculatedDuration)
267 {
268 calculatedDuration = ppduDurationForSta;
269 staId = *iterStaId;
270 longuestSize = size;
271 }
272 ++iterStaId;
273 }
274 Time calculatedDurationUsingList = CalculateTxDurationUsingList (sizes, staIds, txVector, testedBand);
275 if (calculatedDuration != knownDuration || calculatedDuration != calculatedDurationUsingList)
276 {
277 std::cerr << "size=" << longuestSize
278 << " band=" << testedBand
279 << " staId=" << staId
280 << " nss=" << +txVector.GetNss (staId)
281 << " mode=" << txVector.GetMode (staId)
282 << " channelWidth=" << channelWidth
283 << " guardInterval=" << guardInterval
284 << " datarate=" << txVector.GetMode (staId).GetDataRate (channelWidth, guardInterval, txVector.GetNss (staId))
285 << " known=" << knownDuration
286 << " calculated=" << calculatedDuration
287 << " calculatedUsingList=" << calculatedDurationUsingList
288 << std::endl;
289 return false;
290 }
291 }
292 return true;
293}
294
295Time
296TxDurationTest::CalculateTxDurationUsingList (std::list<uint32_t> sizes, std::list<uint16_t> staIds,
297 WifiTxVector txVector, WifiPhyBand band)
298{
299 NS_ASSERT (sizes.size () == staIds.size ());
300 WifiConstPsduMap psduMap;
301 auto itStaId = staIds.begin ();
302 WifiMacHeader hdr;
303 hdr.SetType (WIFI_MAC_CTL_ACK); //so that size may not be empty while being as short as possible
304 for (auto & size : sizes)
305 {
306 // MAC header and FCS are to deduce from size
307 psduMap[*itStaId++] = Create<WifiPsdu> (Create<Packet> (size - hdr.GetSerializedSize () - 4), hdr);
308 }
309 return WifiPhy::CalculateTxDuration (psduMap, txVector, band);
310}
311
312void
314{
315 bool retval = true;
316
317 //IEEE Std 802.11-2007 Table 18-2 "Example of LENGTH calculations for CCK"
318 retval = retval
319 && CheckPayloadDuration (1023, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (744))
320 && CheckPayloadDuration (1024, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (745))
321 && CheckPayloadDuration (1025, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (746))
322 && CheckPayloadDuration (1026, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (747));
323
324 NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11b CCK duration failed");
325
326 //Similar, but we add PHY preamble and header durations
327 //and we test different rates.
328 //The payload durations for modes other than 11mbb have been
329 //calculated by hand according to IEEE Std 802.11-2007 18.2.3.5
330 retval = retval
331 && CheckTxDuration (1023, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (744 + 96))
332 && CheckTxDuration (1024, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (745 + 96))
333 && CheckTxDuration (1025, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (746 + 96))
334 && CheckTxDuration (1026, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (747 + 96))
335 && CheckTxDuration (1023, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (744 + 192))
336 && CheckTxDuration (1024, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (745 + 192))
337 && CheckTxDuration (1025, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (746 + 192))
338 && CheckTxDuration (1026, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (747 + 192))
339 && CheckTxDuration (1023, DsssPhy::GetDsssRate5_5Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (1488 + 96))
340 && CheckTxDuration (1024, DsssPhy::GetDsssRate5_5Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (1490 + 96))
341 && CheckTxDuration (1025, DsssPhy::GetDsssRate5_5Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (1491 + 96))
342 && CheckTxDuration (1026, DsssPhy::GetDsssRate5_5Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (1493 + 96))
343 && CheckTxDuration (1023, DsssPhy::GetDsssRate5_5Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (1488 + 192))
344 && CheckTxDuration (1024, DsssPhy::GetDsssRate5_5Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (1490 + 192))
345 && CheckTxDuration (1025, DsssPhy::GetDsssRate5_5Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (1491 + 192))
346 && CheckTxDuration (1026, DsssPhy::GetDsssRate5_5Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (1493 + 192))
347 && CheckTxDuration (1023, DsssPhy::GetDsssRate2Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (4092 + 96))
348 && CheckTxDuration (1024, DsssPhy::GetDsssRate2Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (4096 + 96))
349 && CheckTxDuration (1025, DsssPhy::GetDsssRate2Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (4100 + 96))
350 && CheckTxDuration (1026, DsssPhy::GetDsssRate2Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (4104 + 96))
351 && CheckTxDuration (1023, DsssPhy::GetDsssRate2Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (4092 + 192))
352 && CheckTxDuration (1024, DsssPhy::GetDsssRate2Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (4096 + 192))
353 && CheckTxDuration (1025, DsssPhy::GetDsssRate2Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (4100 + 192))
354 && CheckTxDuration (1026, DsssPhy::GetDsssRate2Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (4104 + 192))
355 && CheckTxDuration (1023, DsssPhy::GetDsssRate1Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (8184 + 192))
356 && CheckTxDuration (1024, DsssPhy::GetDsssRate1Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (8192 + 192))
357 && CheckTxDuration (1025, DsssPhy::GetDsssRate1Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (8200 + 192))
358 && CheckTxDuration (1026, DsssPhy::GetDsssRate1Mbps (), 22, 800, WIFI_PREAMBLE_SHORT, MicroSeconds (8208 + 192))
359 && CheckTxDuration (1023, DsssPhy::GetDsssRate1Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (8184 + 192))
360 && CheckTxDuration (1024, DsssPhy::GetDsssRate1Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (8192 + 192))
361 && CheckTxDuration (1025, DsssPhy::GetDsssRate1Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (8200 + 192))
362 && CheckTxDuration (1026, DsssPhy::GetDsssRate1Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (8208 + 192));
363
364 //values from http://mailman.isi.edu/pipermail/ns-developers/2009-July/006226.html
365 retval = retval && CheckTxDuration (14, DsssPhy::GetDsssRate1Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (304));
366
367 //values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
368 retval = retval
369 && CheckTxDuration (1536, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (1310))
370 && CheckTxDuration (76, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (248))
371 && CheckTxDuration (14, DsssPhy::GetDsssRate11Mbps (), 22, 800, WIFI_PREAMBLE_LONG, MicroSeconds (203));
372
373 NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11b duration failed");
374
375 //802.11a durations
376 //values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
377 retval = retval
378 && CheckTxDuration (1536, OfdmPhy::GetOfdmRate54Mbps (), 20, 800, WIFI_PREAMBLE_LONG, MicroSeconds (248))
379 && CheckTxDuration (76, OfdmPhy::GetOfdmRate54Mbps (), 20, 800, WIFI_PREAMBLE_LONG, MicroSeconds (32))
380 && CheckTxDuration (14, OfdmPhy::GetOfdmRate54Mbps (), 20, 800, WIFI_PREAMBLE_LONG, MicroSeconds (24));
381
382 NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11a duration failed");
383
384 //802.11g durations are same as 802.11a durations but with 6 us signal extension
385 retval = retval
386 && CheckTxDuration (1536, ErpOfdmPhy::GetErpOfdmRate54Mbps (), 20, 800, WIFI_PREAMBLE_LONG, MicroSeconds (254))
387 && CheckTxDuration (76, ErpOfdmPhy::GetErpOfdmRate54Mbps (), 20, 800, WIFI_PREAMBLE_LONG, MicroSeconds (38))
388 && CheckTxDuration (14, ErpOfdmPhy::GetErpOfdmRate54Mbps (), 20, 800, WIFI_PREAMBLE_LONG, MicroSeconds (30));
389
390 NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11g duration failed");
391
392 //802.11n durations
393 retval = retval
394 && CheckTxDuration (1536, HtPhy::GetHtMcs7 (), 20, 800, WIFI_PREAMBLE_HT_MF, MicroSeconds (228))
395 && CheckTxDuration (76, HtPhy::GetHtMcs7 (), 20, 800, WIFI_PREAMBLE_HT_MF, MicroSeconds (48))
396 && CheckTxDuration (14, HtPhy::GetHtMcs7 (), 20, 800, WIFI_PREAMBLE_HT_MF, MicroSeconds (40))
397 && CheckTxDuration (1536, HtPhy::GetHtMcs0 (), 20, 400, WIFI_PREAMBLE_HT_MF, NanoSeconds (1742400))
398 && CheckTxDuration (76, HtPhy::GetHtMcs0 (), 20, 400, WIFI_PREAMBLE_HT_MF, MicroSeconds (126))
399 && CheckTxDuration (14, HtPhy::GetHtMcs0 (), 20, 400, WIFI_PREAMBLE_HT_MF, NanoSeconds (57600))
400 && CheckTxDuration (1536, HtPhy::GetHtMcs6 (), 20, 400, WIFI_PREAMBLE_HT_MF, NanoSeconds (226800))
401 && CheckTxDuration (76, HtPhy::GetHtMcs6 (), 20, 400, WIFI_PREAMBLE_HT_MF, NanoSeconds (46800))
402 && CheckTxDuration (14, HtPhy::GetHtMcs6 (), 20, 400, WIFI_PREAMBLE_HT_MF, NanoSeconds (39600))
403 && CheckTxDuration (1536, HtPhy::GetHtMcs7 (), 40, 800, WIFI_PREAMBLE_HT_MF, MicroSeconds (128))
404 && CheckTxDuration (76, HtPhy::GetHtMcs7 (), 40, 800, WIFI_PREAMBLE_HT_MF, MicroSeconds (44))
405 && CheckTxDuration (14, HtPhy::GetHtMcs7 (), 40, 800, WIFI_PREAMBLE_HT_MF, MicroSeconds (40))
406 && CheckTxDuration (1536, HtPhy::GetHtMcs7 (), 40, 400, WIFI_PREAMBLE_HT_MF, NanoSeconds (118800))
407 && CheckTxDuration (76, HtPhy::GetHtMcs7 (), 40, 400, WIFI_PREAMBLE_HT_MF, NanoSeconds (43200))
408 && CheckTxDuration (14, HtPhy::GetHtMcs7 (), 40, 400, WIFI_PREAMBLE_HT_MF, NanoSeconds (39600));
409
410 NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11n duration failed");
411
412 //802.11ac durations
413 retval = retval
414 && CheckTxDuration (1536, VhtPhy::GetVhtMcs8 (), 20, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (196))
415 && CheckTxDuration (76, VhtPhy::GetVhtMcs8 (), 20, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (48))
416 && CheckTxDuration (14, VhtPhy::GetVhtMcs8 (), 20, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (40))
417 && CheckTxDuration (1536, VhtPhy::GetVhtMcs8 (), 20, 400, WIFI_PREAMBLE_VHT_SU, MicroSeconds (180))
418 && CheckTxDuration (76, VhtPhy::GetVhtMcs8 (), 20, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (46800))
419 && CheckTxDuration (14, VhtPhy::GetVhtMcs8 (), 20, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (39600))
420 && CheckTxDuration (1536, VhtPhy::GetVhtMcs9 (), 40, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (108))
421 && CheckTxDuration (76, VhtPhy::GetVhtMcs9 (), 40, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (40))
422 && CheckTxDuration (14, VhtPhy::GetVhtMcs9 (), 40, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (40))
423 && CheckTxDuration (1536, VhtPhy::GetVhtMcs9 (), 40, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (100800))
424 && CheckTxDuration (76, VhtPhy::GetVhtMcs9 (), 40, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (39600))
425 && CheckTxDuration (14, VhtPhy::GetVhtMcs9 (), 40, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (39600))
426 && CheckTxDuration (1536, VhtPhy::GetVhtMcs0 (), 80, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (460))
427 && CheckTxDuration (76, VhtPhy::GetVhtMcs0 (), 80, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (60))
428 && CheckTxDuration (14, VhtPhy::GetVhtMcs0 (), 80, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (44))
429 && CheckTxDuration (1536, VhtPhy::GetVhtMcs0 (), 80, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (417600))
430 && CheckTxDuration (76, VhtPhy::GetVhtMcs0 (), 80, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (57600))
431 && CheckTxDuration (14, VhtPhy::GetVhtMcs0 (), 80, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (43200))
432 && CheckTxDuration (1536, VhtPhy::GetVhtMcs9 (), 80, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (68))
433 && CheckTxDuration (76, VhtPhy::GetVhtMcs9 (), 80, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (40))
434 && CheckTxDuration (14, VhtPhy::GetVhtMcs9 (), 80, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (40))
435 && CheckTxDuration (1536, VhtPhy::GetVhtMcs9 (), 80, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (64800))
436 && CheckTxDuration (76, VhtPhy::GetVhtMcs9 (), 80, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (39600))
437 && CheckTxDuration (14, VhtPhy::GetVhtMcs9 (), 80, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (39600))
438 && CheckTxDuration (1536, VhtPhy::GetVhtMcs8 (), 160, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (56))
439 && CheckTxDuration (76, VhtPhy::GetVhtMcs8 (), 160, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (40))
440 && CheckTxDuration (14, VhtPhy::GetVhtMcs8 (), 160, 800, WIFI_PREAMBLE_VHT_SU, MicroSeconds (40))
441 && CheckTxDuration (1536, VhtPhy::GetVhtMcs8 (), 160, 400, WIFI_PREAMBLE_VHT_SU, MicroSeconds (54))
442 && CheckTxDuration (76, VhtPhy::GetVhtMcs8 (), 160, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (39600))
443 && CheckTxDuration (14, VhtPhy::GetVhtMcs8 (), 160, 400, WIFI_PREAMBLE_VHT_SU, NanoSeconds (39600));
444
445 NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11ac duration failed");
446
447 //802.11ax SU durations
448 retval = retval
449 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 20, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (1485600))
450 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 20, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (125600))
451 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 20, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (71200))
452 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 40, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (764800))
453 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 40, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (84800))
454 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 40, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
455 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 80, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (397600))
456 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 80, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (71200))
457 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 80, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
458 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 160, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (220800))
459 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 160, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
460 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 160, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
461 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 20, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (1570400))
462 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 20, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (130400))
463 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 20, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (72800))
464 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 40, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (807200))
465 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 40, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (87200))
466 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 40, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
467 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 80, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (418400))
468 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 80, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (72800))
469 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 80, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
470 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 160, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (231200))
471 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 160, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
472 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 160, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
473 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 20, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (1740))
474 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 20, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (140))
475 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 20, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (76))
476 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 40, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (892))
477 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 40, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (92))
478 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 40, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
479 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 80, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (460))
480 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 80, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (76))
481 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 80, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
482 && CheckTxDuration (1536, HePhy::GetHeMcs0 (), 160, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (252))
483 && CheckTxDuration (76, HePhy::GetHeMcs0 (), 160, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
484 && CheckTxDuration (14, HePhy::GetHeMcs0 (), 160, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
485 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 20, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (139200))
486 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 20, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
487 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 20, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
488 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 40, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (98400))
489 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 40, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
490 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 40, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
491 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 80, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (71200))
492 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 80, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
493 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 80, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
494 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 160, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
495 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 160, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
496 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 160, 800, WIFI_PREAMBLE_HE_SU, NanoSeconds (57600))
497 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 20, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (144800))
498 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 20, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
499 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 20, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
500 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 40, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (101600))
501 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 40, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
502 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 40, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
503 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 80, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (72800))
504 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 80, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
505 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 80, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
506 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 160, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
507 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 160, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
508 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 160, 1600, WIFI_PREAMBLE_HE_SU, NanoSeconds (58400))
509 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 20, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (156))
510 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 20, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
511 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 20, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
512 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 40, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (108))
513 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 40, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
514 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 40, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
515 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 80, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (76))
516 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 80, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
517 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 80, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
518 && CheckTxDuration (1536, HePhy::GetHeMcs11 (), 160, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
519 && CheckTxDuration (76, HePhy::GetHeMcs11 (), 160, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60))
520 && CheckTxDuration (14, HePhy::GetHeMcs11 (), 160, 3200, WIFI_PREAMBLE_HE_SU, MicroSeconds (60));
521
522 NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11ax SU duration failed");
523
524 //802.11ax MU durations
525 retval = retval
526 && CheckMuTxDuration (std::list<uint32_t> {1536, 1536},
527 std::list<HeMuUserInfo> { {{HeRu::RU_242_TONE, 1, true}, HePhy::GetHeMcs0 (), 1},
528 {{HeRu::RU_242_TONE, 2, true}, HePhy::GetHeMcs0 (), 1} },
529 40, 800, WIFI_PREAMBLE_HE_MU, NanoSeconds (1493600)) //equivalent to HE_SU for 20 MHz with 2 extra HE-SIG-B (i.e. 8 us)
530 && CheckMuTxDuration (std::list<uint32_t> {1536, 1536},
531 std::list<HeMuUserInfo> { {{HeRu::RU_242_TONE, 1, true}, HePhy::GetHeMcs1 (), 1},
532 {{HeRu::RU_242_TONE, 2, true}, HePhy::GetHeMcs0 (), 1} },
533 40, 800, WIFI_PREAMBLE_HE_MU, NanoSeconds (1493600)) //shouldn't change if first PSDU is shorter
534 && CheckMuTxDuration (std::list<uint32_t> {1536, 76},
535 std::list<HeMuUserInfo> { {{HeRu::RU_242_TONE, 1, true}, HePhy::GetHeMcs0 (), 1},
536 {{HeRu::RU_242_TONE, 2, true}, HePhy::GetHeMcs0 (), 1} },
537 40, 800, WIFI_PREAMBLE_HE_MU, NanoSeconds (1493600));
538
539 NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11ax MU duration failed");
540
541 //802.11be MU durations
542 retval = retval
543 && CheckMuTxDuration (std::list<uint32_t> {1536, 1536},
544 std::list<HeMuUserInfo> { {{HeRu::RU_242_TONE, 1, true}, EhtPhy::GetEhtMcs0 (), 1},
545 {{HeRu::RU_242_TONE, 2, true}, EhtPhy::GetEhtMcs0 (), 1} },
546 40, 800, WIFI_PREAMBLE_EHT_MU, NanoSeconds (1493600)) //equivalent to 802.11ax MU
547 && CheckMuTxDuration (std::list<uint32_t> {1536, 1536},
548 std::list<HeMuUserInfo> { {{HeRu::RU_242_TONE, 1, true}, EhtPhy::GetEhtMcs1 (), 1},
549 {{HeRu::RU_242_TONE, 2, true}, EhtPhy::GetEhtMcs0 (), 1} },
550 40, 800, WIFI_PREAMBLE_EHT_MU, NanoSeconds (1493600)) //shouldn't change if first PSDU is shorter
551 && CheckMuTxDuration (std::list<uint32_t> {1536, 76},
552 std::list<HeMuUserInfo> { {{HeRu::RU_242_TONE, 1, true}, EhtPhy::GetEhtMcs0 (), 1},
553 {{HeRu::RU_242_TONE, 2, true}, EhtPhy::GetEhtMcs0 (), 1} },
554 40, 800, WIFI_PREAMBLE_EHT_MU, NanoSeconds (1493600));
555
556 NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11be MU duration failed");
557
558 Simulator::Destroy ();
559}
560
568{
569public:
571 virtual ~HeSigBDurationTest ();
572 void DoRun (void) override;
573
574private:
583 static WifiTxVector BuildTxVector (uint16_t bw, std::list <HeMuUserInfo> userInfos);
584};
585
587 : TestCase ("Check HE-SIG-B duration computation")
588{
589}
590
592{
593}
594
596HeSigBDurationTest::BuildTxVector (uint16_t bw, std::list <HeMuUserInfo> userInfos)
597{
598 WifiTxVector txVector;
600 txVector.SetChannelWidth (bw);
601 txVector.SetGuardInterval (3200);
602 txVector.SetStbc (0);
603 txVector.SetNess (0);
604 std::list<uint16_t> staIds;
605 uint16_t staId = 1;
606 for (const auto & userInfo : userInfos)
607 {
608 txVector.SetHeMuUserInfo (staId, userInfo);
609 staIds.push_back (staId++);
610 }
611 return txVector;
612}
613
614void
616{
617 const auto & hePhy = WifiPhy::GetStaticPhyEntity(WIFI_MOD_CLASS_HE);
618
619 //20 MHz band
620 std::list<HeMuUserInfo> userInfos;
621 userInfos.push_back ({{HeRu::RU_106_TONE, 1, true}, HePhy::GetHeMcs11 (), 1});
622 userInfos.push_back ({{HeRu::RU_106_TONE, 2, true}, HePhy::GetHeMcs10 (), 4});
623 WifiTxVector txVector = BuildTxVector (20, userInfos);
624 NS_TEST_EXPECT_MSG_EQ (hePhy->GetSigMode (WIFI_PPDU_FIELD_SIG_B, txVector), VhtPhy::GetVhtMcs5 (), "HE-SIG-B should be sent at MCS 5");
625 std::pair<std::size_t, std::size_t> numUsersPerCc = txVector.GetNumRusPerHeSigBContentChannel ();
626 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.first, 2, "Both users should be on HE-SIG-B content channel 1");
627 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 0, "Both users should be on HE-SIG-B content channel 2");
628 NS_TEST_EXPECT_MSG_EQ (hePhy->GetDuration (WIFI_PPDU_FIELD_SIG_B, txVector), MicroSeconds (4), "HE-SIG-B should only last one OFDM symbol");
629
630 //40 MHz band, even number of users per HE-SIG-B content channel
631 userInfos.push_back ({{HeRu::RU_52_TONE, 5, true}, HePhy::GetHeMcs4 (), 1});
632 userInfos.push_back ({{HeRu::RU_52_TONE, 6, true}, HePhy::GetHeMcs6 (), 2});
633 userInfos.push_back ({{HeRu::RU_52_TONE, 7, true}, HePhy::GetHeMcs5 (), 3});
634 userInfos.push_back ({{HeRu::RU_52_TONE, 8, true}, HePhy::GetHeMcs6 (), 2});
635 txVector = BuildTxVector (40, userInfos);
636 NS_TEST_EXPECT_MSG_EQ (hePhy->GetSigMode (WIFI_PPDU_FIELD_SIG_B, txVector), VhtPhy::GetVhtMcs4 (), "HE-SIG-B should be sent at MCS 4");
637 numUsersPerCc = txVector.GetNumRusPerHeSigBContentChannel ();
638 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.first, 2, "Two users should be on HE-SIG-B content channel 1");
639 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 4, "Four users should be on HE-SIG-B content channel 2");
640 NS_TEST_EXPECT_MSG_EQ (hePhy->GetDuration (WIFI_PPDU_FIELD_SIG_B, txVector), MicroSeconds (4), "HE-SIG-B should only last one OFDM symbol");
641
642 //40 MHz band, odd number of users per HE-SIG-B content channel
643 userInfos.push_back ({{HeRu::RU_26_TONE, 13, true}, HePhy::GetHeMcs3 (), 1});
644 txVector = BuildTxVector (40, userInfos);
645 NS_TEST_EXPECT_MSG_EQ (hePhy->GetSigMode (WIFI_PPDU_FIELD_SIG_B, txVector), VhtPhy::GetVhtMcs3 (), "HE-SIG-B should be sent at MCS 3");
646 numUsersPerCc = txVector.GetNumRusPerHeSigBContentChannel ();
647 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.first, 2, "Two users should be on HE-SIG-B content channel 1");
648 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 5, "Five users should be on HE-SIG-B content channel 2");
649 NS_TEST_EXPECT_MSG_EQ (hePhy->GetDuration (WIFI_PPDU_FIELD_SIG_B, txVector), MicroSeconds (8), "HE-SIG-B should last two OFDM symbols");
650
651 //80 MHz band
652 userInfos.push_back ({{HeRu::RU_242_TONE, 3, true}, HePhy::GetHeMcs1 (), 1});
653 userInfos.push_back ({{HeRu::RU_242_TONE, 4, true}, HePhy::GetHeMcs4 (), 1});
654 txVector = BuildTxVector (80, userInfos);
655 NS_TEST_EXPECT_MSG_EQ (hePhy->GetSigMode (WIFI_PPDU_FIELD_SIG_B, txVector), VhtPhy::GetVhtMcs1 (), "HE-SIG-B should be sent at MCS 1");
656 numUsersPerCc = txVector.GetNumRusPerHeSigBContentChannel ();
657 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.first, 3, "Three users should be on HE-SIG-B content channel 1");
658 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 6, "Six users should be on HE-SIG-B content channel 2");
659 NS_TEST_EXPECT_MSG_EQ (hePhy->GetDuration (WIFI_PPDU_FIELD_SIG_B, txVector), MicroSeconds (16), "HE-SIG-B should last four OFDM symbols");
660
661 //160 MHz band
662 userInfos.push_back ({{HeRu::RU_996_TONE, 1, false}, HePhy::GetHeMcs1 (), 1});
663 txVector = BuildTxVector (160, userInfos);
664 NS_TEST_EXPECT_MSG_EQ (hePhy->GetSigMode (WIFI_PPDU_FIELD_SIG_B, txVector), VhtPhy::GetVhtMcs1 (), "HE-SIG-B should be sent at MCS 1");
665 numUsersPerCc = txVector.GetNumRusPerHeSigBContentChannel ();
666 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.first, 4, "Four users should be on HE-SIG-B content channel 1");
667 NS_TEST_EXPECT_MSG_EQ (numUsersPerCc.second, 7, "Seven users should be on HE-SIG-B content channel 2");
668 NS_TEST_EXPECT_MSG_EQ (hePhy->GetDuration (WIFI_PPDU_FIELD_SIG_B, txVector), MicroSeconds (20), "HE-SIG-B should last five OFDM symbols");
669}
670
678{
679public:
681 virtual ~PhyHeaderSectionsTest ();
682 void DoRun (void) override;
683
684
685private:
695};
696
698 : TestCase ("PHY header sections consistency")
699{
700}
701
703{
704}
705
706void
709{
710 NS_ASSERT_MSG (obtained.size () == expected.size (), "The expected map size (" << expected.size () << ") was not obtained (" << obtained.size () << ")");
711
712 auto itObtained = obtained.begin ();
713 auto itExpected = expected.begin ();
714 for (;itObtained != obtained.end () || itExpected != expected.end ();)
715 {
716 WifiPpduField field = itObtained->first;
717 auto window = itObtained->second.first;
718 auto mode = itObtained->second.second;
719
720 WifiPpduField fieldRef = itExpected->first;
721 auto windowRef = itExpected->second.first;
722 auto modeRef = itExpected->second.second;
723
724 NS_TEST_EXPECT_MSG_EQ (field, fieldRef, "The expected PPDU field (" << fieldRef << ") was not obtained (" << field << ")");
725 NS_TEST_EXPECT_MSG_EQ (window.first, windowRef.first, "The expected start time (" << windowRef.first << ") was not obtained (" << window.first << ")");
726 NS_TEST_EXPECT_MSG_EQ (window.second, windowRef.second, "The expected stop time (" << windowRef.second << ") was not obtained (" << window.second << ")");
727 NS_TEST_EXPECT_MSG_EQ (mode, modeRef, "The expected mode (" << modeRef << ") was not obtained (" << mode << ")");
728 ++itObtained;
729 ++itExpected;
730 }
731}
732
733void
735{
736 Time ppduStart = Seconds (1.0);
737 Ptr<PhyEntity> phyEntity;
739 WifiTxVector txVector;
740 WifiMode nonHtMode;
741
742
743 // ==================================================================================
744 // 11b (HR/DSSS)
745 phyEntity = Create<DsssPhy> ();
746 txVector.SetMode (DsssPhy::GetDsssRate1Mbps ());
747 txVector.SetChannelWidth (22);
748
749 // -> long PPDU format
751 nonHtMode = DsssPhy::GetDsssRate1Mbps ();
752 sections = { { WIFI_PPDU_FIELD_PREAMBLE, { { ppduStart,
753 ppduStart + MicroSeconds (144) },
754 nonHtMode } },
755 { WIFI_PPDU_FIELD_NON_HT_HEADER, { { ppduStart + MicroSeconds (144),
756 ppduStart + MicroSeconds (192) },
757 nonHtMode } } };
758 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
759
760 // -> long PPDU format if data rate is 1 Mbps (even if preamble is tagged short)
762 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
763
764 // -> short PPDU format
765 txVector.SetMode (DsssPhy::GetDsssRate11Mbps ());
766 nonHtMode = DsssPhy::GetDsssRate2Mbps ();
768 sections = { { WIFI_PPDU_FIELD_PREAMBLE, { { ppduStart,
769 ppduStart + MicroSeconds (72) },
770 nonHtMode } },
771 { WIFI_PPDU_FIELD_NON_HT_HEADER, { { ppduStart + MicroSeconds (72),
772 ppduStart + MicroSeconds (96) },
773 nonHtMode } } };
774 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
775
776
777 // ==================================================================================
778 // 11a (OFDM)
780
781 // -> one iteration per variant: default, 10 MHz, and 5 MHz
782 std::map<OfdmPhyVariant, std::size_t> variants { //number to use to deduce rate and BW info for each variant
783 { OFDM_PHY_DEFAULT, 1},
784 { OFDM_PHY_10_MHZ, 2},
785 { OFDM_PHY_5_MHZ, 4}
786 };
787 for (auto variant : variants)
788 {
789 phyEntity = Create<OfdmPhy> (variant.first);
790 std::size_t ratio = variant.second;
791 uint16_t bw = 20 / ratio; //MHz
792 txVector.SetChannelWidth (bw);
793 txVector.SetMode (OfdmPhy::GetOfdmRate (12000000 / ratio, bw));
794 nonHtMode = OfdmPhy::GetOfdmRate (6000000 / ratio, bw);
795 sections = { { WIFI_PPDU_FIELD_PREAMBLE, { { ppduStart,
796 ppduStart + MicroSeconds (16 * ratio) },
797 nonHtMode } },
798 { WIFI_PPDU_FIELD_NON_HT_HEADER, { { ppduStart + MicroSeconds (16 * ratio),
799 ppduStart + MicroSeconds (20 * ratio) },
800 nonHtMode } } };
801 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
802 }
803
804
805 // ==================================================================================
806 // 11g (ERP-OFDM)
807 phyEntity = Create<ErpOfdmPhy> ();
808 txVector.SetChannelWidth (20);
809 txVector.SetMode (ErpOfdmPhy::GetErpOfdmRate (54000000));
810 nonHtMode = ErpOfdmPhy::GetErpOfdmRate6Mbps ();
811 sections = { { WIFI_PPDU_FIELD_PREAMBLE, { { ppduStart,
812 ppduStart + MicroSeconds (16) },
813 nonHtMode } },
814 { WIFI_PPDU_FIELD_NON_HT_HEADER, { { ppduStart + MicroSeconds (16),
815 ppduStart + MicroSeconds (20) },
816 nonHtMode } } };
817 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
818
819
820 // ==================================================================================
821 // 11n (HT)
822 phyEntity = Create<HtPhy> (4);
823 txVector.SetChannelWidth (20);
824 txVector.SetMode (HtPhy::GetHtMcs6 ());
825 nonHtMode = OfdmPhy::GetOfdmRate6Mbps ();
826 WifiMode htSigMode = nonHtMode;
827
828 // -> HT-mixed format for 2 SS and no ESS
830 txVector.SetNss (2);
831 txVector.SetNess (0);
832 sections = { { WIFI_PPDU_FIELD_PREAMBLE, { { ppduStart,
833 ppduStart + MicroSeconds (16) },
834 nonHtMode } },
835 { WIFI_PPDU_FIELD_NON_HT_HEADER, { { ppduStart + MicroSeconds (16),
836 ppduStart + MicroSeconds (20) },
837 nonHtMode } },
838 { WIFI_PPDU_FIELD_HT_SIG, { { ppduStart + MicroSeconds (20),
839 ppduStart + MicroSeconds (28) },
840 htSigMode } },
841 { WIFI_PPDU_FIELD_TRAINING, { { ppduStart + MicroSeconds (28),
842 ppduStart + MicroSeconds (40) }, // 1 HT-STF + 2 HT-LTFs
843 htSigMode } } };
844 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
845 txVector.SetChannelWidth (20); //shouldn't have any impact
846 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
847
848 // -> HT-mixed format for 3 SS and 1 ESS
849 txVector.SetNss (3);
850 txVector.SetNess (1);
851 sections[WIFI_PPDU_FIELD_TRAINING] = { { ppduStart + MicroSeconds (28),
852 ppduStart + MicroSeconds (52) }, // 1 HT-STF + 5 HT-LTFs (4 data + 1 extension)
853 htSigMode };
854 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
855
856
857 // ==================================================================================
858 // 11ac (VHT)
859 phyEntity = Create<VhtPhy> ();
860 txVector.SetChannelWidth (20);
861 txVector.SetNess (0);
862 txVector.SetMode (VhtPhy::GetVhtMcs7 ());
863 WifiMode sigAMode = nonHtMode;
864 WifiMode sigBMode = VhtPhy::GetVhtMcs0 ();
865
866 // -> VHT SU format for 5 SS
868 txVector.SetNss (5);
869 sections = { { WIFI_PPDU_FIELD_PREAMBLE, { { ppduStart,
870 ppduStart + MicroSeconds (16) },
871 nonHtMode } },
872 { WIFI_PPDU_FIELD_NON_HT_HEADER, { { ppduStart + MicroSeconds (16),
873 ppduStart + MicroSeconds (20) },
874 nonHtMode } },
875 { WIFI_PPDU_FIELD_SIG_A, { { ppduStart + MicroSeconds (20),
876 ppduStart + MicroSeconds (28) },
877 sigAMode } },
878 { WIFI_PPDU_FIELD_TRAINING, { { ppduStart + MicroSeconds (28),
879 ppduStart + MicroSeconds (56) }, // 1 VHT-STF + 6 VHT-LTFs
880 sigAMode } } };
881 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
882
883 // -> VHT SU format for 7 SS
884 txVector.SetNss (7);
885 sections[WIFI_PPDU_FIELD_TRAINING] = { { ppduStart + MicroSeconds (28),
886 ppduStart + MicroSeconds (64) }, // 1 VHT-STF + 8 VHT-LTFs
887 sigAMode };
888 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
889
890 // -> VHT MU format for 3 SS
892 txVector.SetNss (3);
893 sections[WIFI_PPDU_FIELD_TRAINING] = { { ppduStart + MicroSeconds (28),
894 ppduStart + MicroSeconds (48) }, // 1 VHT-STF + 4 VHT-LTFs
895 sigAMode };
896 sections[WIFI_PPDU_FIELD_SIG_B] = { { ppduStart + MicroSeconds (48),
897 ppduStart + MicroSeconds (52) },
898 sigBMode };
899 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
900 txVector.SetChannelWidth (80); //shouldn't have any impact
901 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
902
903
904 // ==================================================================================
905 // 11ax (HE)
906 phyEntity = Create<HePhy> ();
907 txVector.SetChannelWidth (20);
908 txVector.SetNss (2); //HE-LTF duration assumed to be always 8 us for the time being (see note in HePhy::GetTrainingDuration)
909 txVector.SetMode (HePhy::GetHeMcs9 ());
910 std::map<uint16_t, HeMuUserInfo> userInfoMap = { { 1, { {HeRu::RU_106_TONE, 1, true}, HePhy::GetHeMcs4 (), 2 } },
911 { 2, { {HeRu::RU_106_TONE, 1, true}, HePhy::GetHeMcs9 (), 1 } } };
912 sigAMode = HePhy::GetVhtMcs0 ();
913 sigBMode = HePhy::GetVhtMcs4 (); //because of first user info map
914
915 // -> HE SU format
917 sections = { { WIFI_PPDU_FIELD_PREAMBLE, { { ppduStart,
918 ppduStart + MicroSeconds (16) },
919 nonHtMode } },
920 { WIFI_PPDU_FIELD_NON_HT_HEADER, { { ppduStart + MicroSeconds (16),
921 ppduStart + MicroSeconds (24) }, // L-SIG + RL-SIG
922 nonHtMode } },
923 { WIFI_PPDU_FIELD_SIG_A, { { ppduStart + MicroSeconds (24),
924 ppduStart + MicroSeconds (32) },
925 sigAMode } },
926 { WIFI_PPDU_FIELD_TRAINING, { { ppduStart + MicroSeconds (32),
927 ppduStart + MicroSeconds (52) }, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
928 sigAMode } } };
929 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
930
931 // -> HE ER SU format
933 sections[WIFI_PPDU_FIELD_SIG_A] = { { ppduStart + MicroSeconds (24),
934 ppduStart + MicroSeconds (40) }, // 16 us HE-SIG-A
935 sigAMode };
936 sections[WIFI_PPDU_FIELD_TRAINING] = { { ppduStart + MicroSeconds (40),
937 ppduStart + MicroSeconds (60) }, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
938 sigAMode };
939 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
940
941 // -> HE TB format
943 txVector.SetHeMuUserInfo (1, userInfoMap.at (1));
944 txVector.SetHeMuUserInfo (2, userInfoMap.at (2));
945 sections[WIFI_PPDU_FIELD_SIG_A] = { { ppduStart + MicroSeconds (24),
946 ppduStart + MicroSeconds (32) },
947 sigAMode };
948 sections[WIFI_PPDU_FIELD_TRAINING] = { { ppduStart + MicroSeconds (32),
949 ppduStart + MicroSeconds (56) }, // 1 HE-STF (@ 8 us) + 2 HE-LTFs (@ 8 us)
950 sigAMode };
951 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
952
953 // -> HE MU format
955 sections[WIFI_PPDU_FIELD_SIG_A] = { { ppduStart + MicroSeconds (24),
956 ppduStart + MicroSeconds (32) },
957 sigAMode };
958 sections[WIFI_PPDU_FIELD_SIG_B] = { { ppduStart + MicroSeconds (32),
959 ppduStart + MicroSeconds (36) }, // only one symbol
960 sigBMode };
961 sections[WIFI_PPDU_FIELD_TRAINING] = { { ppduStart + MicroSeconds (36),
962 ppduStart + MicroSeconds (56) }, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
963 sigBMode };
964 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
965 txVector.SetChannelWidth (160); //shouldn't have any impact
966 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
967
968 // ==================================================================================
969 // 11be (EHT)
970 sections.erase (WIFI_PPDU_FIELD_SIG_A); // FIXME: do we keep using seperate type for 11be?
971 sections.erase (WIFI_PPDU_FIELD_SIG_B); // FIXME: do we keep using seperate type for 11be?
972 phyEntity = Create<EhtPhy> ();
973 txVector.SetChannelWidth (20);
974 txVector.SetNss (2); //EHT-LTF duration assumed to be always 8 us for the time being (see note in HePhy::GetTrainingDuration)
975 txVector.SetMode (EhtPhy::GetEhtMcs9 ());
976 userInfoMap = { { 1, { {HeRu::RU_106_TONE, 1, true}, EhtPhy::GetEhtMcs4 (), 2 } },
977 { 2, { {HeRu::RU_106_TONE, 1, true}, EhtPhy::GetEhtMcs9 (), 1 } } };
978 WifiMode uSigMode = EhtPhy::GetVhtMcs0 ();
979 WifiMode ehtSigMode = EhtPhy::GetVhtMcs4 (); //because of first user info map
980
981 // -> EHT TB format
983 txVector.SetHeMuUserInfo (1, userInfoMap.at (1));
984 txVector.SetHeMuUserInfo (2, userInfoMap.at (2));
985 sections[WIFI_PPDU_FIELD_U_SIG] = { { ppduStart + MicroSeconds (24),
986 ppduStart + MicroSeconds (32) },
987 uSigMode };
988 sections[WIFI_PPDU_FIELD_TRAINING] = { { ppduStart + MicroSeconds (32),
989 ppduStart + MicroSeconds (56) }, // 1 EHT-STF (@ 8 us) + 2 EHT-LTFs (@ 8 us)
990 uSigMode };
991 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
992
993 // -> EHT MU format
995 sections[WIFI_PPDU_FIELD_U_SIG] = { { ppduStart + MicroSeconds (24),
996 ppduStart + MicroSeconds (32) },
997 uSigMode };
998 sections[WIFI_PPDU_FIELD_EHT_SIG] = { { ppduStart + MicroSeconds (32),
999 ppduStart + MicroSeconds (36) }, // only one symbol
1000 ehtSigMode };
1001 sections[WIFI_PPDU_FIELD_TRAINING] = { { ppduStart + MicroSeconds (36),
1002 ppduStart + MicroSeconds (56) }, // 1 HE-STF (@ 4 us) + 2 HE-LTFs (@ 8 us)
1003 ehtSigMode };
1004 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
1005 txVector.SetChannelWidth (160); //shouldn't have any impact
1006 CheckPhyHeaderSections (phyEntity->GetPhyHeaderSections (txVector, ppduStart), sections);
1007}
1008
1016{
1017public:
1019};
1020
1022 : TestSuite ("wifi-devices-tx-duration", UNIT)
1023{
1024 AddTestCase (new HeSigBDurationTest, TestCase::QUICK);
1025 AddTestCase (new TxDurationTest, TestCase::QUICK);
1026 AddTestCase (new PhyHeaderSectionsTest, TestCase::QUICK);
1027}
1028
HE-SIG-B duration test.
void DoRun(void) override
Implementation to actually run this TestCase.
static WifiTxVector BuildTxVector(uint16_t bw, std::list< HeMuUserInfo > userInfos)
Build a TXVECTOR for HE MU with the given bandwith and user informations.
PHY header sections consistency test.
void DoRun(void) 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.
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.
virtual ~TxDurationTest()
void DoRun(void) override
Implementation to actually run this TestCase.
Tx Duration Test Suite.
RuType GetRuType(void) const
Get the RU type.
Definition: he-ru.cc:167
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
Definition: phy-entity.h:303
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
Implements the IEEE 802.11 MAC header.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
uint32_t GetSerializedSize(void) const override
represent a single transmission mode
Definition: wifi-mode.h:48
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:177
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:114
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetStbc(bool stbc)
Sets if STBC is being used.
void SetNess(uint8_t ness)
Sets the Ness number.
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.
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.
std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(void) const
Get the number of RUs per HE-SIG-B content channel.
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:67
#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:88
#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:205
#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:240
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1261
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1245
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.
@ WIFI_MAC_CTL_ACK
phy
Definition: third.py:84
HE MU specific user transmission parameters.
HeRu::RuSpec ru
RU specification.
static TxDurationTestSuite g_txDurationTestSuite
the test suite
#define SU_STA_ID
Definition: wifi-mode.h:32