A Discrete-Event Network Simulator
API
wifi-mac-ofdma-test.cc
Go to the documentation of this file.
1  /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
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  * Author: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #include "ns3/test.h"
22 #include "ns3/string.h"
23 #include "ns3/qos-utils.h"
24 #include "ns3/packet.h"
25 #include "ns3/wifi-net-device.h"
26 #include "ns3/wifi-mac-header.h"
27 #include "ns3/he-frame-exchange-manager.h"
28 #include "ns3/wifi-acknowledgment.h"
29 #include "ns3/wifi-protection.h"
30 #include "ns3/he-configuration.h"
31 #include "ns3/mobility-helper.h"
32 #include "ns3/spectrum-wifi-helper.h"
33 #include "ns3/multi-model-spectrum-channel.h"
34 #include "ns3/packet-socket-server.h"
35 #include "ns3/packet-socket-client.h"
36 #include "ns3/packet-socket-helper.h"
37 #include "ns3/config.h"
38 #include "ns3/pointer.h"
39 #include "ns3/rng-seed-manager.h"
40 #include "ns3/wifi-psdu.h"
41 #include "ns3/multi-user-scheduler.h"
42 #include "ns3/he-phy.h"
43 
44 using namespace ns3;
45 
46 NS_LOG_COMPONENT_DEFINE ("WifiMacOfdmaTestSuite");
47 
61 {
62 public:
67  static TypeId GetTypeId (void);
69  virtual ~TestMultiUserScheduler ();
70 
71 private:
72  // Implementation of pure virtual methods of MultiUserScheduler class
73  TxFormat SelectTxFormat (void) override;
74  DlMuInfo ComputeDlMuInfo (void) override;
75  UlMuInfo ComputeUlMuInfo (void) override;
76 
80  void ComputeWifiTxVector (void);
81 
89 };
90 
91 
93 
94 TypeId
96 {
97  static TypeId tid = TypeId ("ns3::TestMultiUserScheduler")
99  .SetGroupName ("Wifi")
100  .AddConstructor<TestMultiUserScheduler> ()
101  ;
102  return tid;
103 }
104 
106  : m_txFormat (SU_TX),
107  m_ulTriggerType (TriggerFrameType::BSRP_TRIGGER)
108 {
109  NS_LOG_FUNCTION (this);
110 }
111 
113 {
115 }
116 
119 {
120  NS_LOG_FUNCTION (this);
121 
122  // Do not use OFDMA if a BA agreement has not been established with all the stations
123  if (Simulator::Now () < Seconds (1.5))
124  {
125  NS_LOG_DEBUG ("Return SU_TX");
126  return SU_TX;
127  }
128 
130 
131  if (m_txFormat == SU_TX || m_txFormat == DL_MU_TX
133  {
134  // try to send a Trigger Frame
135  TriggerFrameType ulTriggerType = (m_txFormat == SU_TX || m_txFormat == DL_MU_TX
138 
139  CtrlTriggerHeader trigger (ulTriggerType, m_txVector);
140 
141  WifiTxVector txVector = m_txVector;
142  txVector.SetGuardInterval (trigger.GetGuardInterval ());
143 
144  uint32_t ampduSize = (ulTriggerType == TriggerFrameType::BSRP_TRIGGER ? m_sizeOf8QosNull : 3500);
145 
146  Time duration = WifiPhy::CalculateTxDuration (ampduSize, txVector,
147  m_apMac->GetWifiPhy ()->GetPhyBand (),
148  m_apMac->GetStaList ().begin ()->first);
149 
150  uint16_t length = HePhy::ConvertHeTbPpduDurationToLSigLength (duration,
151  m_apMac->GetWifiPhy ()->GetPhyBand ());
152  trigger.SetUlLength (length);
153  m_heFem->SetTargetRssi (trigger);
154 
155  Ptr<Packet> packet = Create<Packet> ();
156  packet->AddHeader (trigger);
157 
159  hdr.SetAddr1 (Mac48Address::GetBroadcast ());
160  hdr.SetAddr2 (m_apMac->GetAddress ());
161  hdr.SetDsNotTo ();
162  hdr.SetDsNotFrom ();
163 
164  m_trigger = Create<WifiMacQueueItem> (packet, hdr);
165 
166  m_txParams.Clear ();
167  // set the TXVECTOR used to send the Trigger Frame
168  m_txParams.m_txVector = m_apMac->GetWifiRemoteStationManager ()->GetRtsTxVector (hdr.GetAddr1 ());
169 
170  if (!m_heFem->TryAddMpdu (m_trigger, m_txParams, m_availableTime)
171  || (m_availableTime != Time::Min ()
172  && m_txParams.m_protection->protectionTime
173  + m_txParams.m_txDuration // TF tx time
174  + m_apMac->GetWifiPhy ()->GetSifs ()
175  + duration
176  + m_txParams.m_acknowledgment->acknowledgmentTime
177  > m_availableTime ))
178  {
179  NS_LOG_DEBUG ("Remaining TXOP duration is not enough for BSRP TF exchange");
180  return SU_TX;
181  }
182 
184  m_ulTriggerType = ulTriggerType;
185  m_tbPpduDuration = duration;
186  }
187  else if (m_txFormat == UL_MU_TX)
188  {
189  // try to send a DL MU PPDU
190  m_psduMap.clear ();
191  const std::map<uint16_t, Mac48Address>& staList = m_apMac->GetStaList ();
192  NS_ABORT_MSG_IF (staList.size () != 4, "There must be 4 associated stations");
193 
194  /* Initialize TX params */
195  m_txParams.Clear ();
197 
198  for (auto& sta : staList)
199  {
200  Ptr<const WifiMacQueueItem> peeked = m_apMac->GetQosTxop (AC_BE)->PeekNextMpdu (0, sta.second);
201 
202  if (peeked == 0)
203  {
204  NS_LOG_DEBUG ("No frame to send");
205  return SU_TX;
206  }
207 
209  Ptr<WifiMacQueueItem> mpdu = m_apMac->GetQosTxop (AC_BE)->GetNextMpdu (peeked, m_txParams,
211  m_initialFrame, queueIt);
212  if (mpdu == 0)
213  {
214  NS_LOG_DEBUG ("Not enough time to send frames to all the stations");
215  return SU_TX;
216  }
217 
218  std::vector<Ptr<WifiMacQueueItem>> mpduList;
219  mpduList = m_heFem->GetMpduAggregator ()->GetNextAmpdu (mpdu, m_txParams, m_availableTime, queueIt);
220 
221  if (mpduList.size () > 1)
222  {
223  m_psduMap[sta.first] = Create<WifiPsdu> (std::move (mpduList));
224  }
225  else
226  {
227  m_psduMap[sta.first] = Create<WifiPsdu> (mpdu, true);
228  }
229  }
230 
232  }
233  else
234  {
235  NS_ABORT_MSG ("Cannot get here.");
236  }
237 
238  NS_LOG_DEBUG ("Return " << m_txFormat);
239  return m_txFormat;
240 }
241 
242 void
244 {
246  {
247  // the TX vector has been already computed
248  return;
249  }
250 
251  uint16_t bw = m_apMac->GetWifiPhy ()->GetChannelWidth ();
252 
255  m_txVector.SetGuardInterval (m_apMac->GetHeConfiguration ()->GetGuardInterval ().GetNanoSeconds ());
256  m_txVector.SetTxPowerLevel (GetWifiRemoteStationManager ()->GetDefaultTxPowerLevel ());
257 
258  const std::map<uint16_t, Mac48Address>& staList = m_apMac->GetStaList ();
259  NS_ABORT_MSG_IF (staList.size () != 4, "There must be 4 associated stations");
260 
261  HeRu::RuType ruType;
262  switch (bw)
263  {
264  case 20:
265  ruType = HeRu::RU_52_TONE;
266  break;
267  case 40:
268  ruType = HeRu::RU_106_TONE;
269  break;
270  case 80:
271  ruType = HeRu::RU_242_TONE;
272  break;
273  case 160:
274  ruType = HeRu::RU_484_TONE;
275  break;
276  default:
277  NS_ABORT_MSG ("Unsupported channel width");
278  }
279 
280  bool primary80 = true;
281  std::size_t ruIndex = 1;
282 
283  for (auto& sta : staList)
284  {
285  if (bw == 160 && ruIndex == 3)
286  {
287  ruIndex = 1;
288  primary80 = false;
289  }
290  m_txVector.SetHeMuUserInfo (sta.first,
291  {{ruType, ruIndex++, primary80}, WifiMode ("HeMcs11"), 1});
292  }
293 }
294 
297 {
298  NS_LOG_FUNCTION (this);
299  return DlMuInfo {m_psduMap, std::move (m_txParams)};
300 }
301 
304 {
305  NS_LOG_FUNCTION (this);
306  return UlMuInfo {m_trigger, m_tbPpduDuration, std::move (m_txParams)};
307 }
308 
309 
326 {
327 public:
332  {
333  uint8_t muAifsn;
334  uint16_t muCwMin;
335  uint16_t muCwMax;
336  uint8_t muTimer;
337  };
338 
348  OfdmaAckSequenceTest (uint16_t width, WifiAcknowledgment::Method dlType, uint32_t maxAmpduSize,
349  uint16_t txopLimit, uint16_t nPktsPerSta,
350  MuEdcaParameterSet muEdcaParameterSet);
351  virtual ~OfdmaAckSequenceTest ();
352 
359  void L7Receive (std::string context, Ptr<const Packet> p, const Address &addr);
366  void TraceCw (uint32_t staIndex, uint32_t oldCw, uint32_t cw);
374  void Transmit (std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
381  void CheckResults (Time sifs, Time slotTime, uint8_t aifsn);
382 
383 private:
384  void DoRun (void) override;
385 
387  struct FrameInfo
388  {
393  };
394 
395  uint16_t m_nStations;
398  uint16_t m_channelWidth;
399  std::vector<FrameInfo> m_txPsdus;
401  uint32_t m_maxAmpduSize;
402  uint16_t m_txopLimit;
403  uint16_t m_nPktsPerSta;
405  uint16_t m_received;
406  uint16_t m_flushed;
408  std::vector<uint32_t> m_cwValues;
409 };
410 
412  uint32_t maxAmpduSize, uint16_t txopLimit,
413  uint16_t nPktsPerSta,
414  MuEdcaParameterSet muEdcaParameterSet)
415  : TestCase ("Check correct operation of DL OFDMA acknowledgment sequences"),
416  m_nStations (4),
417  m_channelWidth (width),
418  m_dlMuAckType (dlType),
419  m_maxAmpduSize (maxAmpduSize),
420  m_txopLimit (txopLimit),
421  m_nPktsPerSta (nPktsPerSta),
422  m_muEdcaParameterSet (muEdcaParameterSet),
423  m_received (0),
424  m_flushed (0),
425  m_edcaDisabledStartTime (Seconds (0)),
426  m_cwValues (std::vector<uint32_t> (m_nStations, 2)) // 2 is an invalid CW value
427 {
428 }
429 
431 {
432 }
433 
434 void
435 OfdmaAckSequenceTest::L7Receive (std::string context, Ptr<const Packet> p, const Address &addr)
436 {
437  if (p->GetSize () >= 1400 && Simulator::Now () > Seconds (1.5))
438  {
439  m_received++;
440  }
441 }
442 
443 void
444 OfdmaAckSequenceTest::TraceCw (uint32_t staIndex, uint32_t oldCw, uint32_t cw)
445 {
446  if (m_cwValues.at (staIndex) == 2)
447  {
448  // store the first CW used after MU exchange (the last one may be used after
449  // the MU EDCA timer expired)
450  m_cwValues[staIndex] = cw;
451  }
452 }
453 
454 void
455 OfdmaAckSequenceTest::Transmit (std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
456 {
457  // skip beacon frames and frames transmitted before 1.5s (association
458  // request/response, ADDBA request, ...)
459  if (!psduMap.begin ()->second->GetHeader (0).IsBeacon ()
460  && Simulator::Now () > Seconds (1.5))
461  {
462  Time txDuration = WifiPhy::CalculateTxDuration (psduMap, txVector, WIFI_PHY_BAND_5GHZ);
463  m_txPsdus.push_back ({Simulator::Now (),
464  Simulator::Now () + txDuration,
465  psduMap, txVector});
466 
467  for (const auto& psduPair : psduMap)
468  {
469  NS_LOG_INFO ("Sending " << psduPair.second->GetHeader (0).GetTypeString ()
470  << " #MPDUs " << psduPair.second->GetNMpdus ()
471  << " txDuration " << txDuration
472  << " duration/ID " << psduPair.second->GetHeader (0).GetDuration ()
473  << " #TX PSDUs = " << m_txPsdus.size ());
474  }
475  }
476 
477  // Flush the MAC queue of the AP after sending a DL MU PPDU (no need for
478  // further transmissions)
479  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
480  {
481  auto dev = DynamicCast<WifiNetDevice> (m_apDevice);
482  Ptr<WifiMacQueue> queue = DynamicCast<RegularWifiMac> (dev->GetMac ())->GetQosTxop (AC_BE)->GetWifiMacQueue ();
483  m_flushed = queue->GetNPackets ();
484  queue->Flush ();
485  }
486  else if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
487  && psduMap.begin ()->second->GetHeader (0).HasData ())
488  {
489  Mac48Address sender = psduMap.begin ()->second->GetAddr2 ();
490 
491  for (uint32_t i = 0; i < m_staDevices.GetN (); i++)
492  {
493  auto dev = DynamicCast<WifiNetDevice> (m_staDevices.Get (i));
494 
495  if (dev->GetAddress () == sender)
496  {
497  Ptr<QosTxop> qosTxop = DynamicCast<RegularWifiMac> (dev->GetMac ())->GetQosTxop (AC_BE);
498 
500  {
501  // stations use worse access parameters, trace CW. MU AIFSN must be large
502  // enough to avoid collisions between stations trying to transmit using EDCA
503  // right after the UL MU transmission and the AP trying to send a DL MU PPDU
504  qosTxop->TraceConnectWithoutContext ("CwTrace",
506  this).Bind (i));
507  }
508  else
509  {
510  // there is no "protection" against collisions from stations, hence flush
511  // their MAC queues after sending an HE TB PPDU containing QoS data frames,
512  // so that the AP can send a DL MU PPDU
513  qosTxop->GetWifiMacQueue ()->Flush ();
514  }
515  break;
516  }
517  }
518  }
519  else if (!txVector.IsMu () && psduMap.begin ()->second->GetHeader (0).IsBlockAck ()
520  && psduMap.begin ()->second->GetHeader (0).GetAddr2 () == m_apDevice->GetAddress ()
522  {
523  CtrlBAckResponseHeader blockAck;
524  psduMap.begin ()->second->GetPayload (0)->PeekHeader (blockAck);
525 
526  if (blockAck.IsMultiSta ())
527  {
528  // AP is transmitting a multi-STA BlockAck and stations have to disable EDCA,
529  // record the starting time
530  m_edcaDisabledStartTime = Simulator::Now () + m_txPsdus.back ().endTx - m_txPsdus.back ().startTx;
531  }
532  }
533 }
534 
535 void
536 OfdmaAckSequenceTest::CheckResults (Time sifs, Time slotTime, uint8_t aifsn)
537 {
538  CtrlTriggerHeader trigger;
539  CtrlBAckResponseHeader blockAck;
540  Time tEnd, // TX end for a frame
541  tStart, // TX start fot the next frame
542  tolerance = NanoSeconds (500), // due to propagation delay
543  ifs = (m_txopLimit > 0 ? sifs : sifs + aifsn * slotTime),
544  navEnd;
545 
546  /*
547  * |--------------NAV------------------>|
548  * |------NAV------->| | |------NAV-------->|
549  * |---------| |----------| |---------| |----------| |-----------|
550  * | | |QoS Null 1| | | |QoS Data 1| | |
551  * | BSRP | |----------| | Basic | |----------| | Multi-STA |
552  * | Trigger | |QoS Null 2| | Trigger | |QoS Data 2| | Block Ack |
553  * | Frame |<SIFS>|----------|<IFS>| Frame |<SIFS>|----------|<SIFS>| |
554  * | | |QoS Null 3| | | |QoS Data 3| | |
555  * | | |----------| | | |----------| | |
556  * | | |QoS Null 4| | | |QoS Data 4| | |
557  * -----------------------------------------------------------------------------------------
558  * From: AP AP AP
559  * To: all AP all AP all
560  */
561 
562  // the first packet sent after 1.5s is a BSRP Trigger Frame
563  NS_TEST_EXPECT_MSG_GT_OR_EQ (m_txPsdus.size (), 5, "Expected at least 5 transmitted packet");
564  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[0].psduMap.size () == 1
565  && m_txPsdus[0].psduMap[SU_STA_ID]->GetHeader (0).IsTrigger ()
566  && m_txPsdus[0].psduMap[SU_STA_ID]->GetHeader (0).GetAddr1 ().IsBroadcast ()),
567  true, "Expected a Trigger Frame");
568  m_txPsdus[0].psduMap[SU_STA_ID]->GetPayload (0)->PeekHeader (trigger);
569  NS_TEST_EXPECT_MSG_EQ (trigger.IsBsrp (), true, "Expected a BSRP Trigger Frame");
570  NS_TEST_EXPECT_MSG_EQ (trigger.GetNUserInfoFields (), 4, "Expected one User Info field per station");
571 
572  // A first STA sends 8 QoS Null frames in an HE TB PPDU a SIFS after the reception of the BSRP TF
573  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[1].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
574  && m_txPsdus[1].psduMap.size () == 1
575  && m_txPsdus[1].psduMap.begin ()->second->GetNMpdus () == 8),
576  true, "Expected 8 QoS Null frames in an HE TB PPDU");
577  for (uint8_t i = 0; i < 8; i++)
578  {
579  const WifiMacHeader& hdr = m_txPsdus[1].psduMap.begin ()->second->GetHeader (i);
580  NS_TEST_EXPECT_MSG_EQ (hdr.GetType (), WIFI_MAC_QOSDATA_NULL, "Expected a QoS Null frame");
581  uint8_t tid = hdr.GetQosTid ();
582  if (tid == 0)
583  {
584  NS_TEST_EXPECT_MSG_GT (hdr.GetQosQueueSize (), 0, "Expected a non null queue size for TID " << +tid);
585  }
586  else
587  {
588  NS_TEST_EXPECT_MSG_EQ (hdr.GetQosQueueSize (), 0, "Expected a null queue size for TID " << +tid);
589  }
590  }
591  tEnd = m_txPsdus[0].endTx;
592  navEnd = tEnd + m_txPsdus[0].psduMap[SU_STA_ID]->GetDuration ();
593  tStart = m_txPsdus[1].startTx;
594  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "QoS Null frames in HE TB PPDU sent too early");
595  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "QoS Null frames in HE TB PPDU sent too late");
596  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[1].endTx, "Duration/ID in BSRP Trigger Frame is too short");
597 
598  // A second STA sends 8 QoS Null frames in an HE TB PPDU a SIFS after the reception of the BSRP TF
599  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[2].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
600  && m_txPsdus[2].psduMap.size () == 1
601  && m_txPsdus[2].psduMap.begin ()->second->GetNMpdus () == 8),
602  true, "Expected 8 QoS Null frames in an HE TB PPDU");
603  for (uint8_t i = 0; i < 8; i++)
604  {
605  const WifiMacHeader& hdr = m_txPsdus[2].psduMap.begin ()->second->GetHeader (i);
606  NS_TEST_EXPECT_MSG_EQ (hdr.GetType (), WIFI_MAC_QOSDATA_NULL, "Expected a QoS Null frame");
607  uint8_t tid = hdr.GetQosTid ();
608  if (tid == 0)
609  {
610  NS_TEST_EXPECT_MSG_GT (hdr.GetQosQueueSize (), 0, "Expected a non null queue size for TID " << +tid);
611  }
612  else
613  {
614  NS_TEST_EXPECT_MSG_EQ (hdr.GetQosQueueSize (), 0, "Expected a null queue size for TID " << +tid);
615  }
616  }
617  tStart = m_txPsdus[2].startTx;
618  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "QoS Null frames in HE TB PPDU sent too early");
619  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "QoS Null frames in HE TB PPDU sent too late");
620  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[2].endTx, "Duration/ID in BSRP Trigger Frame is too short");
621 
622  // A third STA sends 8 QoS Null frames in an HE TB PPDU a SIFS after the reception of the BSRP TF
623  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[3].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
624  && m_txPsdus[3].psduMap.size () == 1
625  && m_txPsdus[3].psduMap.begin ()->second->GetNMpdus () == 8),
626  true, "Expected 8 QoS Null frames in an HE TB PPDU");
627  for (uint8_t i = 0; i < 8; i++)
628  {
629  const WifiMacHeader& hdr = m_txPsdus[3].psduMap.begin ()->second->GetHeader (i);
630  NS_TEST_EXPECT_MSG_EQ (hdr.GetType (), WIFI_MAC_QOSDATA_NULL, "Expected a QoS Null frame");
631  uint8_t tid = hdr.GetQosTid ();
632  if (tid == 0)
633  {
634  NS_TEST_EXPECT_MSG_GT (hdr.GetQosQueueSize (), 0, "Expected a non null queue size for TID " << +tid);
635  }
636  else
637  {
638  NS_TEST_EXPECT_MSG_EQ (hdr.GetQosQueueSize (), 0, "Expected a null queue size for TID " << +tid);
639  }
640  }
641  tStart = m_txPsdus[3].startTx;
642  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "QoS Null frames in HE TB PPDU sent too early");
643  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "QoS Null frames in HE TB PPDU sent too late");
644  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[3].endTx, "Duration/ID in BSRP Trigger Frame is too short");
645 
646  // A fourth STA sends 8 QoS Null frames in an HE TB PPDU a SIFS after the reception of the BSRP TF
647  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[4].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
648  && m_txPsdus[4].psduMap.size () == 1
649  && m_txPsdus[4].psduMap.begin ()->second->GetNMpdus () == 8),
650  true, "Expected 8 QoS Null frames in an HE TB PPDU");
651  for (uint8_t i = 0; i < 8; i++)
652  {
653  const WifiMacHeader& hdr = m_txPsdus[4].psduMap.begin ()->second->GetHeader (i);
654  NS_TEST_EXPECT_MSG_EQ (hdr.GetType (), WIFI_MAC_QOSDATA_NULL, "Expected a QoS Null frame");
655  uint8_t tid = hdr.GetQosTid ();
656  if (tid == 0)
657  {
658  NS_TEST_EXPECT_MSG_GT (hdr.GetQosQueueSize (), 0, "Expected a non null queue size for TID " << +tid);
659  }
660  else
661  {
662  NS_TEST_EXPECT_MSG_EQ (hdr.GetQosQueueSize (), 0, "Expected a null queue size for TID " << +tid);
663  }
664  }
665  tStart = m_txPsdus[4].startTx;
666  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "QoS Null frames in HE TB PPDU sent too early");
667  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "QoS Null frames in HE TB PPDU sent too late");
668  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[4].endTx, "Duration/ID in BSRP Trigger Frame is too short");
669 
670  // the AP sends a Basic Trigger Frame to solicit QoS data frames
671  NS_TEST_EXPECT_MSG_GT_OR_EQ (m_txPsdus.size (), 11, "Expected at least 11 transmitted packet");
672  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[5].psduMap.size () == 1
673  && m_txPsdus[5].psduMap[SU_STA_ID]->GetHeader (0).IsTrigger ()
674  && m_txPsdus[5].psduMap[SU_STA_ID]->GetHeader (0).GetAddr1 ().IsBroadcast ()),
675  true, "Expected a Trigger Frame");
676  m_txPsdus[5].psduMap[SU_STA_ID]->GetPayload (0)->PeekHeader (trigger);
677  NS_TEST_EXPECT_MSG_EQ (trigger.IsBasic (), true, "Expected a Basic Trigger Frame");
678  NS_TEST_EXPECT_MSG_EQ (trigger.GetNUserInfoFields (), 4, "Expected one User Info field per station");
679  tEnd = m_txPsdus[1].endTx;
680  tStart = m_txPsdus[5].startTx;
681  NS_TEST_EXPECT_MSG_LT (tEnd + ifs, tStart, "Basic Trigger Frame sent too early");
682  if (m_txopLimit > 0)
683  {
684  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Basic Trigger Frame sent too late");
685  }
686 
687  // A first STA sends QoS data frames in an HE TB PPDU a SIFS after the reception of the Basic TF
688  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[6].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
689  && m_txPsdus[6].psduMap.size () == 1
690  && m_txPsdus[6].psduMap.begin ()->second->GetHeader (0).IsQosData ()),
691  true, "Expected QoS data frames in an HE TB PPDU");
692  tEnd = m_txPsdus[5].endTx;
693  tStart = m_txPsdus[6].startTx;
694  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "QoS data frames in HE TB PPDU sent too early");
695  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "QoS data frames in HE TB PPDU sent too late");
696 
697  // A second STA sends QoS data frames in an HE TB PPDU a SIFS after the reception of the Basic TF
698  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[7].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
699  && m_txPsdus[7].psduMap.size () == 1
700  && m_txPsdus[7].psduMap.begin ()->second->GetHeader (0).IsQosData ()),
701  true, "Expected QoS data frames in an HE TB PPDU");
702  tEnd = m_txPsdus[5].endTx;
703  tStart = m_txPsdus[7].startTx;
704  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "QoS data frames in HE TB PPDU sent too early");
705  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "QoS data frames in HE TB PPDU sent too late");
706 
707  // A third STA sends QoS data frames in an HE TB PPDU a SIFS after the reception of the Basic TF
708  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[8].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
709  && m_txPsdus[8].psduMap.size () == 1
710  && m_txPsdus[8].psduMap.begin ()->second->GetHeader (0).IsQosData ()),
711  true, "Expected QoS data frames in an HE TB PPDU");
712  tEnd = m_txPsdus[5].endTx;
713  tStart = m_txPsdus[8].startTx;
714  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "QoS data frames in HE TB PPDU sent too early");
715  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "QoS data frames in HE TB PPDU sent too late");
716 
717  // A fourth STA sends QoS data frames in an HE TB PPDU a SIFS after the reception of the Basic TF
718  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[9].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
719  && m_txPsdus[9].psduMap.size () == 1
720  && m_txPsdus[9].psduMap.begin ()->second->GetHeader (0).IsQosData ()),
721  true, "Expected QoS data frames in an HE TB PPDU");
722  tEnd = m_txPsdus[5].endTx;
723  tStart = m_txPsdus[9].startTx;
724  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "QoS data frames in HE TB PPDU sent too early");
725  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "QoS data frames in HE TB PPDU sent too late");
726 
727  // the AP sends a Multi-STA Block Ack
728  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[10].psduMap.size () == 1
729  && m_txPsdus[10].psduMap[SU_STA_ID]->GetHeader (0).IsBlockAck ()
730  && m_txPsdus[10].psduMap[SU_STA_ID]->GetHeader (0).GetAddr1 ().IsBroadcast ()),
731  true, "Expected a Block Ack");
732  m_txPsdus[10].psduMap[SU_STA_ID]->GetPayload (0)->PeekHeader (blockAck);
733  NS_TEST_EXPECT_MSG_EQ (blockAck.IsMultiSta (), true, "Expected a Multi-STA Block Ack");
735  "Expected one Per AID TID Info subfield per station");
736  for (uint8_t i = 0; i < 4; i++)
737  {
738  NS_TEST_EXPECT_MSG_EQ (blockAck.GetAckType (i), true, "Expected All-ack context");
739  NS_TEST_EXPECT_MSG_EQ (+blockAck.GetTidInfo (i), 14, "Expected All-ack context");
740  }
741  tEnd = m_txPsdus[9].endTx;
742  tStart = m_txPsdus[10].startTx;
743  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Multi-STA Block Ack sent too early");
744  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Multi-STA Block Ack sent too late");
745 
746  navEnd = m_txPsdus[5].endTx + m_txPsdus[5].psduMap[SU_STA_ID]->GetDuration (); // Basic TF's NAV
747  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[10].endTx, "Duration/ID in Basic Trigger Frame is too short");
748  navEnd = m_txPsdus[6].endTx + m_txPsdus[6].psduMap.begin ()->second->GetDuration (); // 1st QoS Data frame's NAV
749  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[10].endTx, "Duration/ID in 1st QoS Data frame is too short");
750  navEnd = m_txPsdus[7].endTx + m_txPsdus[7].psduMap.begin ()->second->GetDuration (); // 2nd QoS Data frame's NAV
751  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[10].endTx, "Duration/ID in 2nd QoS Data frame is too short");
752  navEnd = m_txPsdus[8].endTx + m_txPsdus[8].psduMap.begin ()->second->GetDuration (); // 3rd QoS Data frame's NAV
753  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[10].endTx, "Duration/ID in 3rd QoS Data frame is too short");
754  navEnd = m_txPsdus[9].endTx + m_txPsdus[9].psduMap.begin ()->second->GetDuration (); // 4th QoS Data frame's NAV
755  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[10].endTx, "Duration/ID in 4th QoS Data frame is too short");
756 
757  // the AP sends a DL MU PPDU
758  NS_TEST_EXPECT_MSG_GT_OR_EQ (m_txPsdus.size (), 12, "Expected at least 12 transmitted packet");
759  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[11].txVector.GetPreambleType (), WIFI_PREAMBLE_HE_MU,
760  "Expected a DL MU PPDU");
761  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[11].psduMap.size (), 4, "Expected 4 PSDUs within the DL MU PPDU");
762  // the TX duration cannot exceed the maximum PPDU duration
763  NS_TEST_EXPECT_MSG_LT_OR_EQ (m_txPsdus[11].endTx - m_txPsdus[11].startTx,
764  GetPpduMaxTime (m_txPsdus[11].txVector.GetPreambleType ()),
765  "TX duration cannot exceed max PPDU duration");
766  for (auto& psdu : m_txPsdus[11].psduMap)
767  {
768  NS_TEST_EXPECT_MSG_LT_OR_EQ (psdu.second->GetSize (), m_maxAmpduSize, "Max A-MPDU size exceeded");
769  }
770  tEnd = m_txPsdus[10].endTx;
771  tStart = m_txPsdus[11].startTx;
772  NS_TEST_EXPECT_MSG_LT_OR_EQ (tEnd + ifs, tStart, "DL MU PPDU sent too early");
773 
774  // The Duration/ID field is the same for all the PSDUs
775  navEnd = m_txPsdus[11].endTx;
776  for (auto& psdu : m_txPsdus[11].psduMap)
777  {
778  if (navEnd == m_txPsdus[11].endTx)
779  {
780  navEnd += psdu.second->GetDuration ();
781  }
782  else
783  {
784  NS_TEST_EXPECT_MSG_EQ (m_txPsdus[11].endTx + psdu.second->GetDuration (), navEnd,
785  "Duration/ID must be the same for all PSDUs");
786  }
787  }
788  NS_TEST_EXPECT_MSG_GT (navEnd, m_txPsdus[11].endTx, "Duration/ID of the DL MU PPDU cannot be zero");
789 
790  std::size_t nTxPsdus = 0;
791 
792  if (m_dlMuAckType == WifiAcknowledgment::DL_MU_BAR_BA_SEQUENCE)
793  {
794  /*
795  * |----------------------------------------NAV---------------------------------------------->|
796  * | |--------------------------NAV---------------------------------->|
797  * | | |-------------------NAV--------------->|
798  * | | | |----NAV---->|
799  * |------| |-----| |-----| |-----| |-----| |-----| |-----| |-----|
800  * |PSDU 1| | | | | | | | | | | | | | |
801  * |------| |Block| |Block| |Block| |Block| |Block| |Block| |Block|
802  * |PSDU 2| | Ack | | Ack | | Ack | | Ack | | Ack | | Ack | | Ack |
803  * |------|<SIFS>| |<SIFS>| Req |<SIFS>| |<SIFS>| Req |<SIFS>| |<SIFS>| Req |<SIFS>| |
804  * |PSDU 3| | | | | | | | | | | | | | |
805  * |------| | | | | | | | | | | | | | |
806  * |PSDU 4| | | | | | | | | | | | | | |
807  * ---------------------------------------------------------------------------------------------------
808  * From: AP STA 1 AP STA 2 AP STA 3 AP STA 4
809  * To: AP STA 2 AP STA 3 AP STA 4 AP
810  */
811  NS_TEST_EXPECT_MSG_GT_OR_EQ (m_txPsdus.size (), 19, "Expected at least 19 packets");
812 
813  // A first STA sends a Block Ack a SIFS after the reception of the DL MU PPDU
814  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[12].psduMap.size () == 1
815  && m_txPsdus[12].psduMap[SU_STA_ID]->GetHeader (0).IsBlockAck ()),
816  true, "Expected a Block Ack");
817  tEnd = m_txPsdus[11].endTx;
818  tStart = m_txPsdus[12].startTx;
819  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "First Block Ack sent too early");
820  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "First Block Ack sent too late");
821 
822  // the AP transmits a Block Ack Request an IFS after the reception of the Block Ack
823  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[13].psduMap.size () == 1
824  && m_txPsdus[13].psduMap[SU_STA_ID]->GetHeader (0).IsBlockAckReq ()),
825  true, "Expected a Block Ack Request");
826  tEnd = m_txPsdus[12].endTx;
827  tStart = m_txPsdus[13].startTx;
828  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "First Block Ack Request sent too early");
829  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "First Block Ack Request sent too late");
830 
831  // A second STA sends a Block Ack a SIFS after the reception of the Block Ack Request
832  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[14].psduMap.size () == 1
833  && m_txPsdus[14].psduMap[SU_STA_ID]->GetHeader (0).IsBlockAck ()),
834  true, "Expected a Block Ack");
835  tEnd = m_txPsdus[13].endTx;
836  tStart = m_txPsdus[14].startTx;
837  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Second Block Ack sent too early");
838  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Second Block Ack sent too late");
839 
840  // the AP transmits a Block Ack Request an IFS after the reception of the Block Ack
841  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[15].psduMap.size () == 1
842  && m_txPsdus[15].psduMap[SU_STA_ID]->GetHeader (0).IsBlockAckReq ()),
843  true, "Expected a Block Ack Request");
844  tEnd = m_txPsdus[14].endTx;
845  tStart = m_txPsdus[15].startTx;
846  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Second Block Ack Request sent too early");
847  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Second Block Ack Request sent too late");
848 
849  // A third STA sends a Block Ack a SIFS after the reception of the Block Ack Request
850  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[16].psduMap.size () == 1
851  && m_txPsdus[16].psduMap[SU_STA_ID]->GetHeader (0).IsBlockAck ()),
852  true, "Expected a Block Ack");
853  tEnd = m_txPsdus[15].endTx;
854  tStart = m_txPsdus[16].startTx;
855  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Third Block Ack sent too early");
856  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Third Block Ack sent too late");
857 
858  // the AP transmits a Block Ack Request an IFS after the reception of the Block Ack
859  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[17].psduMap.size () == 1
860  && m_txPsdus[17].psduMap[SU_STA_ID]->GetHeader (0).IsBlockAckReq ()),
861  true, "Expected a Block Ack Request");
862  tEnd = m_txPsdus[16].endTx;
863  tStart = m_txPsdus[17].startTx;
864  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Third Block Ack Request sent too early");
865  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Third Block Ack Request sent too late");
866 
867  // A fourth STA sends a Block Ack a SIFS after the reception of the Block Ack Request
868  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[18].psduMap.size () == 1
869  && m_txPsdus[18].psduMap[SU_STA_ID]->GetHeader (0).IsBlockAck ()),
870  true, "Expected a Block Ack");
871  tEnd = m_txPsdus[17].endTx;
872  tStart = m_txPsdus[18].startTx;
873  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Fourth Block Ack sent too early");
874  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Fourth Block Ack sent too late");
875 
876  if (m_txopLimit > 0)
877  {
878  // DL MU PPDU's NAV
879  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[18].endTx, "Duration/ID in the DL MU PPDU is too short");
880  // 1st BlockAckReq's NAV
881  navEnd = m_txPsdus[13].endTx + m_txPsdus[13].psduMap[SU_STA_ID]->GetDuration ();
882  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[18].endTx, "Duration/ID in the 1st BlockAckReq is too short");
883  // 2nd BlockAckReq's NAV
884  navEnd = m_txPsdus[15].endTx + m_txPsdus[15].psduMap[SU_STA_ID]->GetDuration ();
885  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[18].endTx, "Duration/ID in the 2nd BlockAckReq is too short");
886  // 3rd BlockAckReq's NAV
887  navEnd = m_txPsdus[17].endTx + m_txPsdus[17].psduMap[SU_STA_ID]->GetDuration ();
888  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[18].endTx, "Duration/ID in the 3rd BlockAckReq is too short");
889  }
890  nTxPsdus = 19;
891  }
892  else if (m_dlMuAckType == WifiAcknowledgment::DL_MU_TF_MU_BAR)
893  {
894  /*
895  * |----------------NAV--------------->|
896  * | |--------NAV------>|
897  * |------| |---------| |-----------|
898  * |PSDU 1| | | |Block Ack 1|
899  * |------| | MU-BAR | |-----------|
900  * |PSDU 2| | Trigger | |Block Ack 2|
901  * |------|<SIFS>| Frame |<SIFS>|-----------|
902  * |PSDU 3| | | |Block Ack 3|
903  * |------| | | |-----------|
904  * |PSDU 4| | | |Block Ack 4|
905  * --------------------------------------------------
906  * From: AP AP
907  * To: all AP
908  */
909  NS_TEST_EXPECT_MSG_GT_OR_EQ (m_txPsdus.size (), 17, "Expected at least 17 packets");
910 
911  // the AP transmits a MU-BAR Trigger Frame an IFS after the transmission of the DL MU PPDU
912  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[12].psduMap.size () == 1
913  && m_txPsdus[12].psduMap[SU_STA_ID]->GetHeader (0).IsTrigger ()),
914  true, "Expected a MU-BAR Trigger Frame");
915  tEnd = m_txPsdus[11].endTx;
916  tStart = m_txPsdus[12].startTx;
917  NS_TEST_EXPECT_MSG_EQ (tStart, tEnd + sifs, "MU-BAR Trigger Frame sent at wrong time");
918 
919  // A first STA sends a Block Ack in an HE TB PPDU a SIFS after the reception of the DL MU PPDU
920  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[13].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
921  && m_txPsdus[13].psduMap.size () == 1
922  && m_txPsdus[13].psduMap.begin ()->second->GetHeader (0).IsBlockAck ()),
923  true, "Expected a Block Ack");
924  tEnd = m_txPsdus[12].endTx;
925  tStart = m_txPsdus[13].startTx;
926  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Block Ack in HE TB PPDU sent too early");
927  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Block Ack in HE TB PPDU sent too late");
928 
929  // A second STA sends a Block Ack in an HE TB PPDU a SIFS after the reception of the DL MU PPDU
930  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[14].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
931  && m_txPsdus[14].psduMap.size () == 1
932  && m_txPsdus[14].psduMap.begin ()->second->GetHeader (0).IsBlockAck ()),
933  true, "Expected a Block Ack");
934  tEnd = m_txPsdus[12].endTx;
935  tStart = m_txPsdus[14].startTx;
936  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Block Ack in HE TB PPDU sent too early");
937  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Block Ack in HE TB PPDU sent too late");
938 
939  // A third STA sends a Block Ack in an HE TB PPDU a SIFS after the reception of the DL MU PPDU
940  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[15].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
941  && m_txPsdus[15].psduMap.size () == 1
942  && m_txPsdus[15].psduMap.begin ()->second->GetHeader (0).IsBlockAck ()),
943  true, "Expected a Block Ack");
944  tEnd = m_txPsdus[12].endTx;
945  tStart = m_txPsdus[15].startTx;
946  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Block Ack in HE TB PPDU sent too early");
947  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Block Ack in HE TB PPDU sent too late");
948 
949  // A fourth STA sends a Block Ack in an HE TB PPDU a SIFS after the reception of the DL MU PPDU
950  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[16].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
951  && m_txPsdus[16].psduMap.size () == 1
952  && m_txPsdus[16].psduMap.begin ()->second->GetHeader (0).IsBlockAck ()),
953  true, "Expected a Block Ack");
954  tEnd = m_txPsdus[12].endTx;
955  tStart = m_txPsdus[16].startTx;
956  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Block Ack in HE TB PPDU sent too early");
957  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Block Ack in HE TB PPDU sent too late");
958 
959  if (m_txopLimit > 0)
960  {
961  // DL MU PPDU's NAV
962  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[13].endTx, "Duration/ID in the DL MU PPDU is too short");
963  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[14].endTx, "Duration/ID in the DL MU PPDU is too short");
964  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[15].endTx, "Duration/ID in the DL MU PPDU is too short");
965  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[16].endTx, "Duration/ID in the DL MU PPDU is too short");
966  }
967  // MU-BAR Trigger Frame's NAV
968  navEnd = m_txPsdus[12].endTx + m_txPsdus[12].psduMap[SU_STA_ID]->GetDuration ();
969  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[13].endTx, "Duration/ID in the MU-BAR Trigger Frame is too short");
970  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[14].endTx, "Duration/ID in the MU-BAR Trigger Frame is too short");
971  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[15].endTx, "Duration/ID in the MU-BAR Trigger Frame is too short");
972  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[16].endTx, "Duration/ID in the MU-BAR Trigger Frame is too short");
973 
974  nTxPsdus = 17;
975  }
976  else if (m_dlMuAckType == WifiAcknowledgment::DL_MU_AGGREGATE_TF)
977  {
978  /*
979  * |--------NAV------>|
980  * |------|-----------| |-----------|
981  * |PSDU 1|MU-BAR TF 1| |Block Ack 1|
982  * |------------------| |-----------|
983  * |PSDU 2|MU-BAR TF 2| |Block Ack 2|
984  * |------------------|<SIFS>|-----------|
985  * |PSDU 3|MU-BAR TF 3| |Block Ack 3|
986  * |------------------| |-----------|
987  * |PSDU 4|MU-BAR TF 4| |Block Ack 4|
988  * --------------------------------------------------
989  * From: AP
990  * To: AP
991  */
992  NS_TEST_EXPECT_MSG_GT_OR_EQ (m_txPsdus.size (), 16, "Expected at least 16 packets");
993 
994  // The last MPDU in each PSDU is a MU-BAR Trigger Frame
995  for (auto& psdu : m_txPsdus[11].psduMap)
996  {
997  NS_TEST_EXPECT_MSG_EQ ((*(--psdu.second->end ()))->GetHeader ().IsTrigger (), true,
998  "Expected an aggregated MU-BAR Trigger Frame");
999  }
1000 
1001  // A first STA sends a Block Ack in an HE TB PPDU a SIFS after the reception of the DL MU PPDU
1002  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[12].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
1003  && m_txPsdus[12].psduMap.size () == 1
1004  && m_txPsdus[12].psduMap.begin ()->second->GetHeader (0).IsBlockAck ()),
1005  true, "Expected a Block Ack");
1006  tEnd = m_txPsdus[11].endTx;
1007  tStart = m_txPsdus[12].startTx;
1008  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Block Ack in HE TB PPDU sent too early");
1009  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Block Ack in HE TB PPDU sent too late");
1010  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[12].endTx, "Duration/ID in the DL MU PPDU is too short");
1011 
1012  // A second STA sends a Block Ack in an HE TB PPDU a SIFS after the reception of the DL MU PPDU
1013  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[13].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
1014  && m_txPsdus[13].psduMap.size () == 1
1015  && m_txPsdus[13].psduMap.begin ()->second->GetHeader (0).IsBlockAck ()),
1016  true, "Expected a Block Ack");
1017  tEnd = m_txPsdus[11].endTx;
1018  tStart = m_txPsdus[13].startTx;
1019  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Block Ack in HE TB PPDU sent too early");
1020  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Block Ack in HE TB PPDU sent too late");
1021  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[13].endTx, "Duration/ID in the DL MU PPDU is too short");
1022 
1023  // A third STA sends a Block Ack in an HE TB PPDU a SIFS after the reception of the DL MU PPDU
1024  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[14].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
1025  && m_txPsdus[14].psduMap.size () == 1
1026  && m_txPsdus[14].psduMap.begin ()->second->GetHeader (0).IsBlockAck ()),
1027  true, "Expected a Block Ack");
1028  tEnd = m_txPsdus[11].endTx;
1029  tStart = m_txPsdus[14].startTx;
1030  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Block Ack in HE TB PPDU sent too early");
1031  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Block Ack in HE TB PPDU sent too late");
1032  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[14].endTx, "Duration/ID in the DL MU PPDU is too short");
1033 
1034  // A fourth STA sends a Block Ack in an HE TB PPDU a SIFS after the reception of the DL MU PPDU
1035  NS_TEST_EXPECT_MSG_EQ ((m_txPsdus[15].txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
1036  && m_txPsdus[15].psduMap.size () == 1
1037  && m_txPsdus[15].psduMap.begin ()->second->GetHeader (0).IsBlockAck ()),
1038  true, "Expected a Block Ack");
1039  tEnd = m_txPsdus[11].endTx;
1040  tStart = m_txPsdus[15].startTx;
1041  NS_TEST_EXPECT_MSG_LT (tEnd + sifs, tStart, "Block Ack in HE TB PPDU sent too early");
1042  NS_TEST_EXPECT_MSG_LT (tStart, tEnd + sifs + tolerance, "Block Ack in HE TB PPDU sent too late");
1043  NS_TEST_EXPECT_MSG_GT_OR_EQ (navEnd + tolerance, m_txPsdus[15].endTx, "Duration/ID in the DL MU PPDU is too short");
1044 
1045  nTxPsdus = 16;
1046  }
1047 
1049  "Not all DL packets have been received");
1050 
1052  {
1053  // EDCA disabled, find the first PSDU transmitted by a station not in an
1054  // HE TB PPDU and check that it was not transmitted before the MU EDCA
1055  // timer expired
1056  for (std::size_t i = nTxPsdus; i < m_txPsdus.size (); ++i)
1057  {
1058  if (m_txPsdus[i].psduMap.size () == 1
1059  && m_txPsdus[i].psduMap.begin ()->second->GetHeader (0).GetAddr2 () != m_apDevice->GetAddress ()
1060  && !m_txPsdus[i].txVector.IsUlMu ())
1061  {
1062  NS_TEST_EXPECT_MSG_GT_OR_EQ (m_txPsdus[i].startTx.GetMicroSeconds (),
1064  + m_muEdcaParameterSet.muTimer * 8192,
1065  "A station transmitted before the MU EDCA timer expired");
1066  break;
1067  }
1068  }
1069  }
1071  {
1072  // stations used worse access parameters after successful UL MU transmission
1073  for (const auto& cwValue : m_cwValues)
1074  {
1075  NS_TEST_EXPECT_MSG_EQ ((cwValue == 2 || cwValue >= m_muEdcaParameterSet.muCwMin),
1076  true, "A station did not set the correct MU CW min");
1077  }
1078  }
1079 
1080  m_txPsdus.clear ();
1081 }
1082 
1083 void
1085 {
1086  RngSeedManager::SetSeed (1);
1087  RngSeedManager::SetRun (2);
1088  int64_t streamNumber = 100;
1089 
1091  wifiApNode.Create (1);
1092 
1094  wifiStaNodes.Create (m_nStations);
1095 
1096  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
1097  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
1098  spectrumChannel->AddPropagationLossModel (lossModel);
1099  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
1100  spectrumChannel->SetPropagationDelayModel (delayModel);
1101 
1103  phy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO);
1104  phy.SetErrorRateModel ("ns3::NistErrorRateModel");
1105  phy.SetChannel (spectrumChannel);
1106  switch (m_channelWidth)
1107  {
1108  case 20:
1109  phy.Set ("ChannelNumber", UintegerValue (36));
1110  break;
1111  case 40:
1112  phy.Set ("ChannelNumber", UintegerValue (38));
1113  break;
1114  case 80:
1115  phy.Set ("ChannelNumber", UintegerValue (42));
1116  break;
1117  case 160:
1118  phy.Set ("ChannelNumber", UintegerValue (50));
1119  break;
1120  default:
1121  NS_ABORT_MSG ("Invalid channel bandwidth (must be 20, 40, 80 or 160)");
1122  }
1123  phy.Set ("ChannelWidth", UintegerValue (m_channelWidth));
1124 
1125  Config::SetDefault ("ns3::HeConfiguration::MuBeAifsn",
1127  Config::SetDefault ("ns3::HeConfiguration::MuBeCwMin",
1129  Config::SetDefault ("ns3::HeConfiguration::MuBeCwMax",
1131  Config::SetDefault ("ns3::HeConfiguration::BeMuEdcaTimer",
1133  // MU EDCA timers must be either all null or all non-null
1134  Config::SetDefault ("ns3::HeConfiguration::BkMuEdcaTimer",
1136  Config::SetDefault ("ns3::HeConfiguration::ViMuEdcaTimer",
1138  Config::SetDefault ("ns3::HeConfiguration::VoMuEdcaTimer",
1140 
1141  // increase MSDU lifetime so that it does not expire before the MU EDCA timer ends
1142  Config::SetDefault ("ns3::WifiMacQueue::MaxDelay", TimeValue (Seconds (2)));
1143 
1144  WifiHelper wifi;
1145  wifi.SetStandard (WIFI_STANDARD_80211ax_5GHZ);
1146  wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
1147 
1149  Ssid ssid = Ssid ("ns-3-ssid");
1150  mac.SetType ("ns3::StaWifiMac",
1151  "BE_MaxAmsduSize", UintegerValue (0),
1152  "BE_MaxAmpduSize", UintegerValue (0),
1153  "Ssid", SsidValue (ssid),
1154  /* setting blockack threshold for sta's BE queue */
1155  "BE_BlockAckThreshold", UintegerValue (2),
1156  "ActiveProbing", BooleanValue (false));
1157 
1158  m_staDevices = wifi.Install (phy, mac, wifiStaNodes);
1159 
1160  mac.SetType ("ns3::ApWifiMac",
1161  "BE_MaxAmsduSize", UintegerValue (0),
1162  "BE_MaxAmpduSize", UintegerValue (0),
1163  "Ssid", SsidValue (ssid),
1164  "BeaconGeneration", BooleanValue (true));
1165  mac.SetMultiUserScheduler ("ns3::TestMultiUserScheduler");
1166  mac.SetAckManager ("ns3::WifiDefaultAckManager", "DlMuAckSequenceType", EnumValue (m_dlMuAckType));
1167 
1168  m_apDevice = wifi.Install (phy, mac, wifiApNode).Get (0);
1169 
1170  // Assign fixed streams to random variables in use
1171  streamNumber += wifi.AssignStreams (NetDeviceContainer (m_apDevice), streamNumber);
1172  streamNumber += wifi.AssignStreams (m_staDevices, streamNumber);
1173 
1175  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1176 
1177  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
1178  positionAlloc->Add (Vector (1.0, 0.0, 0.0));
1179  positionAlloc->Add (Vector (0.0, 1.0, 0.0));
1180  positionAlloc->Add (Vector (-1.0, 0.0, 0.0));
1181  positionAlloc->Add (Vector (-1.0, -1.0, 0.0));
1182  mobility.SetPositionAllocator (positionAlloc);
1183 
1184  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1185  mobility.Install (wifiApNode);
1186  mobility.Install (wifiStaNodes);
1187 
1188  Ptr<WifiNetDevice> dev;
1189 
1190  // Set maximum A-MPDU size
1191  for (uint32_t i = 0; i < m_staDevices.GetN (); i++)
1192  {
1193  dev = DynamicCast<WifiNetDevice> (m_staDevices.Get (i));
1194  dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (m_maxAmpduSize));
1195  }
1196  dev = DynamicCast<WifiNetDevice> (m_apDevice);
1197  dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (m_maxAmpduSize));
1198 
1199  PointerValue ptr;
1200  dev->GetMac ()->GetAttribute ("BE_Txop", ptr);
1201  Ptr<QosTxop> apBeQosTxop = ptr.Get<QosTxop> ();
1202  // set the TXOP limit on BE AC
1203  apBeQosTxop->SetTxopLimit (MicroSeconds (m_txopLimit));
1204 
1205  PacketSocketHelper packetSocket;
1206  packetSocket.Install (wifiApNode);
1207  packetSocket.Install (wifiStaNodes);
1208 
1209  // DL Traffic
1210  for (uint16_t i = 0; i < m_nStations; i++)
1211  {
1212  PacketSocketAddress socket;
1213  socket.SetSingleDevice (m_apDevice->GetIfIndex ());
1214  socket.SetPhysicalAddress (m_staDevices.Get (i)->GetAddress ());
1215  socket.SetProtocol (1);
1216 
1217  // the first client application generates two packets in order
1218  // to trigger the establishment of a Block Ack agreement
1219  Ptr<PacketSocketClient> client1 = CreateObject<PacketSocketClient> ();
1220  client1->SetAttribute ("PacketSize", UintegerValue (1400));
1221  client1->SetAttribute ("MaxPackets", UintegerValue (2));
1222  client1->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
1223  client1->SetRemote (socket);
1224  wifiApNode.Get (0)->AddApplication (client1);
1225  client1->SetStartTime (Seconds (1) + i * MilliSeconds (1));
1226  client1->SetStopTime (Seconds (2.0));
1227 
1228  // the second client application generates the selected number of packets,
1229  // which are sent in DL MU PPDUs.
1230  Ptr<PacketSocketClient> client2 = CreateObject<PacketSocketClient> ();
1231  client2->SetAttribute ("PacketSize", UintegerValue (1400 + i * 100));
1232  client2->SetAttribute ("MaxPackets", UintegerValue (m_nPktsPerSta));
1233  client2->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
1234  client2->SetRemote (socket);
1235  wifiApNode.Get (0)->AddApplication (client2);
1236  client2->SetStartTime (Seconds (1.5));
1237  client2->SetStopTime (Seconds (2.5));
1238 
1239  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
1240  server->SetLocal (socket);
1241  wifiStaNodes.Get (i)->AddApplication (server);
1242  server->SetStartTime (Seconds (0.0));
1243  server->SetStopTime (Seconds (3.0));
1244  }
1245 
1246  // UL Traffic
1247  for (uint16_t i = 0; i < m_nStations; i++)
1248  {
1249  PacketSocketAddress socket;
1250  socket.SetSingleDevice (m_staDevices.Get (i)->GetIfIndex ());
1252  socket.SetProtocol (1);
1253 
1254  // the first client application generates two packets in order
1255  // to trigger the establishment of a Block Ack agreement
1256  Ptr<PacketSocketClient> client1 = CreateObject<PacketSocketClient> ();
1257  client1->SetAttribute ("PacketSize", UintegerValue (1400));
1258  client1->SetAttribute ("MaxPackets", UintegerValue (2));
1259  client1->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
1260  client1->SetRemote (socket);
1261  wifiStaNodes.Get (i)->AddApplication (client1);
1262  client1->SetStartTime (Seconds (1.005) + i * MilliSeconds (1));
1263  client1->SetStopTime (Seconds (2.0));
1264 
1265  // the second client application generates the selected number of packets,
1266  // which are sent in HE TB PPDUs.
1267  Ptr<PacketSocketClient> client2 = CreateObject<PacketSocketClient> ();
1268  client2->SetAttribute ("PacketSize", UintegerValue (1400 + i * 100));
1269  client2->SetAttribute ("MaxPackets", UintegerValue (m_nPktsPerSta));
1270  client2->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
1271  client2->SetRemote (socket);
1272  wifiStaNodes.Get (i)->AddApplication (client2);
1273  client2->SetStartTime (Seconds (1.50011)); // start before sending QoS Null frames
1274  client2->SetStopTime (Seconds (2.5));
1275 
1276  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
1277  server->SetLocal (socket);
1278  wifiApNode.Get (0)->AddApplication (server);
1279  server->SetStartTime (Seconds (0.0));
1280  server->SetStopTime (Seconds (3.0));
1281  }
1282 
1283  Config::Connect ("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx",
1285  // Trace PSDUs passed to the PHY on all devices
1286  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
1288 
1289  Simulator::Stop (Seconds (3));
1290  Simulator::Run ();
1291 
1292  CheckResults (dev->GetMac ()->GetWifiPhy ()->GetSifs (), dev->GetMac ()->GetWifiPhy ()->GetSlot (),
1293  apBeQosTxop->GetAifsn ());
1294 
1295  Simulator::Destroy ();
1296 }
1297 
1298 
1306 {
1307 public:
1309 };
1310 
1312  : TestSuite ("wifi-mac-ofdma", UNIT)
1313 {
1314  using MuEdcaParams = std::initializer_list<OfdmaAckSequenceTest::MuEdcaParameterSet>;
1315 
1316  for (auto& muEdcaParameterSet : MuEdcaParams {{0, 0, 0, 0,} /* no MU EDCA */,
1317  {0, 127, 2047, 100} /* EDCA disabled */,
1318  {10, 127, 2047, 100} /* worse parameters */})
1319  {
1320  AddTestCase (new OfdmaAckSequenceTest (20, WifiAcknowledgment::DL_MU_BAR_BA_SEQUENCE, 10000, 5440, 15, muEdcaParameterSet), TestCase::QUICK);
1321  AddTestCase (new OfdmaAckSequenceTest (20, WifiAcknowledgment::DL_MU_AGGREGATE_TF, 10000, 5440, 15, muEdcaParameterSet), TestCase::QUICK);
1322  AddTestCase (new OfdmaAckSequenceTest (20, WifiAcknowledgment::DL_MU_TF_MU_BAR, 10000, 5440, 15, muEdcaParameterSet), TestCase::QUICK);
1323  AddTestCase (new OfdmaAckSequenceTest (40, WifiAcknowledgment::DL_MU_BAR_BA_SEQUENCE, 10000, 0, 15, muEdcaParameterSet), TestCase::QUICK);
1324  AddTestCase (new OfdmaAckSequenceTest (40, WifiAcknowledgment::DL_MU_AGGREGATE_TF, 10000, 0, 15, muEdcaParameterSet), TestCase::QUICK);
1325  AddTestCase (new OfdmaAckSequenceTest (40, WifiAcknowledgment::DL_MU_TF_MU_BAR, 10000, 0, 15, muEdcaParameterSet), TestCase::QUICK);
1326  }
1327 }
1328 
ns3::SpectrumChannel::SetPropagationDelayModel
void SetPropagationDelayModel(Ptr< PropagationDelayModel > delay)
Set the propagation delay model to be used.
Definition: spectrum-channel.cc:139
ns3::NetDeviceContainer
holds a vector of ns3::NetDevice pointers
Definition: net-device-container.h:42
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::MultiUserScheduler::DL_MU_TX
@ DL_MU_TX
Definition: multi-user-scheduler.h:66
ns3::WIFI_MAC_QOSDATA_NULL
@ WIFI_MAC_QOSDATA_NULL
Definition: wifi-mac-header.h:74
ns3::MultiUserScheduler::UlMuInfo
Information to be provided in case of UL MU transmission.
Definition: multi-user-scheduler.h:79
ns3::TestCase::AddTestCase
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
ns3::ListPositionAllocator::Add
void Add(Vector v)
Add a position to the list of positions.
Definition: position-allocator.cc:70
OfdmaAckSequenceTest::CheckResults
void CheckResults(Time sifs, Time slotTime, uint8_t aifsn)
Check correctness of transmitted frames.
Definition: wifi-mac-ofdma-test.cc:536
ns3::WifiTxVector::SetTxPowerLevel
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
Definition: wifi-tx-vector.cc:241
NS_OBJECT_ENSURE_REGISTERED
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
OfdmaAckSequenceTest::FrameInfo::txVector
WifiTxVector txVector
TXVECTOR.
Definition: wifi-mac-ofdma-test.cc:392
ns3::BooleanValue
AttributeValue implementation for Boolean.
Definition: boolean.h:37
ns3::SpectrumChannel::AddPropagationLossModel
void AddPropagationLossModel(Ptr< PropagationLossModel > loss)
Add the single-frequency propagation loss model to be used.
Definition: spectrum-channel.cc:117
ns3::WifiPsduMap
std::unordered_map< uint16_t, Ptr< WifiPsdu > > WifiPsduMap
Map of PSDUs indexed by STA-ID.
Definition: he-frame-exchange-manager.h:34
OfdmaAckSequenceTest::MuEdcaParameterSet::muTimer
uint8_t muTimer
MU EDCA Timer in units of 8192 microseconds (0 not to use MU EDCA)
Definition: wifi-mac-ofdma-test.cc:336
ns3::WifiMacHeader::GetQosQueueSize
uint8_t GetQosQueueSize(void) const
Get the Queue Size subfield in the QoS control field.
Definition: wifi-mac-header.cc:869
OfdmaAckSequenceTest::FrameInfo::psduMap
WifiConstPsduMap psduMap
transmitted PSDU map
Definition: wifi-mac-ofdma-test.cc:391
ns3::Packet::GetSize
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
ns3::Packet::AddHeader
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
ns3::NetDevice::GetAddress
virtual Address GetAddress(void) const =0
ns3::WifiTxParameters::m_txDuration
Time m_txDuration
TX duration of the frame.
Definition: wifi-tx-parameters.h:65
ns3::MultiUserScheduler
MultiUserScheduler is an abstract base class defining the API that APs supporting at least VHT can us...
Definition: multi-user-scheduler.h:51
OfdmaAckSequenceTest::DoRun
void DoRun(void) override
Implementation to actually run this TestCase.
Definition: wifi-mac-ofdma-test.cc:1084
TestMultiUserScheduler::m_txVector
WifiTxVector m_txVector
the TX vector for MU PPDUs
Definition: wifi-mac-ofdma-test.cc:86
TestMultiUserScheduler::TestMultiUserScheduler
TestMultiUserScheduler()
Definition: wifi-mac-ofdma-test.cc:105
OfdmaAckSequenceTest::L7Receive
void L7Receive(std::string context, Ptr< const Packet > p, const Address &addr)
Function to trace packets received by the server application.
Definition: wifi-mac-ofdma-test.cc:435
OfdmaAckSequenceTest::m_staDevices
NetDeviceContainer m_staDevices
stations' devices
Definition: wifi-mac-ofdma-test.cc:396
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::CtrlTriggerHeader::GetGuardInterval
uint16_t GetGuardInterval(void) const
Get the guard interval duration (in nanoseconds) of the solicited HE TB PPDU.
Definition: ctrl-headers.cc:1919
NS_TEST_EXPECT_MSG_GT_OR_EQ
#define NS_TEST_EXPECT_MSG_GT_OR_EQ(actual, limit, msg)
Test that an actual value is greater than or equal to limit and report if not.
Definition: test.h:1109
ns3::WifiHelper
helps to create WifiNetDevice objects
Definition: wifi-helper.h:327
ns3::MicroSeconds
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
OfdmaAckSequenceTest::MuEdcaParameterSet::muCwMin
uint16_t muCwMin
MU CW min.
Definition: wifi-mac-ofdma-test.cc:334
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
OfdmaAckSequenceTest::m_apDevice
Ptr< NetDevice > m_apDevice
AP's device.
Definition: wifi-mac-ofdma-test.cc:397
ns3::WIFI_STANDARD_80211ax_5GHZ
@ WIFI_STANDARD_80211ax_5GHZ
Definition: wifi-standards.h:135
ns3::WifiMacHeader::SetDsNotFrom
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
Definition: wifi-mac-header.cc:90
ns3::MultiUserScheduler::m_initialFrame
bool m_initialFrame
true if a TXOP is being started
Definition: multi-user-scheduler.h:139
OfdmaAckSequenceTest::m_txopLimit
uint16_t m_txopLimit
TXOP limit in microseconds.
Definition: wifi-mac-ofdma-test.cc:402
TestMultiUserScheduler::m_psduMap
WifiPsduMap m_psduMap
the DL MU PPDU to transmit
Definition: wifi-mac-ofdma-test.cc:88
ns3::TriggerFrameType
TriggerFrameType
The different Trigger frame types.
Definition: ctrl-headers.h:561
ns3::PointerValue
Hold objects of type Ptr<T>.
Definition: pointer.h:37
ns3::Mac48Address
an EUI-48 address
Definition: mac48-address.h:44
Min
#define Min(a, b)
Definition: aarf-wifi-manager.cc:25
ns3::WifiMacQueue::GetNPackets
uint32_t GetNPackets(uint8_t tid, Mac48Address dest) const
Return the number of QoS packets in the queue having tid equal to tid and destination address equal t...
Definition: wifi-mac-queue.cc:594
ns3::PacketSocketAddress
an address for a packet socket
Definition: packet-socket-address.h:39
ns3::ObjectBase::SetAttribute
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
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
WifiMacOfdmaTestSuite
wifi MAC OFDMA Test Suite
Definition: wifi-mac-ofdma-test.cc:1306
ns3::CtrlBAckResponseHeader::GetNPerAidTidInfoSubfields
std::size_t GetNPerAidTidInfoSubfields(void) const
For Multi-STA Block Acks, get the number of Per AID TID Info subfields included in this Block Ack.
Definition: ctrl-headers.cc:621
ns3::WifiMacHeader::GetAddr1
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
Definition: wifi-mac-header.cc:424
third.mac
mac
Definition: third.py:99
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
OfdmaAckSequenceTest::MuEdcaParameterSet
MU EDCA Parameter Set.
Definition: wifi-mac-ofdma-test.cc:332
ns3::WifiTxParameters
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
Definition: wifi-tx-parameters.h:45
ns3::PacketSocketClient::SetRemote
void SetRemote(PacketSocketAddress addr)
set the remote address and protocol to be used
Definition: packet-socket-client.cc:91
ns3::TypeId::SetParent
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
OfdmaAckSequenceTest::m_edcaDisabledStartTime
Time m_edcaDisabledStartTime
time when disabling EDCA started
Definition: wifi-mac-ofdma-test.cc:407
ns3::MultiUserScheduler::SU_TX
@ SU_TX
Definition: multi-user-scheduler.h:65
ns3::EnumValue
Hold variables of type enum.
Definition: enum.h:55
ns3::SsidValue
AttributeValue implementation for Ssid.
Definition: ssid.h:105
ns3::Ssid
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
OfdmaAckSequenceTest::MuEdcaParameterSet::muAifsn
uint8_t muAifsn
MU AIFS (0 to disable EDCA)
Definition: wifi-mac-ofdma-test.cc:333
ns3::WifiTxParameters::m_protection
std::unique_ptr< WifiProtection > m_protection
protection method
Definition: wifi-tx-parameters.h:63
OfdmaAckSequenceTest::m_channelWidth
uint16_t m_channelWidth
PHY channel bandwidth in MHz.
Definition: wifi-mac-ofdma-test.cc:398
TestMultiUserScheduler::m_ulTriggerType
TriggerFrameType m_ulTriggerType
Trigger Frame type for UL MU.
Definition: wifi-mac-ofdma-test.cc:83
TestMultiUserScheduler::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: wifi-mac-ofdma-test.cc:95
ns3::GetPpduMaxTime
Time GetPpduMaxTime(WifiPreamble preamble)
Get the maximum PPDU duration (see Section 10.14 of 802.11-2016) for the PHY layers defining the aPPD...
Definition: wifi-utils.cc:254
ns3::TestCase
encapsulates test code
Definition: test.h:1154
ns3::WifiMacHeader::SetAddr1
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
Definition: wifi-mac-header.cc:108
OfdmaAckSequenceTest::m_maxAmpduSize
uint32_t m_maxAmpduSize
maximum A-MPDU size in bytes
Definition: wifi-mac-ofdma-test.cc:401
TestMultiUserScheduler::m_txFormat
TxFormat m_txFormat
the format of next transmission
Definition: wifi-mac-ofdma-test.cc:82
ns3::WifiMacHeader
Implements the IEEE 802.11 MAC header.
Definition: wifi-mac-header.h:85
ns3::CtrlBAckResponseHeader::IsMultiSta
bool IsMultiSta(void) const
Check if the BlockAck frame variant is Multi-STA Block Ack.
Definition: ctrl-headers.cc:564
ns3::Application::SetStopTime
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:75
TestMultiUserScheduler
Dummy Multi User Scheduler used to test OFDMA ack sequences.
Definition: wifi-mac-ofdma-test.cc:61
ns3::PacketSocketHelper::Install
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Definition: packet-socket-helper.cc:37
third.wifi
wifi
Definition: third.py:96
TestMultiUserScheduler::ComputeUlMuInfo
UlMuInfo ComputeUlMuInfo(void) override
Prepare the information required to solicit an UL MU transmission.
Definition: wifi-mac-ofdma-test.cc:303
ns3::Ptr< WifiMacQueueItem >
OfdmaAckSequenceTest::m_muEdcaParameterSet
MuEdcaParameterSet m_muEdcaParameterSet
MU EDCA Parameter Set.
Definition: wifi-mac-ofdma-test.cc:404
ns3::Application::SetStartTime
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
NS_TEST_EXPECT_MSG_GT
#define NS_TEST_EXPECT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report if not.
Definition: test.h:1088
ns3::WifiMacHeader::GetType
WifiMacType GetType(void) const
Return the type (enum WifiMacType)
Definition: wifi-mac-header.cc:448
ns3::QosTxop::GetAifsn
uint8_t GetAifsn(void) const override
Return the number of slots that make up an AIFS according to the EDCA Parameter Set or the MU EDCA Pa...
Definition: qos-txop.cc:229
OfdmaAckSequenceTest::m_nStations
uint16_t m_nStations
number of stations
Definition: wifi-mac-ofdma-test.cc:395
ns3::WifiMode
represent a single transmission mode
Definition: wifi-mode.h:48
ns3::Now
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
ns3::MultiUserScheduler::m_availableTime
Time m_availableTime
the time available for frame exchange
Definition: multi-user-scheduler.h:138
ns3::NanoSeconds
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
ns3::Address
a polymophic address class
Definition: address.h:91
ns3::Time::GetMicroSeconds
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:388
ns3::MultiUserScheduler::DlMuInfo
Information to be provided in case of DL MU transmission.
Definition: multi-user-scheduler.h:72
NS_LOG_INFO
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
ns3::MilliSeconds
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
ns3::CtrlTriggerHeader::IsBasic
bool IsBasic(void) const
Check if this is a Basic Trigger frame.
Definition: ctrl-headers.cc:1768
ns3::BSRP_TRIGGER
@ BSRP_TRIGGER
Definition: ctrl-headers.h:566
OfdmaAckSequenceTest::FrameInfo
Information about transmitted frames.
Definition: wifi-mac-ofdma-test.cc:388
ns3::Txop::GetWifiMacQueue
Ptr< WifiMacQueue > GetWifiMacQueue() const
Return the packet queue associated with this Txop.
Definition: txop.cc:149
ns3::HeRu::RuType
RuType
The different HE Resource Unit (RU) types.
Definition: he-ru.h:42
ns3::MultiUserScheduler::m_heFem
Ptr< HeFrameExchangeManager > m_heFem
HE Frame Exchange Manager.
Definition: multi-user-scheduler.h:136
OfdmaAckSequenceTest::FrameInfo::endTx
Time endTx
end TX time
Definition: wifi-mac-ofdma-test.cc:390
ns3::CtrlTriggerHeader
Headers for Trigger frames.
Definition: ctrl-headers.h:886
ns3::MultiUserScheduler::UL_MU_TX
@ UL_MU_TX
Definition: multi-user-scheduler.h:67
ns3::AC_BE
@ AC_BE
Best Effort.
Definition: qos-utils.h:73
SU_STA_ID
#define SU_STA_ID
Definition: wifi-mode.h:32
ns3::PointerValue::Get
Ptr< T > Get(void) const
Definition: pointer.h:201
ns3::WIFI_MAC_CTL_TRIGGER
@ WIFI_MAC_CTL_TRIGGER
Definition: wifi-mac-header.h:38
ns3::WifiTxParameters::Clear
void Clear(void)
Reset the TX parameters.
Definition: wifi-tx-parameters.cc:67
OfdmaAckSequenceTest::FrameInfo::startTx
Time startTx
start TX time
Definition: wifi-mac-ofdma-test.cc:389
ns3::WIFI_PREAMBLE_HE_MU
@ WIFI_PREAMBLE_HE_MU
Definition: wifi-phy-common.h:71
ns3::WifiTxVector::GetPreambleType
WifiPreamble GetPreambleType(void) const
Definition: wifi-tx-vector.cc:147
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
TestMultiUserScheduler::m_tbPpduDuration
Time m_tbPpduDuration
Duration of the solicited TB PPDUs.
Definition: wifi-mac-ofdma-test.cc:85
ns3::Time
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
TestMultiUserScheduler::SelectTxFormat
TxFormat SelectTxFormat(void) override
Select the format of the next transmission.
Definition: wifi-mac-ofdma-test.cc:118
ns3::WifiTxVector::SetChannelWidth
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
Definition: wifi-tx-vector.cc:253
third.wifiApNode
wifiApNode
Definition: third.py:90
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::MultiUserScheduler::m_apMac
Ptr< ApWifiMac > m_apMac
the AP wifi MAC
Definition: multi-user-scheduler.h:135
ns3::CtrlTriggerHeader::GetNUserInfoFields
std::size_t GetNUserInfoFields(void) const
Get the number of User Info fields in this Trigger Frame.
Definition: ctrl-headers.cc:2034
ns3::PacketSocketAddress::SetSingleDevice
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Definition: packet-socket-address.cc:46
ns3::PacketSocketHelper
Give ns3::PacketSocket powers to ns3::Node.
Definition: packet-socket-helper.h:32
ns3::MultiUserScheduler::GetWifiRemoteStationManager
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(void) const
Get the station manager attached to the AP.
Definition: multi-user-scheduler.cc:121
ns3::WifiTxVector::IsMu
bool IsMu(void) const
Return true if this TX vector is used for a multi-user transmission.
Definition: wifi-tx-vector.cc:369
ns3::CtrlTriggerHeader::SetUlLength
void SetUlLength(uint16_t len)
Set the UL Length subfield of the Common Info field.
Definition: ctrl-headers.cc:1816
ns3::QosTxop
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:75
ns3::WifiTxParameters::m_acknowledgment
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
Definition: wifi-tx-parameters.h:64
TestMultiUserScheduler::~TestMultiUserScheduler
virtual ~TestMultiUserScheduler()
Definition: wifi-mac-ofdma-test.cc:112
ns3::WifiMacQueueItem::QueueIteratorPair
Information needed to remove an MSDU from the queue.
Definition: wifi-mac-queue-item.h:147
ns3::MakeCallback
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
WifiMacOfdmaTestSuite::WifiMacOfdmaTestSuite
WifiMacOfdmaTestSuite()
Definition: wifi-mac-ofdma-test.cc:1311
OfdmaAckSequenceTest::m_received
uint16_t m_received
number of packets received by the stations
Definition: wifi-mac-ofdma-test.cc:405
OfdmaAckSequenceTest::MuEdcaParameterSet::muCwMax
uint16_t muCwMax
MU CW max.
Definition: wifi-mac-ofdma-test.cc:335
ns3::WifiMacHeader::SetAddr2
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
Definition: wifi-mac-header.cc:114
OfdmaAckSequenceTest::m_cwValues
std::vector< uint32_t > m_cwValues
CW used by stations after MU exchange.
Definition: wifi-mac-ofdma-test.cc:408
ns3::WifiMacHeader::GetQosTid
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
Definition: wifi-mac-header.cc:862
ns3::TestSuite
A suite of tests to run.
Definition: test.h:1344
NS_LOG_FUNCTION_NOARGS
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log-macros-enabled.h:209
OfdmaAckSequenceTest::~OfdmaAckSequenceTest
virtual ~OfdmaAckSequenceTest()
Definition: wifi-mac-ofdma-test.cc:430
ns3::CtrlBAckResponseHeader::GetAckType
bool GetAckType(std::size_t index) const
For Multi-STA Block Acks, get the Ack Type subfield of the Per AID TID Info subfield identified by th...
Definition: ctrl-headers.cc:597
ns3::Config::Connect
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
ns3::CtrlBAckResponseHeader::GetTidInfo
uint8_t GetTidInfo(std::size_t index=0) const
For Block Ack variants other than Multi-STA Block Ack, get the TID_INFO subfield of the BA Control fi...
Definition: ctrl-headers.cc:510
NS_TEST_EXPECT_MSG_LT_OR_EQ
#define NS_TEST_EXPECT_MSG_LT_OR_EQ(actual, limit, msg)
Test that an actual value is less than or equal to a limit and report if not.
Definition: test.h:922
OfdmaAckSequenceTest::m_dlMuAckType
WifiAcknowledgment::Method m_dlMuAckType
DL MU ack sequence type.
Definition: wifi-mac-ofdma-test.cc:400
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
ns3::WifiTxParameters::m_txVector
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
Definition: wifi-tx-parameters.h:62
OfdmaAckSequenceTest::m_nPktsPerSta
uint16_t m_nPktsPerSta
number of packets to send to each station
Definition: wifi-mac-ofdma-test.cc:403
OfdmaAckSequenceTest
Test OFDMA acknowledgment sequences.
Definition: wifi-mac-ofdma-test.cc:326
ns3::Seconds
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
OfdmaAckSequenceTest::TraceCw
void TraceCw(uint32_t staIndex, uint32_t oldCw, uint32_t cw)
Function to trace CW value used by the given station after the MU exchange.
Definition: wifi-mac-ofdma-test.cc:444
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::PacketSocketAddress::SetPhysicalAddress
void SetPhysicalAddress(const Address address)
Set the destination address.
Definition: packet-socket-address.cc:53
ns3::BASIC_TRIGGER
@ BASIC_TRIGGER
Definition: ctrl-headers.h:562
third.ssid
ssid
Definition: third.py:100
ns3::TimeValue
AttributeValue implementation for Time.
Definition: nstime.h:1353
OfdmaAckSequenceTest::OfdmaAckSequenceTest
OfdmaAckSequenceTest(uint16_t width, WifiAcknowledgment::Method dlType, uint32_t maxAmpduSize, uint16_t txopLimit, uint16_t nPktsPerSta, MuEdcaParameterSet muEdcaParameterSet)
Constructor.
Definition: wifi-mac-ofdma-test.cc:411
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::Txop::SetTxopLimit
void SetTxopLimit(Time txopLimit)
Set the TXOP limit.
Definition: txop.cc:249
g_wifiMacOfdmaTestSuite
static WifiMacOfdmaTestSuite g_wifiMacOfdmaTestSuite
the test suite
Definition: wifi-mac-ofdma-test.cc:1329
ns3::CtrlTriggerHeader::IsBsrp
bool IsBsrp(void) const
Check if this is a Buffer Status Report Poll Trigger frame.
Definition: ctrl-headers.cc:1792
ns3::NodeContainer
keep track of a set of node pointers.
Definition: node-container.h:39
TestMultiUserScheduler::ComputeDlMuInfo
DlMuInfo ComputeDlMuInfo(void) override
Compute the information required to perform a DL MU transmission.
Definition: wifi-mac-ofdma-test.cc:296
TestMultiUserScheduler::ComputeWifiTxVector
void ComputeWifiTxVector(void)
Compute the TX vector to use for MU PPDUs.
Definition: wifi-mac-ofdma-test.cc:243
OfdmaAckSequenceTest::m_flushed
uint16_t m_flushed
number of DL packets flushed after DL MU PPDU
Definition: wifi-mac-ofdma-test.cc:406
TestMultiUserScheduler::m_txParams
WifiTxParameters m_txParams
TX parameters.
Definition: wifi-mac-ofdma-test.cc:87
third.wifiStaNodes
wifiStaNodes
Definition: third.py:88
ns3::MultiUserScheduler::m_sizeOf8QosNull
uint32_t m_sizeOf8QosNull
size in bytes of 8 QoS Null frames
Definition: multi-user-scheduler.h:140
OfdmaAckSequenceTest::m_txPsdus
std::vector< FrameInfo > m_txPsdus
transmitted PSDUs
Definition: wifi-mac-ofdma-test.cc:399
ns3::PacketSocketAddress::SetProtocol
void SetProtocol(uint16_t protocol)
Set the protocol.
Definition: packet-socket-address.cc:33
ns3::WifiAcknowledgment::Method
Method
Available acknowledgment methods.
Definition: wifi-acknowledgment.h:51
ns3::UintegerValue
Hold an unsigned integer type.
Definition: uinteger.h:44
OfdmaAckSequenceTest::Transmit
void Transmit(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when FrameExchangeManager passes PSDUs to the PHY.
Definition: wifi-mac-ofdma-test.cc:455
TestMultiUserScheduler::m_trigger
Ptr< WifiMacQueueItem > m_trigger
Trigger Frame to send.
Definition: wifi-mac-ofdma-test.cc:84
ns3::WifiMacHelper
create MAC layers for a ns3::WifiNetDevice.
Definition: wifi-mac-helper.h:48
ns3::Config::SetDefault
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
ns3::NetDeviceContainer::GetN
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
Definition: net-device-container.cc:57
ns3::WifiMacHeader::SetDsNotTo
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
Definition: wifi-mac-header.cc:102
ns3::ObjectBase::TraceConnectWithoutContext
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
ns3::MultiUserScheduler::TxFormat
TxFormat
Enumeration of the possible transmission formats.
Definition: multi-user-scheduler.h:63
ns3::PacketSocketServer::SetLocal
void SetLocal(PacketSocketAddress addr)
set the local address and protocol to be used
Definition: packet-socket-server.cc:102
ns3::NetDeviceContainer::Get
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
Definition: net-device-container.cc:62
ns3::WIFI_PREAMBLE_HE_TB
@ WIFI_PREAMBLE_HE_TB
Definition: wifi-phy-common.h:72
ns3::NetDevice::GetIfIndex
virtual uint32_t GetIfIndex(void) const =0
ns3::WifiTxVector::SetPreambleType
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
Definition: wifi-tx-vector.cc:247
ns3::MobilityHelper
Helper class used to assign positions and mobility models to nodes.
Definition: mobility-helper.h:43
ns3::SpectrumWifiPhyHelper
Make it easy to create and manage PHY objects for the spectrum model.
Definition: spectrum-wifi-helper.h:38
third.mobility
mobility
Definition: third.py:108
third.phy
phy
Definition: third.py:93
NS_TEST_EXPECT_MSG_LT
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
Definition: test.h:901
ns3::CtrlBAckResponseHeader
Headers for BlockAck response.
Definition: ctrl-headers.h:202
ns3::WifiNetDevice::GetMac
Ptr< WifiMac > GetMac(void) const
Definition: wifi-net-device.cc:201
NS_ABORT_MSG
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50