A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
55using namespace ns3;
56
57/**
58 * \ingroup wifi-test
59 * \ingroup tests
60 *
61 * \brief Ampdu Aggregation Test
62 */
64{
65 public:
67
68 /// Test parameters
69 struct Params
70 {
71 WifiStandard standard; //!< the standard of the device
72 uint8_t nLinks; //!< number of links (>1 only for EHT)
73 std::string dataMode; //!< data mode
74 uint16_t bufferSize; //!< the size (in number of MPDUs) of the BlockAck buffer
75 uint16_t maxAmsduSize; //!< maximum A-MSDU size (bytes)
76 uint32_t maxAmpduSize; //!< maximum A-MPDU size (bytes)
77 Time txopLimit; //!< TXOP limit duration
78 };
79
80 /**
81 * Construct object with non-default test parameters
82 *
83 * \param name the name of the test case
84 * \param params the test parameters
85 */
86 AmpduAggregationTest(const std::string& name, const Params& params);
87
88 protected:
89 /**
90 * Establish a BlockAck agreement.
91 *
92 * \param recipient the recipient MAC address
93 */
94 void EstablishAgreement(const Mac48Address& recipient);
95
96 /**
97 * Enqueue the given number of packets addressed to the given station and of the given size.
98 *
99 * \param count the number of packets
100 * \param size the size (bytes) of each packet
101 * \param dest the destination address
102 */
103 void EnqueuePkts(std::size_t count, uint32_t size, const Mac48Address& dest);
104
105 /**
106 * \return the Best Effort QosTxop
107 */
108 Ptr<QosTxop> GetBeQueue() const;
109
110 /**
111 * Dequeue a PSDU.
112 *
113 * \param mpduList the MPDUs contained in the PSDU
114 */
115 void DequeueMpdus(const std::vector<Ptr<WifiMpdu>>& mpduList);
116
118 std::vector<Ptr<WifiPhy>> m_phys; ///< Phys
119 Params m_params; //!< test parameters
120
121 private:
122 /**
123 * Fired when the MAC discards an MPDU.
124 *
125 * \param reason the reason why the MPDU was discarded
126 * \param mpdu the discarded MPDU
127 */
129
130 void DoSetup() override;
131 void DoRun() override;
132 void DoTeardown() override;
133
134 Ptr<WifiNetDevice> m_device; ///< WifiNetDevice
135 std::vector<Ptr<WifiRemoteStationManager>> m_managers; ///< remote station managers
137 bool m_discarded; ///< whether the packet should be 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
152AmpduAggregationTest::AmpduAggregationTest(const std::string& name, const Params& params)
153 : TestCase(name),
154 m_params(params),
155 m_discarded(false)
156{
157}
158
159void
161{
162 m_discarded = true;
163}
164
165void
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");
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 }
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 {
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"));
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
330void
332{
333 std::list<Ptr<const WifiMpdu>> mpdus(mpduList.cbegin(), mpduList.cend());
334 m_mac->GetTxopQueue(AC_BE)->DequeueIfQueued(mpdus);
335}
336
337void
339{
341 reqHdr.SetImmediateBlockAck();
342 reqHdr.SetTid(0);
344 reqHdr.SetTimeout(0);
345 reqHdr.SetStartingSequence(0);
346 GetBeQueue()->GetBaManager()->CreateOriginatorAgreement(reqHdr, recipient);
347
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
360void
361AmpduAggregationTest::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
377void
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
483void
485{
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
498/**
499 * \ingroup wifi-test
500 * \ingroup tests
501 *
502 * \brief Two Level Aggregation Test
503 */
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
525void
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
718/**
719 * \ingroup wifi-test
720 * \ingroup tests
721 *
722 * \brief 802.11ax aggregation test which permits 64 or 256 MPDUs in A-MPDU according to the
723 * negotiated buffer size.
724 */
726{
727 public:
728 /**
729 * Constructor.
730 *
731 * \param bufferSize the size (in number of MPDUs) of the BlockAck buffer
732 */
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
752void
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
784/**
785 * \ingroup wifi-test
786 * \ingroup tests
787 *
788 * \brief 802.11be aggregation test which permits up to 1024 MPDUs in A-MPDU according to the
789 * negotiated buffer size.
790 */
792{
793 public:
794 /**
795 * Constructor.
796 *
797 * \param bufferSize the size (in number of MPDUs) of the BlockAck buffer
798 */
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
818void
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
914/**
915 * \ingroup wifi-test
916 * \ingroup tests
917 *
918 * \brief Test for A-MSDU and A-MPDU aggregation
919 *
920 * This test aims to check that the packets passed to the MAC layer (on the sender
921 * side) are forwarded up to the upper layer (on the receiver side) when A-MSDU and
922 * A-MPDU aggregation are used. This test checks that no packet copies are performed,
923 * hence packets can be tracked by means of a pointer.
924 *
925 * In this test, an HT STA sends 8 packets (each of 1000 bytes) to an HT AP.
926 * The block ack threshold is set to 2, hence the first packet is sent as an MPDU
927 * containing a single MSDU because the establishment of a Block Ack agreement is
928 * not triggered yet. The maximum A-MSDU size is set to 4500 bytes and the
929 * maximum A-MPDU size is set to 7500 bytes, hence the remaining packets are sent
930 * in an A-MPDU containing two MPDUs, the first one including 4 MSDUs and the second
931 * one including 3 MPDUs.
932 */
934{
935 public:
937 ~PreservePacketsInAmpdus() override;
938
939 void DoRun() override;
940
941 private:
942 std::list<Ptr<const Packet>> m_packetList; ///< List of packets passed to the MAC
943 std::vector<std::size_t> m_nMpdus; ///< Number of MPDUs in PSDUs passed to the PHY
944 std::vector<std::size_t> m_nMsdus; ///< Number of MSDUs in MPDUs passed to the PHY
945
946 /**
947 * Callback invoked when an MSDU is passed to the MAC
948 * \param packet the MSDU to transmit
949 */
951 /**
952 * Callback invoked when the sender MAC passes a PSDU(s) to the PHY
953 * \param psduMap the PSDU map
954 * \param txVector the TX vector
955 * \param txPowerW the transmit power in Watts
956 */
957 void NotifyPsduForwardedDown(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
958 /**
959 * Callback invoked when the receiver MAC forwards a packet up to the upper layer
960 * \param p the packet
961 */
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
975void
977{
978 m_packetList.push_back(packet);
979}
980
981void
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
1005void
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
1013void
1015{
1016 NodeContainer wifiStaNode;
1017 wifiStaNode.Create(1);
1018
1019 NodeContainer wifiApNode;
1020 wifiApNode.Create(1);
1021
1024 phy.SetChannel(channel.Create());
1025
1026 WifiHelper wifi;
1027 wifi.SetStandard(WIFI_STANDARD_80211n);
1028 wifi.SetRemoteStationManager("ns3::IdealWifiManager");
1029
1030 WifiMacHelper mac;
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
1045 NetDeviceContainer staDevices;
1046 staDevices = wifi.Install(phy, mac, wifiStaNode);
1047
1048 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid), "BeaconGeneration", BooleanValue(true));
1049
1050 NetDeviceContainer apDevices;
1051 apDevices = wifi.Install(phy, mac, wifiApNode);
1052
1053 MobilityHelper mobility;
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));
1086 &PacketSocketClient::SetAttribute,
1087 client,
1088 "Interval",
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
1109
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
1126/**
1127 * \ingroup wifi-test
1128 * \ingroup tests
1129 *
1130 * \brief Wifi Aggregation Test Suite
1131 */
1133{
1134 public:
1136};
1137
1139 : TestSuite("wifi-aggregation", Type::UNIT)
1140{
1141 AddTestCase(new AmpduAggregationTest, TestCase::Duration::QUICK);
1142 AddTestCase(new TwoLevelAggregationTest, TestCase::Duration::QUICK);
1143 AddTestCase(new HeAggregationTest(64), TestCase::Duration::QUICK);
1144 AddTestCase(new HeAggregationTest(256), TestCase::Duration::QUICK);
1145 AddTestCase(new EhtAggregationTest(512), TestCase::Duration::QUICK);
1146 AddTestCase(new EhtAggregationTest(1024), TestCase::Duration::QUICK);
1147 AddTestCase(new PreservePacketsInAmpdus, TestCase::Duration::QUICK);
1148}
1149
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 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 DequeueMpdus(const std::vector< Ptr< WifiMpdu > > &mpduList)
Dequeue a PSDU.
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.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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
static Mac48Address GetBroadcast()
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:164
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:322
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:211
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:258
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.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Ptr< BlockAckManager > GetBaManager()
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:282
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
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:96
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:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:287
AttributeValue implementation for Time.
Definition: nstime.h:1406
Ptr< WifiMacQueue > GetWifiMacQueue() const
Return the packet queue associated with this Txop.
Definition: txop.cc:230
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:878
Ptr< QosTxop > GetBEQueue() const
Accessor for the AC_BE channel access function.
Definition: wifi-mac.cc:547
virtual void SetMacQueueScheduler(Ptr< WifiMacQueueScheduler > scheduler)
Set the wifi MAC queue scheduler.
Definition: wifi-mac.cc:583
const std::map< uint8_t, std::unique_ptr< LinkEntity > > & GetLinks() const
Definition: wifi-mac.cc:932
virtual void SetAddress(Mac48Address address)
Definition: wifi-mac.cc:459
virtual void ConfigureStandard(WifiStandard standard)
Definition: wifi-mac.cc:762
void SetWifiRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &stationManagers)
Definition: wifi-mac.cc:897
Ptr< MacTxMiddle > m_txMiddle
TX middle (aggregation etc.)
Definition: wifi-mac.h:907
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:559
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:920
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-mac.cc:442
void SetMac(const Ptr< WifiMac > mac)
void SetPhys(const std::vector< Ptr< WifiPhy > > &phys)
void SetHeConfiguration(Ptr< HeConfiguration > heConfiguration)
void SetHtConfiguration(Ptr< HtConfiguration > htConfiguration)
void SetVhtConfiguration(Ptr< VhtConfiguration > vhtConfiguration)
void SetRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &managers)
void SetStandard(WifiStandard standard)
Set the Wifi standard.
void SetEhtConfiguration(Ptr< EhtConfiguration > ehtConfiguration)
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.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
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:145
#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:252
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1343
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
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:80
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ AC_BE
Best Effort.
Definition: qos-utils.h:75
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:454
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:706
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
STL namespace.
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