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