A Discrete-Event Network Simulator
API
wifi-aggregation-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
18  */
19 
20 #include "ns3/eht-configuration.h"
21 #include "ns3/fcfs-wifi-queue-scheduler.h"
22 #include "ns3/he-configuration.h"
23 #include "ns3/ht-configuration.h"
24 #include "ns3/ht-frame-exchange-manager.h"
25 #include "ns3/interference-helper.h"
26 #include "ns3/mac-tx-middle.h"
27 #include "ns3/mgt-action-headers.h"
28 #include "ns3/mobility-helper.h"
29 #include "ns3/mpdu-aggregator.h"
30 #include "ns3/msdu-aggregator.h"
31 #include "ns3/multi-link-element.h"
32 #include "ns3/node-container.h"
33 #include "ns3/packet-socket-client.h"
34 #include "ns3/packet-socket-helper.h"
35 #include "ns3/packet-socket-server.h"
36 #include "ns3/pointer.h"
37 #include "ns3/simulator.h"
38 #include "ns3/sta-wifi-mac.h"
39 #include "ns3/string.h"
40 #include "ns3/test.h"
41 #include "ns3/vht-configuration.h"
42 #include "ns3/wifi-default-ack-manager.h"
43 #include "ns3/wifi-default-protection-manager.h"
44 #include "ns3/wifi-mac-queue.h"
45 #include "ns3/wifi-net-device.h"
46 #include "ns3/wifi-psdu.h"
47 #include "ns3/yans-wifi-helper.h"
48 #include "ns3/yans-wifi-phy.h"
49 #include <ns3/attribute-container.h>
50 
51 #include <algorithm>
52 #include <iterator>
53 #include <vector>
54 
55 using namespace ns3;
56 
64 {
65  public:
67 
69  struct Params
70  {
72  uint8_t nLinks;
73  std::string dataMode;
74  uint16_t bufferSize;
75  uint16_t maxAmsduSize;
76  uint32_t maxAmpduSize;
78  };
79 
86  AmpduAggregationTest(const std::string& name, const Params& params);
87 
88  protected:
94  void EstablishAgreement(const Mac48Address& recipient);
95 
103  void EnqueuePkts(std::size_t count, uint32_t size, const Mac48Address& dest);
104 
108  Ptr<QosTxop> GetBeQueue() const;
109 
115  void DequeueMpdus(const std::vector<Ptr<WifiMpdu>>& mpduList);
116 
118  std::vector<Ptr<WifiPhy>> m_phys;
120 
121  private:
128  void MpduDiscarded(WifiMacDropReason reason, Ptr<const WifiMpdu> mpdu);
129 
130  void DoSetup() override;
131  void DoRun() override;
132  void DoTeardown() override;
133 
135  std::vector<Ptr<WifiRemoteStationManager>> m_managers;
137  bool m_discarded;
138 };
139 
141  : AmpduAggregationTest("Check the correctness of MPDU aggregation operations",
142  Params{.standard = WIFI_STANDARD_80211n,
143  .nLinks = 1,
144  .dataMode = "HtMcs7",
145  .bufferSize = 64,
146  .maxAmsduSize = 0,
147  .maxAmpduSize = 65535,
148  .txopLimit = Seconds(0)})
149 {
150 }
151 
153  : TestCase(name),
154  m_params(params),
155  m_discarded(false)
156 {
157 }
158 
159 void
161 {
162  m_discarded = true;
163 }
164 
165 void
167 {
168  /*
169  * Create device and attach HT configuration.
170  */
171  m_device = CreateObject<WifiNetDevice>();
173  auto htConfiguration = CreateObject<HtConfiguration>();
174  m_device->SetHtConfiguration(htConfiguration);
176  {
177  auto vhtConfiguration = CreateObject<VhtConfiguration>();
178  m_device->SetVhtConfiguration(vhtConfiguration);
179  auto heConfiguration = CreateObject<HeConfiguration>();
180  m_device->SetHeConfiguration(heConfiguration);
181  }
183  {
184  auto ehtConfiguration = CreateObject<EhtConfiguration>();
185  m_device->SetEhtConfiguration(ehtConfiguration);
186  }
187 
188  /*
189  * Create and configure phy layer.
190  */
191  for (uint8_t i = 0; i < m_params.nLinks; i++)
192  {
193  m_phys.emplace_back(CreateObject<YansWifiPhy>());
194  auto interferenceHelper = CreateObject<InterferenceHelper>();
195  m_phys.back()->SetInterferenceHelper(interferenceHelper);
196  m_phys.back()->SetDevice(m_device);
197  m_phys.back()->ConfigureStandard(m_params.standard);
198  }
200 
201  /*
202  * Create and configure manager.
203  */
205  m_factory.SetTypeId("ns3::ConstantRateWifiManager");
206  m_factory.Set("DataMode", StringValue(m_params.dataMode));
207  for (uint8_t i = 0; i < m_params.nLinks; i++)
208  {
210  m_managers.back()->SetupPhy(m_phys.at(i));
211  }
213 
214  /*
215  * Create and configure mac layer.
216  */
217  m_mac = CreateObjectWithAttributes<StaWifiMac>("QosSupported", BooleanValue(true));
220  for (uint8_t i = 0; i < m_params.nLinks; i++)
221  {
222  m_managers.at(i)->SetupMac(m_mac);
223  }
224  m_mac->SetAddress(Mac48Address("00:00:00:00:00:01"));
228  for (uint8_t i = 0; i < m_params.nLinks; i++)
229  {
230  auto fem = m_mac->GetFrameExchangeManager(i);
231  auto protectionManager = CreateObject<WifiDefaultProtectionManager>();
232  protectionManager->SetWifiMac(m_mac);
233  fem->SetProtectionManager(protectionManager);
234  auto ackManager = CreateObject<WifiDefaultAckManager>();
235  ackManager->SetWifiMac(m_mac);
236  fem->SetAckManager(ackManager);
237  // here we should assign link addresses in case of MLDs, but we don't actually use link
238  // addresses in this test
239  }
240  m_mac->SetState(StaWifiMac::ASSOCIATED);
241  if (m_params.nLinks > 1)
242  {
243  // the bssid field of StaLinkEntity must hold a value
244  for (const auto& [id, link] : m_mac->GetLinks())
245  {
246  static_cast<StaWifiMac::StaLinkEntity&>(*link).bssid = Mac48Address::GetBroadcast();
247  }
248  }
249  m_mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
250 
251  /*
252  * Configure A-MSDU and A-MPDU aggregation.
253  */
254  // Make sure that at least 1024 MPDUs are buffered (to test aggregation on EHT devices)
255  m_mac->GetTxopQueue(AC_BE)->SetAttribute("MaxSize", StringValue("2000p"));
256  m_mac->SetAttribute("BE_MaxAmsduSize", UintegerValue(m_params.maxAmsduSize));
257  m_mac->SetAttribute("BE_MaxAmpduSize", UintegerValue(m_params.maxAmpduSize));
259  "TxopLimits",
261 
262  if (m_params.nLinks > 1)
263  {
264  auto mleCommonInfo2 = std::make_shared<CommonInfoBasicMle>();
265  mleCommonInfo2->m_mldMacAddress = Mac48Address("00:00:00:00:00:02");
266  for (uint8_t i = 0; i < m_params.nLinks; i++)
267  {
268  // we don't actually use the link addresses of the receiver, so we just use one address
269  // as both the MLD address and the link address of the receiver (the first argument in
270  // the call below should be the link address)
271  m_managers.at(i)->AddStationMleCommonInfo(mleCommonInfo2->m_mldMacAddress,
272  mleCommonInfo2);
273  }
274 
275  auto mleCommonInfo3 = std::make_shared<CommonInfoBasicMle>();
276  mleCommonInfo3->m_mldMacAddress = Mac48Address("00:00:00:00:00:03");
277  for (uint8_t i = 0; i < m_params.nLinks; i++)
278  {
279  m_managers.at(i)->AddStationMleCommonInfo(mleCommonInfo3->m_mldMacAddress,
280  mleCommonInfo3);
281  }
282  }
283 
284  for (uint8_t i = 0; i < m_params.nLinks; i++)
285  {
286  HtCapabilities htCapabilities;
287  htCapabilities.SetMaxAmsduLength(7935);
288  htCapabilities.SetMaxAmpduLength(65535);
289  m_managers.at(i)->AddStationHtCapabilities(Mac48Address("00:00:00:00:00:02"),
290  htCapabilities);
291  m_managers.at(i)->AddStationHtCapabilities(Mac48Address("00:00:00:00:00:03"),
292  htCapabilities);
293 
295  {
296  VhtCapabilities vhtCapabilities;
297  vhtCapabilities.SetMaxMpduLength(11454);
298  m_managers.at(i)->AddStationVhtCapabilities(Mac48Address("00:00:00:00:00:02"),
299  vhtCapabilities);
300  }
302  {
303  HeCapabilities heCapabilities;
304  heCapabilities.SetMaxAmpduLength((1 << 23) - 1);
305  m_managers.at(i)->AddStationHeCapabilities(Mac48Address("00:00:00:00:00:02"),
306  heCapabilities);
307  }
309  {
310  EhtCapabilities ehtCapabilities;
311  ehtCapabilities.SetMaxMpduLength(11454);
312  ehtCapabilities.SetMaxAmpduLength((1 << 24) - 1);
313  m_managers.at(i)->AddStationEhtCapabilities(Mac48Address("00:00:00:00:00:02"),
314  ehtCapabilities);
315  }
316  }
317 
318  /*
319  * Establish agreement.
320  */
321  EstablishAgreement(Mac48Address("00:00:00:00:00:02"));
322 }
323 
326 {
327  return m_mac->GetBEQueue();
328 }
329 
330 void
332 {
333  std::list<Ptr<const WifiMpdu>> mpdus(mpduList.cbegin(), mpduList.cend());
334  m_mac->GetTxopQueue(AC_BE)->DequeueIfQueued(mpdus);
335 }
336 
337 void
339 {
340  MgtAddBaRequestHeader reqHdr;
341  reqHdr.SetImmediateBlockAck();
342  reqHdr.SetTid(0);
344  reqHdr.SetTimeout(0);
345  reqHdr.SetStartingSequence(0);
346  GetBeQueue()->GetBaManager()->CreateOriginatorAgreement(reqHdr, recipient);
347 
348  MgtAddBaResponseHeader respHdr;
349  StatusCode code;
350  code.SetSuccess();
351  respHdr.SetStatusCode(code);
352  respHdr.SetAmsduSupport(reqHdr.IsAmsduSupported());
353  respHdr.SetImmediateBlockAck();
354  respHdr.SetTid(reqHdr.GetTid());
356  respHdr.SetTimeout(reqHdr.GetTimeout());
357  GetBeQueue()->GetBaManager()->UpdateOriginatorAgreement(respHdr, recipient, 0);
358 }
359 
360 void
361 AmpduAggregationTest::EnqueuePkts(std::size_t count, uint32_t size, const Mac48Address& dest)
362 {
363  for (std::size_t i = 0; i < count; i++)
364  {
365  auto pkt = Create<Packet>(size);
366  WifiMacHeader hdr;
367 
368  hdr.SetAddr1(dest);
369  hdr.SetAddr2(Mac48Address("00:00:00:00:00:01"));
371  hdr.SetQosTid(0);
372 
373  GetBeQueue()->GetWifiMacQueue()->Enqueue(Create<WifiMpdu>(pkt, hdr));
374  }
375 }
376 
377 void
379 {
380  /*
381  * Test behavior when no other packets are in the queue
382  */
384  auto htFem = DynamicCast<HtFrameExchangeManager>(fem);
385  auto mpduAggregator = htFem->GetMpduAggregator();
386 
387  /*
388  * Create a dummy packet of 1500 bytes and fill mac header fields.
389  */
390  EnqueuePkts(1, 1500, Mac48Address("00:00:00:00:00:02"));
391 
392  auto peeked = GetBeQueue()->PeekNextMpdu(SINGLE_LINK_OP_ID);
393  WifiTxParameters txParams;
394  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
395  peeked->GetHeader(),
396  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
397  auto item = GetBeQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
398 
399  auto mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
400 
401  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), true, "a single packet should not result in an A-MPDU");
402 
403  // the packet has not been "transmitted", release its sequence number
404  m_mac->m_txMiddle->SetSequenceNumberFor(&item->GetHeader());
405  item->UnassignSeqNo();
406 
407  //---------------------------------------------------------------------------------------------
408 
409  /*
410  * Test behavior when 2 more packets are in the queue
411  */
412  EnqueuePkts(2, 1500, Mac48Address("00:00:00:00:00:02"));
413 
414  item = GetBeQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
415  mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
416 
417  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), false, "MPDU aggregation failed");
418 
419  auto psdu = Create<WifiPsdu>(mpduList);
420  DequeueMpdus(mpduList);
421 
422  NS_TEST_EXPECT_MSG_EQ(psdu->GetSize(), 4606, "A-MPDU size is not correct");
423  NS_TEST_EXPECT_MSG_EQ(mpduList.size(), 3, "A-MPDU should contain 3 MPDUs");
424  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
425  0,
426  "queue should be empty");
427 
428  for (uint32_t i = 0; i < psdu->GetNMpdus(); i++)
429  {
430  NS_TEST_EXPECT_MSG_EQ(psdu->GetHeader(i).GetSequenceNumber(), i, "wrong sequence number");
431  }
432 
433  //---------------------------------------------------------------------------------------------
434 
435  /*
436  * Test behavior when the 802.11n station and another non-QoS station are associated to the AP.
437  * The AP sends an A-MPDU to the 802.11n station followed by the last retransmission of a
438  * non-QoS data frame to the non-QoS station. This is used to reproduce bug 2224.
439  */
440  EnqueuePkts(1, 1500, Mac48Address("00:00:00:00:00:02"));
441  EnqueuePkts(2, 1500, Mac48Address("00:00:00:00:00:03"));
442 
444  txParams.Clear();
445  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
446  peeked->GetHeader(),
447  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
448  item = GetBeQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
449 
450  mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
451 
452  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(),
453  true,
454  "a single packet for this destination should not result in an A-MPDU");
455  // dequeue the MPDU
456  DequeueMpdus({item});
457 
459  txParams.Clear();
460  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
461  peeked->GetHeader(),
462  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
463  item = GetBeQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
464 
465  mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
466 
467  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(),
468  true,
469  "no MPDU aggregation should be performed if there is no agreement");
470 
472  ->SetMaxSsrc(
473  0); // set to 0 in order to fake that the maximum number of retries has been reached
474  m_mac->TraceConnectWithoutContext("DroppedMpdu",
476  htFem->m_dcf = GetBeQueue();
477  htFem->NormalAckTimeout(item, txParams.m_txVector);
478 
479  NS_TEST_EXPECT_MSG_EQ(m_discarded, true, "packet should be discarded");
480  GetBeQueue()->GetWifiMacQueue()->Flush();
481 }
482 
483 void
485 {
486  Simulator::Destroy();
487 
488  for (auto manager : m_managers)
489  {
490  manager->Dispose();
491  }
492  m_managers.clear();
493 
494  m_device->Dispose();
495  m_device = nullptr;
496 }
497 
505 {
506  public:
508 
509  private:
510  void DoRun() override;
511 };
512 
514  : AmpduAggregationTest("Check the correctness of two-level aggregation operations",
515  Params{.standard = WIFI_STANDARD_80211n,
516  .nLinks = 1,
517  .dataMode = "HtMcs2", // 19.5Mbps
518  .bufferSize = 64,
519  .maxAmsduSize = 3050,
520  .maxAmpduSize = 65535,
521  .txopLimit = MicroSeconds(3008)})
522 {
523 }
524 
525 void
527 {
528  /*
529  * Create dummy packets of 1500 bytes and fill mac header fields that will be used for the
530  * tests.
531  */
532  EnqueuePkts(3, 1500, Mac48Address("00:00:00:00:00:02"));
533 
534  //---------------------------------------------------------------------------------------------
535 
536  /*
537  * Test MSDU and MPDU aggregation. Three MSDUs are in the queue and the maximum A-MSDU size
538  * is such that only two MSDUs can be aggregated. Therefore, the first MPDU we get contains
539  * an A-MSDU of 2 MSDUs.
540  */
542  auto htFem = DynamicCast<HtFrameExchangeManager>(fem);
543  auto msduAggregator = htFem->GetMsduAggregator();
544  auto mpduAggregator = htFem->GetMpduAggregator();
545 
546  auto peeked = GetBeQueue()->PeekNextMpdu(SINGLE_LINK_OP_ID);
547  WifiTxParameters txParams;
548  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
549  peeked->GetHeader(),
550  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
551  htFem->TryAddMpdu(peeked, txParams, Time::Min());
552  auto item = msduAggregator->GetNextAmsdu(peeked, txParams, Time::Min());
553 
554  bool result{item};
555  NS_TEST_EXPECT_MSG_EQ(result, true, "aggregation failed");
556  NS_TEST_EXPECT_MSG_EQ(item->GetPacketSize(), 3030, "wrong packet size");
557 
558  // dequeue the MSDUs
559  DequeueMpdus({item});
560 
561  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
562  1,
563  "Unexpected number of MSDUs left in the EDCA queue");
564 
565  //---------------------------------------------------------------------------------------------
566 
567  /*
568  * A-MSDU aggregation fails when there is just one MSDU in the queue.
569  */
570 
572  txParams.Clear();
573  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
574  peeked->GetHeader(),
575  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
576  htFem->TryAddMpdu(peeked, txParams, Time::Min());
577  item = msduAggregator->GetNextAmsdu(peeked, txParams, Time::Min());
578 
579  NS_TEST_EXPECT_MSG_EQ(item, nullptr, "A-MSDU aggregation did not fail");
580 
581  DequeueMpdus({peeked});
582 
583  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
584  0,
585  "queue should be empty");
586 
587  //---------------------------------------------------------------------------------------------
588 
589  /*
590  * Aggregation of MPDUs is stopped to prevent that the PPDU duration exceeds the TXOP limit.
591  * In this test, a TXOP limit of 3008 microseconds is used.
592  */
593 
594  // Add 10 MSDUs to the EDCA queue
595  EnqueuePkts(10, 1300, Mac48Address("00:00:00:00:00:02"));
596 
598  txParams.Clear();
599  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
600  peeked->GetHeader(),
601  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
602 
603  // Compute the first MPDU to be aggregated in an A-MPDU. It must contain an A-MSDU
604  // aggregating two MSDUs
605  item = GetBeQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, m_params.txopLimit, true);
606 
607  NS_TEST_EXPECT_MSG_EQ(std::distance(item->begin(), item->end()),
608  2,
609  "There must be 2 MSDUs in the A-MSDU");
610 
611  auto mpduList = mpduAggregator->GetNextAmpdu(item, txParams, m_params.txopLimit);
612 
613  // The maximum number of bytes that can be transmitted in a TXOP is (approximately, as we
614  // do not consider that the preamble is transmitted at a different rate):
615  // 19.5 Mbps * 3.008 ms = 7332 bytes
616  // Given that the max A-MSDU size is set to 3050, an A-MSDU will contain two MSDUs and have
617  // a size of 2 * 1300 (MSDU size) + 2 * 14 (A-MSDU subframe header size) + 2 (one padding field)
618  // = 2630 bytes Hence, we expect that the A-MPDU will consist of:
619  // - 2 MPDUs containing each an A-MSDU. The size of each MPDU is 2630 (A-MSDU) + 30
620  // (header+trailer) = 2660
621  // - 1 MPDU containing a single MSDU. The size of such MPDU is 1300 (MSDU) + 30 (header+trailer)
622  // = 1330 The size of the A-MPDU is 4 + 2660 + 4 + 2660 + 4 + 1330 = 6662
623  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), false, "aggregation failed");
624  NS_TEST_EXPECT_MSG_EQ(mpduList.size(), 3, "Unexpected number of MPDUs in the A-MPDU");
625  NS_TEST_EXPECT_MSG_EQ(mpduList.at(0)->GetSize(), 2660, "Unexpected size of the first MPDU");
626  NS_TEST_EXPECT_MSG_EQ(mpduList.at(0)->GetHeader().IsQosAmsdu(),
627  true,
628  "Expecting the first MPDU to contain an A-MSDU");
629  NS_TEST_EXPECT_MSG_EQ(mpduList.at(1)->GetSize(), 2660, "Unexpected size of the second MPDU");
630  NS_TEST_EXPECT_MSG_EQ(mpduList.at(1)->GetHeader().IsQosAmsdu(),
631  true,
632  "Expecting the second MPDU to contain an A-MSDU");
633  NS_TEST_EXPECT_MSG_EQ(mpduList.at(2)->GetSize(), 1330, "Unexpected size of the third MPDU");
634  NS_TEST_EXPECT_MSG_EQ(mpduList.at(2)->GetHeader().IsQosAmsdu(),
635  false,
636  "Expecting the third MPDU not to contain an A-MSDU");
637 
638  auto psdu = Create<WifiPsdu>(mpduList);
639  NS_TEST_EXPECT_MSG_EQ(psdu->GetSize(), 6662, "Unexpected size of the A-MPDU");
640 
641  // we now have two A-MSDUs and 6 MSDUs in the queue (5 MSDUs with no assigned sequence number)
642  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
643  8,
644  "Unexpected number of items left in the EDCA queue");
645 
646  // prepare another A-MPDU (e.g., for transmission on another link)
647  peeked = GetBeQueue()->PeekNextMpdu(SINGLE_LINK_OP_ID, 0, psdu->GetAddr1(), mpduList.at(2));
648  txParams.Clear();
649  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
650  peeked->GetHeader(),
651  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
652 
653  // Compute the first MPDU to be aggregated in an A-MPDU. It must contain an A-MSDU
654  // aggregating two MSDUs
655  item = GetBeQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, m_params.txopLimit, true);
656 
657  NS_TEST_EXPECT_MSG_EQ(std::distance(item->begin(), item->end()),
658  2,
659  "There must be 2 MSDUs in the A-MSDU");
660 
661  auto mpduList2 = mpduAggregator->GetNextAmpdu(item, txParams, m_params.txopLimit);
662 
663  // we now have two A-MSDUs, one MSDU, two A-MSDUs and one MSDU in the queue (all with assigned
664  // sequence number)
665  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
666  6,
667  "Unexpected number of items left in the EDCA queue");
668 
669  // unassign sequence numbers for all MPDUs (emulates an RTS/CTS failure on both links)
670  mpduList.at(0)->UnassignSeqNo();
671  mpduList.at(1)->UnassignSeqNo();
672  mpduList.at(2)->UnassignSeqNo();
673  mpduList2.at(0)->UnassignSeqNo();
674  mpduList2.at(1)->UnassignSeqNo();
675  mpduList2.at(2)->UnassignSeqNo();
676 
677  // set A-MSDU max size to a large value
678  m_mac->SetAttribute("BE_MaxAmsduSize", UintegerValue(7000));
679 
680  // A-MSDU aggregation now fails because the first item in the queue contain A-MSDUs
682  txParams.Clear();
683  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
684  peeked->GetHeader(),
685  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
686 
687  htFem->TryAddMpdu(peeked, txParams, Time::Min());
688  item = msduAggregator->GetNextAmsdu(peeked, txParams, Time::Min());
689 
690  NS_TEST_EXPECT_MSG_EQ(item, nullptr, "Expecting not to be able to aggregate A-MSDUs");
691 
692  // remove the first two items in the queue (containing A-MSDUs)
693  DequeueMpdus({mpduList.at(0), mpduList.at(1)});
694 
695  // we now have one MSDU, two A-MSDUs and one MSDU in the queue
696  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
697  4,
698  "Unexpected number of items left in the EDCA queue");
699 
701  txParams.Clear();
702  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
703  peeked->GetHeader(),
704  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
705 
706  NS_TEST_EXPECT_MSG_EQ(peeked->GetHeader().IsQosAmsdu(),
707  false,
708  "Expecting the peeked MPDU not to contain an A-MSDU");
709 
710  item = GetBeQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
711 
712  // A-MSDU aggregation is not attempted because the next item contains an A-MSDU
713  NS_TEST_EXPECT_MSG_EQ(item->GetHeader().IsQosAmsdu(),
714  false,
715  "Expecting the returned MPDU not to contain an A-MSDU");
716 }
717 
726 {
727  public:
733  HeAggregationTest(uint16_t bufferSize);
734 
735  private:
736  void DoRun() override;
737 };
738 
740  : AmpduAggregationTest("Check the correctness of 802.11ax aggregation operations, size=" +
741  std::to_string(bufferSize),
742  Params{.standard = WIFI_STANDARD_80211ax,
743  .nLinks = 1,
744  .dataMode = "HeMcs11",
745  .bufferSize = bufferSize,
746  .maxAmsduSize = 0,
747  .maxAmpduSize = 65535,
748  .txopLimit = Seconds(0)})
749 {
750 }
751 
752 void
754 {
755  /*
756  * Test behavior when 300 packets are ready for transmission
757  */
758  EnqueuePkts(300, 100, Mac48Address("00:00:00:00:00:02"));
759 
761  auto htFem = DynamicCast<HtFrameExchangeManager>(fem);
762  auto mpduAggregator = htFem->GetMpduAggregator();
763 
764  auto peeked = GetBeQueue()->PeekNextMpdu(SINGLE_LINK_OP_ID);
765  WifiTxParameters txParams;
766  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
767  peeked->GetHeader(),
768  m_phys.at(SINGLE_LINK_OP_ID)->GetChannelWidth());
769  auto item = GetBeQueue()->GetNextMpdu(SINGLE_LINK_OP_ID, peeked, txParams, Time::Min(), true);
770 
771  auto mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
772  DequeueMpdus(mpduList);
773 
774  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), false, "MPDU aggregation failed");
775  NS_TEST_EXPECT_MSG_EQ(mpduList.size(),
777  "A-MPDU contains an unexpected number of MPDUs");
778  uint16_t expectedRemainingPacketsInQueue = 300 - m_params.bufferSize;
779  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
780  expectedRemainingPacketsInQueue,
781  "Queue contains an unexpected number of MPDUs");
782 }
783 
792 {
793  public:
799  EhtAggregationTest(uint16_t bufferSize);
800 
801  private:
802  void DoRun() override;
803 };
804 
806  : AmpduAggregationTest("Check the correctness of 802.11be aggregation operations, size=" +
807  std::to_string(bufferSize),
808  Params{.standard = WIFI_STANDARD_80211be,
809  .nLinks = 2,
810  .dataMode = "EhtMcs13",
811  .bufferSize = bufferSize,
812  .maxAmsduSize = 0,
813  .maxAmpduSize = 102000,
814  .txopLimit = Seconds(0)})
815 {
816 }
817 
818 void
820 {
821  /*
822  * Test behavior when 1200 packets of 100 bytes each are ready for transmission. The max
823  * A-MPDU size limit (102000 B) is computed to have at most 750 MPDUs aggregated in a single
824  * A-MPDU (each MPDU is 130 B, plus 4 B of A-MPDU subframe header, plus 2 B of padding).
825  */
826  EnqueuePkts(1200, 100, Mac48Address("00:00:00:00:00:02"));
827  const std::size_t maxNMpdus = 750;
828 
829  for (uint8_t linkId = 0; linkId < m_params.nLinks; linkId++)
830  {
831  auto fem = m_mac->GetFrameExchangeManager(linkId);
832  auto htFem = DynamicCast<HtFrameExchangeManager>(fem);
833  auto mpduAggregator = htFem->GetMpduAggregator();
834  std::vector<Ptr<WifiMpdu>> mpduList;
835 
836  auto peeked = GetBeQueue()->PeekNextMpdu(linkId);
837  if (peeked)
838  {
839  WifiTxParameters txParams;
840  txParams.m_txVector = m_mac->GetWifiRemoteStationManager()->GetDataTxVector(
841  peeked->GetHeader(),
842  m_phys.at(linkId)->GetChannelWidth());
843  auto item = GetBeQueue()->GetNextMpdu(linkId, peeked, txParams, Time::Min(), true);
844 
845  mpduList = mpduAggregator->GetNextAmpdu(item, txParams, Time::Min());
846  DequeueMpdus(mpduList);
847  }
848 
849  uint16_t expectedRemainingPacketsInQueue;
850 
851  if (m_params.bufferSize >= maxNMpdus)
852  {
853  // two A-MPDUs are transmitted concurrently on the two links and together saturate
854  // the transmit window
855  switch (linkId)
856  {
857  case 0:
858  // the first A-MPDU includes maxNMpdus MPDUs
859  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), false, "MPDU aggregation failed");
860  NS_TEST_EXPECT_MSG_EQ(mpduList.size(),
861  maxNMpdus,
862  "A-MPDU contains an unexpected number of MPDUs");
863  expectedRemainingPacketsInQueue = 1200 - maxNMpdus;
864  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
865  expectedRemainingPacketsInQueue,
866  "Queue contains an unexpected number of MPDUs");
867  break;
868  case 1:
869  // the second A-MPDU includes bufferSize - maxNMpdus MPDUs
870  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), false, "MPDU aggregation failed");
871  NS_TEST_EXPECT_MSG_EQ(mpduList.size(),
872  m_params.bufferSize - maxNMpdus,
873  "A-MPDU contains an unexpected number of MPDUs");
874  expectedRemainingPacketsInQueue = 1200 - m_params.bufferSize;
875  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
876  expectedRemainingPacketsInQueue,
877  "Queue contains an unexpected number of MPDUs");
878  break;
879  default:
880  NS_TEST_ASSERT_MSG_EQ(true, false, "Unexpected link ID " << +linkId);
881  }
882  }
883  else
884  {
885  // one A-MPDU is transmitted that saturates the transmit window
886  switch (linkId)
887  {
888  case 0:
889  // the first A-MPDU includes bufferSize MPDUs
890  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), false, "MPDU aggregation failed");
891  NS_TEST_EXPECT_MSG_EQ(mpduList.size(),
893  "A-MPDU contains an unexpected number of MPDUs");
894  expectedRemainingPacketsInQueue = 1200 - m_params.bufferSize;
895  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
896  expectedRemainingPacketsInQueue,
897  "Queue contains an unexpected number of MPDUs");
898  break;
899  case 1:
900  // no more MPDUs can be sent, aggregation fails
901  NS_TEST_EXPECT_MSG_EQ(mpduList.empty(), true, "MPDU aggregation did not fail");
902  expectedRemainingPacketsInQueue = 1200 - m_params.bufferSize;
903  NS_TEST_EXPECT_MSG_EQ(GetBeQueue()->GetWifiMacQueue()->GetNPackets(),
904  expectedRemainingPacketsInQueue,
905  "Queue contains an unexpected number of MPDUs");
906  break;
907  default:
908  NS_TEST_ASSERT_MSG_EQ(true, false, "Unexpected link ID " << +linkId);
909  }
910  }
911  }
912 }
913 
934 {
935  public:
937  ~PreservePacketsInAmpdus() override;
938 
939  void DoRun() override;
940 
941  private:
942  std::list<Ptr<const Packet>> m_packetList;
943  std::vector<std::size_t> m_nMpdus;
944  std::vector<std::size_t> m_nMsdus;
945 
957  void NotifyPsduForwardedDown(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
963 };
964 
966  : TestCase("Test case to check that the Wifi Mac forwards up the same packets received at "
967  "sender side.")
968 {
969 }
970 
972 {
973 }
974 
975 void
977 {
978  m_packetList.push_back(packet);
979 }
980 
981 void
983  WifiTxVector txVector,
984  double txPowerW)
985 {
986  NS_TEST_EXPECT_MSG_EQ((psduMap.size() == 1 && psduMap.begin()->first == SU_STA_ID),
987  true,
988  "No DL MU PPDU expected");
989 
990  if (!psduMap[SU_STA_ID]->GetHeader(0).IsQosData())
991  {
992  return;
993  }
994 
995  m_nMpdus.push_back(psduMap[SU_STA_ID]->GetNMpdus());
996 
997  for (auto& mpdu : *PeekPointer(psduMap[SU_STA_ID]))
998  {
999  std::size_t dist = std::distance(mpdu->begin(), mpdu->end());
1000  // the list of aggregated MSDUs is empty if the MPDU includes a non-aggregated MSDU
1001  m_nMsdus.push_back(dist > 0 ? dist : 1);
1002  }
1003 }
1004 
1005 void
1007 {
1008  auto it = std::find(m_packetList.begin(), m_packetList.end(), p);
1009  NS_TEST_EXPECT_MSG_EQ((it != m_packetList.end()), true, "Packet being forwarded up not found");
1010  m_packetList.erase(it);
1011 }
1012 
1013 void
1015 {
1016  NodeContainer wifiStaNode;
1017  wifiStaNode.Create(1);
1018 
1020  wifiApNode.Create(1);
1021 
1022  YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
1024  phy.SetChannel(channel.Create());
1025 
1026  WifiHelper wifi;
1027  wifi.SetStandard(WIFI_STANDARD_80211n);
1028  wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1029 
1031  Ssid ssid = Ssid("ns-3-ssid");
1032  mac.SetType("ns3::StaWifiMac",
1033  "BE_MaxAmsduSize",
1034  UintegerValue(4500),
1035  "BE_MaxAmpduSize",
1036  UintegerValue(7500),
1037  "Ssid",
1038  SsidValue(ssid),
1039  /* setting blockack threshold for sta's BE queue */
1040  "BE_BlockAckThreshold",
1041  UintegerValue(2),
1042  "ActiveProbing",
1043  BooleanValue(false));
1044 
1046  staDevices = wifi.Install(phy, mac, wifiStaNode);
1047 
1048  mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
1049 
1051  apDevices = wifi.Install(phy, mac, wifiApNode);
1052 
1054  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
1055 
1056  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
1057  positionAlloc->Add(Vector(1.0, 0.0, 0.0));
1058  mobility.SetPositionAllocator(positionAlloc);
1059 
1060  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1061  mobility.Install(wifiApNode);
1062  mobility.Install(wifiStaNode);
1063 
1064  Ptr<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice>(apDevices.Get(0));
1065  Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice>(staDevices.Get(0));
1066 
1067  PacketSocketAddress socket;
1068  socket.SetSingleDevice(sta_device->GetIfIndex());
1069  socket.SetPhysicalAddress(ap_device->GetAddress());
1070  socket.SetProtocol(1);
1071 
1072  // install packet sockets on nodes.
1073  PacketSocketHelper packetSocket;
1074  packetSocket.Install(wifiStaNode);
1075  packetSocket.Install(wifiApNode);
1076 
1077  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient>();
1078  client->SetAttribute("PacketSize", UintegerValue(1000));
1079  client->SetAttribute("MaxPackets", UintegerValue(8));
1080  client->SetAttribute("Interval", TimeValue(Seconds(1)));
1081  client->SetRemote(socket);
1082  wifiStaNode.Get(0)->AddApplication(client);
1083  client->SetStartTime(Seconds(1));
1084  client->SetStopTime(Seconds(3.0));
1085  Simulator::Schedule(Seconds(1.5),
1086  &PacketSocketClient::SetAttribute,
1087  client,
1088  "Interval",
1089  TimeValue(MicroSeconds(0)));
1090 
1091  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer>();
1092  server->SetLocal(socket);
1093  wifiApNode.Get(0)->AddApplication(server);
1094  server->SetStartTime(Seconds(0.0));
1095  server->SetStopTime(Seconds(4.0));
1096 
1097  sta_device->GetMac()->TraceConnectWithoutContext(
1098  "MacTx",
1100  sta_device->GetPhy()->TraceConnectWithoutContext(
1101  "PhyTxPsduBegin",
1103  ap_device->GetMac()->TraceConnectWithoutContext(
1104  "MacRx",
1106 
1107  Simulator::Stop(Seconds(5));
1108  Simulator::Run();
1109 
1110  Simulator::Destroy();
1111 
1112  // Two packets are transmitted. The first one is an MPDU containing a single MSDU.
1113  // The second one is an A-MPDU containing two MPDUs: the first MPDU contains 4 MSDUs
1114  // and the second MPDU contains 3 MSDUs
1115  NS_TEST_EXPECT_MSG_EQ(m_nMpdus.size(), 2, "Unexpected number of transmitted packets");
1116  NS_TEST_EXPECT_MSG_EQ(m_nMsdus.size(), 3, "Unexpected number of transmitted MPDUs");
1117  NS_TEST_EXPECT_MSG_EQ(m_nMpdus[0], 1, "Unexpected number of MPDUs in the first A-MPDU");
1118  NS_TEST_EXPECT_MSG_EQ(m_nMsdus[0], 1, "Unexpected number of MSDUs in the first MPDU");
1119  NS_TEST_EXPECT_MSG_EQ(m_nMpdus[1], 2, "Unexpected number of MPDUs in the second A-MPDU");
1120  NS_TEST_EXPECT_MSG_EQ(m_nMsdus[1], 4, "Unexpected number of MSDUs in the second MPDU");
1121  NS_TEST_EXPECT_MSG_EQ(m_nMsdus[2], 3, "Unexpected number of MSDUs in the third MPDU");
1122  // All the packets must have been forwarded up at the receiver
1123  NS_TEST_EXPECT_MSG_EQ(m_packetList.empty(), true, "Some packets have not been forwarded up");
1124 }
1125 
1133 {
1134  public:
1136 };
1137 
1139  : TestSuite("wifi-aggregation", UNIT)
1140 {
1141  AddTestCase(new AmpduAggregationTest, TestCase::QUICK);
1142  AddTestCase(new TwoLevelAggregationTest, TestCase::QUICK);
1143  AddTestCase(new HeAggregationTest(64), TestCase::QUICK);
1144  AddTestCase(new HeAggregationTest(256), TestCase::QUICK);
1145  AddTestCase(new EhtAggregationTest(512), TestCase::QUICK);
1146  AddTestCase(new EhtAggregationTest(1024), TestCase::QUICK);
1147  AddTestCase(new PreservePacketsInAmpdus, TestCase::QUICK);
1148 }
1149 
#define Min(a, b)
Ampdu Aggregation Test.
bool m_discarded
whether the packet should be discarded
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Ptr< QosTxop > GetBeQueue() const
void DequeueMpdus(const std::vector< Ptr< WifiMpdu >> &mpduList)
Dequeue a PSDU.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
ObjectFactory m_factory
factory
Params m_params
test parameters
void EnqueuePkts(std::size_t count, uint32_t size, const Mac48Address &dest)
Enqueue the given number of packets addressed to the given station and of the given size.
std::vector< Ptr< WifiRemoteStationManager > > m_managers
remote station managers
void DoRun() override
Implementation to actually run this TestCase.
Ptr< WifiNetDevice > m_device
WifiNetDevice.
void EstablishAgreement(const Mac48Address &recipient)
Establish a BlockAck agreement.
void MpduDiscarded(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Fired when the MAC discards an MPDU.
std::vector< Ptr< WifiPhy > > m_phys
Phys.
Ptr< StaWifiMac > m_mac
Mac.
802.11be aggregation test which permits up to 1024 MPDUs in A-MPDU according to the negotiated buffer...
void DoRun() override
Implementation to actually run this TestCase.
EhtAggregationTest(uint16_t bufferSize)
Constructor.
802.11ax aggregation test which permits 64 or 256 MPDUs in A-MPDU according to the negotiated buffer ...
HeAggregationTest(uint16_t bufferSize)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
Test for A-MSDU and A-MPDU aggregation.
void DoRun() override
Implementation to actually run this TestCase.
void NotifyPsduForwardedDown(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when the sender MAC passes a PSDU(s) to the PHY.
std::list< Ptr< const Packet > > m_packetList
List of packets passed to the MAC.
std::vector< std::size_t > m_nMsdus
Number of MSDUs in MPDUs passed to the PHY.
std::vector< std::size_t > m_nMpdus
Number of MPDUs in PSDUs passed to the PHY.
void NotifyMacForwardUp(Ptr< const Packet > p)
Callback invoked when the receiver MAC forwards a packet up to the upper layer.
void NotifyMacTransmit(Ptr< const Packet > packet)
Callback invoked when an MSDU is passed to the MAC.
Two Level Aggregation Test.
void DoRun() override
Implementation to actually run this TestCase.
Wifi Aggregation Test Suite.
A container for one type of attribute.
The IEEE 802.11be EHT Capabilities.
void SetMaxMpduLength(uint16_t length)
Set the maximum MPDU length.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum A-MPDU length.
The IEEE 802.11ax HE Capabilities.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
The HT Capabilities Information Element.
void SetMaxAmsduLength(uint16_t maxAmsduLength)
Set the maximum AMSDU length.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
an EUI-48 address
Definition: mac48-address.h:46
Implement the header for management frames of type Add Block Ack request.
void SetBufferSize(uint16_t size)
Set buffer size.
void SetImmediateBlockAck()
Enable immediate BlockAck.
uint16_t GetTimeout() const
Return the timeout.
uint8_t GetTid() const
Return the Traffic ID (TID).
bool IsAmsduSupported() const
Return whether A-MSDU capability is supported.
void SetTimeout(uint16_t timeout)
Set timeout.
void SetTid(uint8_t tid)
Set Traffic ID (TID).
void SetStartingSequence(uint16_t seq)
Set the starting sequence number.
Implement the header for management frames of type Add Block Ack response.
void SetTid(uint8_t tid)
Set Traffic ID (TID).
void SetTimeout(uint16_t timeout)
Set timeout.
void SetBufferSize(uint16_t size)
Set buffer size.
void SetStatusCode(StatusCode code)
Set the status code.
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
void SetImmediateBlockAck()
Enable immediate BlockAck.
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:315
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
void Dispose()
Dispose of this Object.
Definition: object.cc:219
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Ptr< BlockAckManager > GetBaManager()
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:286
Ptr< WifiMpdu > PeekNextMpdu(uint8_t linkId, uint8_t tid=8, Mac48Address recipient=Mac48Address::GetBroadcast(), Ptr< const WifiMpdu > mpdu=nullptr)
Peek the next frame to transmit on the given link to the given receiver and of the given TID from the...
Definition: qos-txop.cc:378
Ptr< WifiMpdu > GetNextMpdu(uint8_t linkId, Ptr< WifiMpdu > peekedItem, WifiTxParameters &txParams, Time availableTime, bool initialFrame)
Prepare the frame to transmit on the given link starting from the MPDU that has been previously peeke...
Definition: qos-txop.cc:495
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
void SetState(MacState value)
Set the current MAC state.
void SetWifiPhys(const std::vector< Ptr< WifiPhy >> &phys) override
Status code for association response.
Definition: status-code.h:32
void SetSuccess()
Set success bit to 0 (success).
Definition: status-code.cc:30
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Ptr< WifiMacQueue > GetWifiMacQueue() const
Return the packet queue associated with this Txop.
Definition: txop.cc:231
Hold an unsigned integer type.
Definition: uinteger.h:45
The IEEE 802.11ac VHT Capabilities.
void SetMaxMpduLength(uint16_t length)
Set the maximum MPDU length.
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
Implements the IEEE 802.11 MAC header.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
create MAC layers for a ns3::WifiNetDevice.
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Definition: wifi-mac.cc:864
Ptr< QosTxop > GetBEQueue() const
Accessor for the AC_BE channel access function.
Definition: wifi-mac.cc:533
virtual void SetMacQueueScheduler(Ptr< WifiMacQueueScheduler > scheduler)
Set the wifi MAC queue scheduler.
Definition: wifi-mac.cc:569
const std::map< uint8_t, std::unique_ptr< LinkEntity > > & GetLinks() const
Definition: wifi-mac.cc:918
virtual void SetAddress(Mac48Address address)
Definition: wifi-mac.cc:445
virtual void ConfigureStandard(WifiStandard standard)
Definition: wifi-mac.cc:748
Ptr< MacTxMiddle > m_txMiddle
TX middle (aggregation etc.)
Definition: wifi-mac.h:893
virtual Ptr< WifiMacQueue > GetTxopQueue(AcIndex ac) const
Get the wifi MAC queue of the (Qos)Txop associated with the given AC, if such (Qos)Txop is installed,...
Definition: wifi-mac.cc:545
void SetWifiRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager >> &stationManagers)
Definition: wifi-mac.cc:883
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:906
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-mac.cc:428
void SetMac(const Ptr< WifiMac > mac)
void SetHeConfiguration(Ptr< HeConfiguration > heConfiguration)
void SetHtConfiguration(Ptr< HtConfiguration > htConfiguration)
Ptr< WifiMac > GetMac() const
void SetRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager >> &managers)
void SetVhtConfiguration(Ptr< VhtConfiguration > vhtConfiguration)
void SetStandard(WifiStandard standard)
Set the Wifi standard.
void SetEhtConfiguration(Ptr< EhtConfiguration > ehtConfiguration)
Ptr< WifiPhy > GetPhy() const
uint32_t GetIfIndex() const override
void SetPhys(const std::vector< Ptr< WifiPhy >> &phys)
Address GetAddress() const override
hold a list of per-remote-station state.
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
void Clear()
Reset the TX parameters.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
manage and create wifi channel objects for the YANS model.
Make it easy to create and manage PHY objects for the YANS model.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiMacDropReason
The reason why an MPDU was dropped.
Definition: wifi-mac.h:77
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ AC_BE
Best Effort.
Definition: qos-utils.h:75
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:25255
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
static constexpr uint8_t SINGLE_LINK_OP_ID
Link ID for single link operations (helps tracking places where correct link ID is to be used to supp...
Definition: wifi-utils.h:192
@ WIFI_MAC_QOSDATA
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:449
staDevices
Definition: third.py:100
ssid
Definition: third.py:93
channel
Definition: third.py:88
mac
Definition: third.py:92
wifi
Definition: third.py:95
apDevices
Definition: third.py:103
wifiApNode
Definition: third.py:86
mobility
Definition: third.py:105
phy
Definition: third.py:89
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
uint8_t nLinks
number of links (>1 only for EHT)
uint32_t maxAmpduSize
maximum A-MPDU size (bytes)
uint16_t bufferSize
the size (in number of MPDUs) of the BlockAck buffer
WifiStandard standard
the standard of the device
uint16_t maxAmsduSize
maximum A-MSDU size (bytes)
Time txopLimit
TXOP limit duration.
static WifiAggregationTestSuite g_wifiAggregationTestSuite
the test suite